所以,我想制作一个字符串列表到字符串的地图,但我不能让它正常工作:
这是我所做的所有代码,直到我找到原因,我无法进步:
Map<List<String>, String> test = new HashMap<List<String>, String>();
test.put( new ArrayList<String>(), "s1");
test.put( new ArrayList<String>(), "s2");
test.put( new ArrayList<String>(), "s3");
System.out.println(test.size());
我得到1,应该是3 !! 为什么在我为3个独立的对象进行3次调用时只添加了一个对象?我知道不小心将同一个对象添加到集合中的危险,但我专门为每个put创建了一个新的ArrayList,从而创建了一个全新的对象。
那么为什么Map中只有一个对象呢? 谢谢!
答案 0 :(得分:3)
试试这个:
Map<String,List<String>> test = new HashMap<String,List<String>>();
test.put("s1", new ArrayList<String>());
test.put("s2", new ArrayList<String>());
test.put("s3", new ArrayList<String>());
System.out.println(test.size());
请注意,地图是key-value
关系。因此,您可能希望将String
用作键,将ArrayList
用作值,而不是相反。这样,如果添加3个不同的字符串,每个字符串将具有不同的哈希值(哈希码)。因此,Map
中有3个不同的密钥。
另请注意:
<强>把强>
public Object put(对象键, Object value)将指定的值与此映射中的指定键相关联。如果之前的地图包含a 此键的映射,旧值已替换。
这就是为什么你得到1而不是3,因为你要添加相同的对象new ArrayList<String>()
。
详细了解Class HashM规范。
答案 1 :(得分:2)
ArrayList #hashCode()为所有这些返回相同的内容。如果你看一下它的来源:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/AbstractList.java#AbstractList.hashCode%28%29
你可以看到,如果没有元素或所有相同的元素,hashCode将是相同的。
解决这个问题,它应该可以正常工作。使用Map或以某种方式更改hashCode。
答案 2 :(得分:1)
使用ArrayList作为键,尝试
System.out.println(new ArrayList<String>().equals(new ArrayList<String>()));
打印
true
答案 3 :(得分:0)
最好的方法是使用String对象作为键,将List作为值。
查看java文档所说的here。
如果你想将ArrayList作为键添加,那么覆盖equals方法就足够了。
帖子here提供了很好的见解。我把那些我喜欢的东西放在那篇文章中。
覆盖两个ArrayLists的等于:
public boolean equals(List<String> one, List<String> two){
if (one == null && two == null){
return true;
}
if((one == null && two != null)
|| one != null && two == null
|| one.size() != two.size()){
return false;
}
//to avoid messing the order of the lists we will use a copy
//as noted in comments by A. R. S.
one = new ArrayList<String>(one);
two = new ArrayList<String>(two);
Collections.sort(one);
Collections.sort(two);
return one.equals(two);
}
答案 4 :(得分:0)
我不确定为什么你需要列表作为键,字符串作为值,但是你基本上对每个put操作使用相同的'key',因为hashcode对于任何空列表都是相同的。与其他答案一样,最好将列表作为值切换,将字符串作为键。如果列表发生更改,则以后对.get的任何尝试都将返回null
public static void main(String...args) {
Map<List<String>, String> test = new HashMap<List<String>, String>();
List<String> bob = new ArrayList<>();
bob.add("asdf");
test.put( new ArrayList<String>(), "s1");
test.put( bob, "s2");
System.out.println(test.size());
System.out.println(test.get(bob));
}
输出
2
s2
添加新项目时
public static void main(String...args) {
Map<List<String>, String> test = new HashMap<List<String>, String>();
List<String> bob = new ArrayList<>();
bob.add("asdf");
test.put( new ArrayList<String>(), "s1");
test.put( bob, "s2");
bob.add("aabbcc");
System.out.println(test.size());
System.out.println(test.get(bob));
}
get不起作用,因为列表的哈希值已经改变。这种情况下的输出是:
2
null