我必须制作有序映射,其中键是int [],值是double。它不能被交换,因为double将被复制。此外,map将按值排序,最后x值将被删除。
我试图制作
Map<int[],Double> map = new TreeMap<>();;
int[] i = {0,1,1,0};
map.put(i,8.5); // ERROR HERE Organisms.java:46
i = new int[]{0,0,0,0};
map.put(i,30.0);
System.out.println("sorted" + sortByValue(map));
线程“AWT-EventQueue-0”中的异常java.lang.ClassCastException: [我无法将其转换为java.lang.Comparable java.util.TreeMap.compare(TreeMap.java:1294)at java.util.TreeMap.put(TreeMap.java:538)at com.pszt_organism.Organisms.test(Organisms.java:46)&lt; - MARKED ERROR
我在此主题中找到了方法sortByValue(Map<K, V> map)
:java8 example by Carter Page
我认为TreeMap对int的排序表有问题。怎么解决?
编辑:
private <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
return map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(/*Collections.reverseOrder()*/))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
}
答案 0 :(得分:3)
问题是Java数组类型没有实现Comparable
。
解决方案:实现一个Comparator
,它将比较您的int[]
密钥,并将一个实例作为参数传递给TreeMap
构造函数。
但是,只有当int[]
个对象在用作密钥时才会发生变异,这才会起作用。如果你改变它们,那么你将会#34;打破&#34; TreeMap
和Map
操作的行为不正确。
您还可以将int[]
对象包装在实现Comparable
的类中,实现compareTo
,equals
和hashCode
。关于突变的同样警告也适用于这种方法。
答案 1 :(得分:1)
int[]
数组不适合用作Map
中的键(有关简要说明,请参阅this Q&A;它讨论数组列表,但同样的逻辑也适用于数组)。
如果您仍然使用数组作为键,请谨慎行事:
由于int[]
不是Comparable
,因此如果不提供用于比较数组的逻辑,则不能将其用作键。
以下是如何做到这一点:
Map<int[],Double> map = new TreeMap<>(
new Comparator<int[]>() {
@Override public int compare(int[] lhs, int[] rhs) {
int len = Math.min(lhs.length, rhs.length);
for (int i = 0 ; i != len ; i++) {
if (lhs[i] != rhs[i]) {
return Integer.compare(lhs[i], rhs[i]);
}
}
// If we're here, common elements match up;
// hence, the longer of the two arrays wins.
return Integer.compare(lhs.length, rhs.length)
}
}
);
答案 2 :(得分:0)
您不需要使用TreeMap
来使用该排序方法。只需使用其他Map
即可。该排序方法为结果创建一个新的LinkedHashMap
,因此作为参数传递的Map
只是一个临时容器。