【问题标题】:TreeMap<int[],Double> initialisation and sorting by valueTreeMap<int[],Double> 初始化和按值排序
【发布时间】:2017-05-22 13:01:53
【问题描述】:

我必须制作键为 int[] 且值为双精度的排序映射。它不能被交换,因为 double 将被复制。此外,地图将按值排序,最后 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 at java.util.TreeMap.compare(TreeMap.java:1294) 在 java.util.TreeMap.put(TreeMap.java:538) 在 com.pszt_organism.Organisms.test(Organisms.java:46)

我在这个话题中找到了方法sortByValue(Map&lt;K, V&gt; 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
                ));
    }

【问题讨论】:

  • 能否分享一下你的sortByValue函数实现
  • 您需要将int[] 包装到一个实现Comparable 以及hashcode()equals() 方法的类中
  • 如果您希望它按值排序,那么为什么还要麻烦按键排序的地图实现呢?

标签: java sorting treemap


【解决方案1】:

问题是Java数组类型没有实现Comparable

解决方案:实现一个Comparator,它将比较您的int[] 键,并将一个实例作为参数传递给TreeMap 构造函数。

但是,这仅适用于 int[] 对象在用作键时未发生变异的情况。如果您对它们进行变异,那么您将“破坏”TreeMapMap 操作的行为将不正确。

您还可以将int[] 对象包装在实现Comparable、实现compareToequalshashCode 的类中。关于突变的同样警告也适用于这种方法。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 这个,除了你应该只保留一个最终的静态比较器并传递它。永久内存使用量稍微多一些,分配量少很多。
    【解决方案3】:

    您无需使用TreeMap 即可使用该排序方法。只需使用不同的Map。该排序方法会为结果创建一个新的LinkedHashMap,因此作为参数传递的Map 只是一个临时容器。

    【讨论】:

      猜你喜欢
      • 2017-08-13
      • 2023-03-10
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多