当键是数组时对Map键进行排序

时间:2017-05-23 09:38:21

标签: java arrays dictionary

我有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);
    }
}

谢谢。

5 个答案:

答案 0 :(得分:5)

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

您必须向Comparator<Integer[]>构造函数提供TreeMap才能自行定义订单。

BTW,在HashMap中使用数组作为键是一个坏主意(因为数组不会覆盖equals()hashCode()的默认实现),所以&#39你切换到TreeMap是一件好事。

答案 1 :(得分:2)

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

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

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

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

但是,如果你需要使用数组作为键,你可以做的是创建一个带有数组的类作为它的成员并覆盖此类的hashcode()equals()方法并使用此类作为密钥。

答案 2 :(得分:1)

数组没有自然顺序。解决问题并使其可预测的一种方法是做这样的事情:

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

这将比较每个数组的第一个元素。如果数组可以为空,则需要稍微更改一下,这样就不会引发异常。

答案 3 :(得分:1)

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

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

如果您认为通过在数组中移动元素,您将要更改哈希映射的值存储区中项目的排序,那么您会感到非常错误。

答案 4 :(得分:1)

您应该在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]);
        }