【问题标题】:Sorting Map keys when keys are arrays当键是数组时对映射键进行排序
【发布时间】:2017-10-23 04:30:38
【问题描述】:

我有一个HashMap<Float[], Integer>,我可能需要将其转换为TreeMap。 TreeMap 的键(即数组)如何排序?通过他们的第一个元素?

我打算运行一个简单的测试,但它以某种方式导致了错误:

public class treeMapTest {
    public static void main(String[] args) {
        Integer arr1[] = {9, 0, 3};
        Integer arr2[] = {2, 2, 2};
        Integer arr3[] = {4, 2, 1};

        TreeMap<Integer[], Integer> tm = new TreeMap<Integer[], Integer>();
        tm.put(arr1, 7);
        tm.put(arr2, 7);
        tm.put(arr3, 7);

        System.out.println(tm);
    }
}

谢谢。

【问题讨论】:

  • 奇怪,我以前从未见过错误不知何故 ;-)

标签: java arrays dictionary


【解决方案1】:

数组没有自然排序(即它们没有实现Comparable 接口),这就是为什么当您使用无参数构造函数实例化TreeMap 时您的代码会引发异常。

您必须向TreeMap 构造函数提供Comparator&lt;Integer[]&gt; 才能自己定义排序。

顺便说一句,在HashMap 中使用数组作为键是个坏主意(因为数组不会覆盖equals()hashCode() 的默认实现),所以切换到@987654328 是件好事@。

【讨论】:

  • 对。否则你会得到Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Integer; cannot be cast to java.lang.Comparable
  • 是的,这是我得到的例外。谢谢。
  • @Vic 这是你知道的重要信息 ;)
【解决方案2】:

这在语法上可能是正确的,但实际上并没有用。 该映射使用equals() 方法来确定2 个键是否相等。 数组从 Object 类继承 equals()hashcode() 方法。因此,当您要搜索特定键(数组对象)时,除非传递了初始数组对象的引用,否则您将找不到它。 例如

Integer arr1[] = {9, 0, 3};

Integer arr1_copy[] = {9, 0, 3};

是 2 个不同的对象,默认 equals() 将失败。

但是,如果您需要使用数组作为键,您可以做的是创建一个以数组为成员的类,并覆盖该类的 hashcode()equals() 方法,并使用该类作为键。

【讨论】:

  • 这还没有回答订购问题;)
  • 好吧,一旦你“创建一个以数组为成员的类”,问题就会来得非常快;)
【解决方案3】:

数组没有自然排序。解决它并使其可预测的一种方法是执行以下操作:

TreeMap<Integer[], Integer> tm = new TreeMap<>((a1, a2) -> Integer.compare(a1[0], a2[0]) );

这将比较每个数组的第一个元素。如果数组可以为空,则需要稍作更改,以免引发异常。

【讨论】:

    【解决方案4】:

    密钥由哈希码标识。这意味着表示数组的 Array 对象的哈希码,而不是数组的实际内容。

    这很可能不是您的想法,即使它可能适用于您正在处理的场景。

    如果您认为通过在数组中移动元素会改变哈希映射的值桶中项目的排序,那么您就大错特错了。

    【讨论】:

      【解决方案5】:

      您应该在 Treemap 中为您的排序偏好提供 Comparator。

      public static void main(String[] args) {
                  Integer arr1[] = {9, 0, 3};
                  Integer arr2[] = {2, 2, 2};
                  Integer arr3[] = {4, 2, 1};
      
                  TreeMap<Integer[], Integer> tm = new TreeMap<Integer[], Integer>(new Comparator<Integer[]>() {
      
                      @Override
                      public int compare(Integer[] o1, Integer[] o2) {
                          int cmp=o1[0].compareTo(o2[0]);
                          return cmp;
                      }
                  });
                  tm.put(arr1, 7);
                  tm.put(arr2, 7);
                  tm.put(arr3, 7);
                  for(Integer[] o1:tm.keySet())
                  System.out.println(o1[0]);
              }
      

      【讨论】:

        猜你喜欢
        • 2015-07-17
        • 2022-07-29
        • 1970-01-01
        • 1970-01-01
        • 2023-01-12
        • 1970-01-01
        • 2021-12-23
        • 2013-02-01
        • 2011-04-05
        相关资源
        最近更新 更多