Java - 使用HashMap和List<>作为关键

时间:2017-02-11 22:46:07

标签: java arraylist hashmap

我尝试使用HashMap和Hastable以及对象列表作为键。 请参阅下面我的代码的简化版本,它不起作用。 当我调试这段代码时,我希望在 TestMap4 对象中有3个项目,但只有1个。

List<String> lst = new ArrayList<>();
lst.add("Hello");
lst.add("World");

Map<List<String>, Integer> testMap4 = new HashMap<List<String>, Integer>();
testMap4.put(lst, 1);
testMap4.put(lst, 2);
testMap4.put(lst, 5);

当我将新项目放入HashMap对象时会发生什么?为什么它不起作用?

我通过下面这个新例子得到了相同的结果。 (每个List都有相同的2个字符串)

List<String> lst = new ArrayList<>();
lst.add("Hello");
lst.add("World");

List<String> lst2 = new ArrayList<>();
lst2.add("Hello");
lst2.add("World");

List<String> lst3 = new ArrayList<>();
lst3.add("Hello");
lst3.add("World");

Map<List<String>, Integer> testMap4 = new HashMap<List<String>, Integer>();
testMap4.put(lst,1);
testMap4.put(lst2,2);
testMap4.put(lst3,5);

如果我只修改2个字符串中的1个字符,那就没问题

3 个答案:

答案 0 :(得分:5)

您不理解HashMap的概念。

您的问题是每次都使用相同的密钥。

testMap4.put(lst, 1);     <----same key, different value
testMap4.put(lst, 2);     <----same key, different value
testMap4.put(lst, 5);     <----same key, different value

Hashmap中,存储在Hashmap中的每个值都有一个key,其中包含该特定值,每个值都唯一存储在Hashmap

关于HashMap的重点:

1- HashMap包含基于密钥的值。

2-它只包含独特的元素。

3-它可能有一个空键和多个空值。

4-它没有订单。

示例

 HashMap<Integer,String> hm=new HashMap<Integer,String>();  

其次,如果在将任何列表插入地图后修改了任何列表,则使用可变对象(List<>)作为键将导致未定义的行为。只有当条目首次插入到地图中时,才会根据List的合同(请参阅Javadoc)计算哈希码。更改列表的内容将更改哈希代码,您将无法再找到该条目。

使用List<>(或任何可变对象)作为HashMap<>中的键是 Really Bad Idea™

答案 1 :(得分:0)

它不起作用,因为您每次使用相同的键来存储不同的值,因为所有值都映射到相同的键,而hashmap只存储最后一个值,因为此值会覆盖以前的值。

答案 2 :(得分:0)

HashMap调用放在HashMap中的键对象上的hashCode()方法。

由于您没有为您使用的密钥类(在您的情况下为List<>)覆盖它,因此它会调用hashCode()上的java.lang.Object方法,该方法返回唯一的对象ID

当您将相同的对象放入地图三次时,它与您连续三次放入的密钥相同。

List<String> lst1 = new ArrayList<>();
lst.add("Hello");
lst.add("World");
List<String> lst2 = new ArrayList<>();
List<String> lst3 = new ArrayList<>();

Map<List<String>, Integer> testMap4 = new HashMap<List<String>, Integer>();
testMap4.put(lst1, 1);
testMap4.put(lst2, 2);
testMap4.put(lst3, 5);

会在地图中为您提供三个条目。

如果您需要对列表内容使用HashCode以用作HashMap密钥,请查看:

static int java.util.Objects.hash(Object... values)
static boolean java.util.Arrays.equals(Object[] a, Object[] a2)

请勿忘记总是必须覆盖两种方法。 hashCode() equals()。如果你只覆盖其中一个,你会立刻掉线! ;)