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]);
}