2011-06-24 30 views
2

这让我为难以下段将如何导致布尔强制性的空值,虽然它不是在实际的哈希表对应的按键无效:通过哈希键迭代时的空值设置

for (List<List<A>> a : hashMap.keySet()) { 
    Boolean mandatory = hashMap.get(a); 
} 
+0

您如何知道HashMap中的实际值不为null? –

+7

HashMap可以具有空值,但更大的问题是为什么您的密钥是List列表?难道你找不到更好的布尔值键吗? – Paul

+0

@rationalSpring:通过检查调试器中的值 @Paul没有那真的是我需要的密钥 – user695652

回答

2

HashMap将返回nullif the key specified is not bound to a value

问题几乎可以肯定的是a的比较操作 - 列表 - 对照键失败。

让我猜你是否在调用put之后修改这些列表(关键对象)?您是否删除了其中一个键中的所有条目?记住一个空的列表是equal所有空ArrayLists。进一步记住List.equals()比较列表内容(逐个)以测试相等性。

package sof_6462281; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

/** 
* Demonstrate the fact that the Map uses key.equals(k) to 
* test for key equality. Further demonstrate that it is a 
* very bad idea to use mutable collections are keys to maps. 
*/ 
public class ListAsKey { 
    public static void main(String[] args) { 
     Map<List<A>, Boolean> map = new HashMap<List<A>, Boolean>(); 

     List<A> alist = new ArrayList<A>(); 
     map.put(alist, true); 
     for (List<A> a : map.keySet()) { 
      Boolean b = map.get(a); 
      System.out.format("\t%s([email protected]%d) => %s\n",a, a.hashCode(), map.get(a)); 
     } 

     // you changed your list after the put, didn't you? 
     alist.add(new A()); 
     for (List<A> a : map.keySet()) { 
      Boolean b = map.get(a); 
      System.out.format("\t%s([email protected]%d) => %s\n",a, a.hashCode(), map.get(a)); 
     } 

     alist.clear(); 
     for (List<A> a : map.keySet()) { 
      Boolean b = map.get(a); 
      System.out.format("\t%s([email protected]%d) => %s\n",a, a.hashCode(), map.get(a)); 
     } 
    } 
    public static final class A { /* foo */ } 
} 

结果:

[]([email protected]) => true 
[sof_6462281.List[email protected]]([email protected]) => null 
[]([email protected]) => true 

编辑:加入多个op以上并加入控制台出来。

0

布尔值可以为null,因为它包装值类型原始布尔值。我不确定你的意思是它在实际散列表中的相应键上不是空。您正在迭代密钥,然后获取这些密钥的值。一个键的值被插入为空,所以当你检索它时,你会得到空值。

+0

是的,我明白,但我插入在关键字的布尔值不是空,我也看到它在调试器中的对象也可以说是真实的。但是当我使用循环访问它时,我得到一个空值 – user695652

+0

您将不得不提供更多的细节。在附注中,为什么不使用values()或entrySet()方法遍历散列映射中的所有值或所有对? –

0

对Map键使用可变对象始终是一件危险的事情。如果在插入地图后仍然保留对这些键的引用,那么很可能这些键中的一个将在未来某个时刻被修改,这会使地图的内容失效。

一个不太可能的,但可能的情况下,即使假设你有点不搞砸了你的List<List<>>关键的是,如果你搞砸A类的equals方法,那么你的任务列表equals方法也将被搞砸了,再次搞砸你的地图。

看看alphazero的漂亮代码示例,如果您需要进一步证明您尝试做的事是一个坏主意。