Java 当键是数组时对映射键进行排序

Java 当键是数组时对映射键进行排序,java,arrays,dictionary,Java,Arrays,Dictionary,我有一个HashMap,可能需要将其转换为TreeMap。树映射的键(即数组)将如何排序?由他们的第一要素 我本来打算运行一个简单的测试,但不知怎的导致了错误: public class treeMapTest { public static void main(String[] args) { Integer arr1[] = {9, 0, 3}; Integer arr2[] = {2, 2, 2}; Integer arr3[] =

我有一个
HashMap
,可能需要将其转换为
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);
    }
}
公共类树形图{
公共静态void main(字符串[]args){
整数arr1[]={9,0,3};
整数arr2[]={2,2,2};
整数arr3[]={4,2,1};
TreeMap tm=新的TreeMap();
tm.put(arr1,7);
tm.put(arr2,7);
tm.put(arr3,7);
系统输出println(tm);
}
}

谢谢。

数组没有自然排序(即,它们没有实现
可比较的
接口),这就是为什么在使用无参数构造函数实例化
树映射时,代码会引发异常

您必须向
TreeMap
构造函数提供
比较器
,以便自己定义排序


顺便说一句,在
HashMap
中使用数组作为键是一个坏主意(因为数组不会覆盖
equals()
hashCode()
)的默认实现),所以最好切换到
TreeMap
数组没有自然顺序。解决这一问题并使其可预测的一种方法是这样做:

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

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

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

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


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

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

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


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

您应该在树映射中为您的排序首选项提供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]);
        }
publicstaticvoidmain(字符串[]args){
整数arr1[]={9,0,3};
整数arr2[]={2,2,2};
整数arr3[]={4,2,1};
TreeMap tm=新的TreeMap(新的比较器(){
@凌驾
公共整数比较(整数[]o1,整数[]o2){
int cmp=o1[0]。与(o2[0])相比;
返回cmp;
}
});
tm.put(arr1,7);
tm.put(arr2,7);
tm.put(arr3,7);
对于(整数[]o1:tm.keySet())
System.out.println(o1[0]);
}

奇怪,我以前从未见过这种错误;-)正确的。否则,您将在线程“main”java.lang.ClassCastException中得到
异常:[Ljava.lang.Integer;无法转换为java.lang.Comparable
是的,这就是我得到的异常。谢谢。@Vic这是一个您知道的重要信息;)这还不能回答排序问题;)好的,一旦您“创建一个以数组为成员的类”,问题很快就会出现;)
Integer arr1_copy[] = {9, 0, 3};
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]);
        }