【问题标题】:ArrayList<X> works as a key in a HashMap, but array of X[] doesn't workArrayList<X> 用作 HashMap 中的键,但 X[] 的数组不起作用
【发布时间】:2013-02-06 03:59:45
【问题描述】:

当我尝试将数组和数组列表作为键放入 Map 时遇到了这个问题。 第一段代码:

        LinkedHashMap<ArrayList<String>, String> lhm = new LinkedHashMap<ArrayList<String>, String>();
    for (int i =0;i < strs.length; i++){
        ArrayList<String> arr = new 
            ArrayList<String>(Arrays.asList(strs[i].toLowerCase().split(" "))); 
        Collections.sort(arr);
        lhm.put(arr, strs[i]);
    }

第二段代码:

LinkedHashMap<String[], String> lhm = new LinkedHashMap<String[], String>();
for (int i =0;i < strs.length; i++){
    String[] str = strs[i].toLowerCase().split(" ");
        Arrays.sort(str);
        System.out.println("***********");
        for (String strin :str)
        {
            System.out.println(strin);
        }
        System.out.println("***********");
        lhm.put(str, strs[i]);
    }

第一段代码按预期工作,每当我放置重复键(Arraylist 作为相同内容的键)时,它会覆盖前一个键的值。 但第二部分没有按预期工作。它只是把所有的价值都放进去。 任何人都可以解释这是如何工作的吗? 将 Array/ArrayList(或者集合作为键)是一个好习惯吗?

【问题讨论】:

  • 在地图中使用可变对象作为键很少是一个好主意...
  • 不知道你想赚什么,能具体点吗?如果您想要具有不同值的相同键,您可以使用 Guava 库的 Multimap。
  • @pst:是的,我相信这是真的。但是我只想“懒惰”一次,所以我没有使用“array.toString”作为键,而是将数组本身放入。
  • @Martin:我只是将数组和数组列表作为键(我相信这不是一个好习惯)。并且 arraylist 作为键工作正常,但 array 没有。
  • Arrays.asList() 已经给你一个List,你不需要创建一个新的ArrayList

标签: java arrays collections hashmap


【解决方案1】:

Java 中的数组使用继承自 Object 的默认 equals 方法。 hashCode 方法也是如此。因此,即使您使用与键相同的元素放置数组,最终也会出现“重复”。另一方面,列表会覆盖 hashcode 方法,以返回更能代表其内容的值。

在任何情况下,使用可变对象作为 hashmap 中的键通常不是一个好主意,尽管在某些情况下这是不可避免的。特别是使用集合作为键可能会以多种方式绊倒你;

  • 向列表中添加元素
  • 改变列表中的对象,使其 hashCode/平等合同发生变化

【讨论】:

  • @pst - 同意。在这种情况下,问题在于动词,而不是名词。我淡化了一些“修辞”。
  • @Perception 好的,数组不会覆盖 hashcode() 和 equals() 函数。所以,Map 认为它们是不同的键。明白了。谢谢
猜你喜欢
  • 2016-06-04
  • 2012-04-15
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
相关资源
最近更新 更多