【问题标题】:PriorityQueue Sort By Map Value with out Lambda (older version of Java)PriorityQueue 按映射值排序,不使用 Lambda(Java 的旧版本)
【发布时间】:2021-01-20 22:31:14
【问题描述】:

以下问题需要在 jdk 1.8 之前解决。
我有一个字符串 S="aab"。所有字符都根据它们的频率放入HashMap。现在用Comparator 声明PriorityQueue。这样所有字符都可以按频率降序存储在PriorityQueue中。但我收到以下错误--

    Map<Character, Integer> dicT = new HashMap<>();        
    for(int i = 0;i < S.length(); i++) {           
       dicT.put(S.charAt(i), dicT.getOrDefault(S.charAt(i), 0) + 1);
    }

    PriorityQueue<Character> maxHeap = new PriorityQueue(
        new Comparator<Map.Entry<Character,Integer>>() {
            public int compare(Map.Entry<Character, Integer> entry1, 
                               Map.Entry<Character, Integer> entry2) {
                return entry2.getValue().compareTo(entry1.getValue());
            }
        });
        
    maxHeap.addAll(dicT.keySet());

错误(仅使用较新的jdk演示问题,目标jdk版本在jdk 1.8之前)---

java.lang.ClassCastException: 类 java.lang.Character
不能转换为类 java.util.Map$Entry
(java.lang.Character 和 java.util.Map$Entry 在模块中
java.base of loader 'bootstrap') 在第 14 行,
解决方案 1 美元。比较第 659 行,
java.base/java.util.PriorityQueue.siftUpUsingComparator 在第 636 行,
java.base/java.util.PriorityQueue.siftUp 在第 329 行,
java.base/java.util.PriorityQueue.offer 在第 310 行,
java.base/java.util.PriorityQueue.add 在第 187 行,
java.base/java.util.AbstractQueue.addAll 在第 22 行,
Solution.reorganizeString 在第 54 行,
DriverSolution.helper 在第 84 行,
Driver.main

但如果我使用 lambda,那么它工作正常 --

PriorityQueue<Character> maxHeap = new PriorityQueue(
        (x, y) -> dicT.get(y) - dicT.get(x));
    maxHeap.addAll(dicT.keySet());

请帮助我如何在没有 lambda 的情况下编写代码块?

【问题讨论】:

  • 在创建泛型类的实例时不要忽略&lt;&gt;,即new PriorityQueue&lt;&gt;(…),也不要因为忽略它而忽略编译器警告。对了,dicT.put(S.charAt(i),dicT.getOrDefault(S.charAt(i),0)+1);可以简化为dicT.merge(S.charAt(i), 1, Integer::sum);

标签: java arrays algorithm collections comparator


【解决方案1】:

您正在声明一个PriorityQueue&lt;Character&gt;,它使用Comparator&lt;Character&gt; 来定义优先级。但是您提供的是Comparator&lt;Map.Entry&lt;...&gt;&gt;,因此出现了错误。改为Comparator&lt;Character&gt;

Comparator<Character> order = Comparator.comparingInt(dict::get).reversed();
PriorityQueue<Character> maxHeap = new PriorityQueue<>(order);

您可以使用匿名类而不是 Comparator 静态方法,但我真的看不出有什么理由这样做。

【讨论】:

  • 您的代码按升序排列。但我需要它按降序排列。如果我想写代码比较方法我该怎么办?
  • 使用reversed 方法。我已经更改了我的代码以反映。我很想知道您为什么要编写 compare 代码而不是使用 Comparator 静态方法?
  • @Numery 在您选择的 IDE 中,单击 lambda 表达式版本并选择“转换为匿名类”。
  • 这与我的 IDE 无关。我的工作场所不允许我们使用所有的 Oracle 库。而且项目太旧了。使用旧版本的 jdk。所以我们不能使用任何 lambda 或方法引用。
  • @Numery 如果您需要使用较旧版本的 Java,那么将其包含在您的问题中会很有帮助。 Lamba 函数并不是唯一依赖于版本的 Java 功能。
【解决方案2】:

非常感谢您的帮助。这与我的 IDE 无关。我的工作场所不允许我们使用所有的 Oracle 库。而且项目太旧了。使用旧版本的 jdk。所以我们不能使用任何 lambda 或方法引用。但我能够找出解决方案。

  1. 没有 Lambda --

    PriorityQueue<Character> maxHeap= new PriorityQueue(new Comparator<Character>(){           
         public int compare(Character c1, Character c2){
             return dicT.get(c2) - dicT.get(c1);
         }            
     });
    
  2. 使用 Lambda --

    PriorityQueue<Character> maxHeap =new PriorityQueue((x,y)->dicT.get(y)-dicT.get(x));
    
  3. 有方法参考--

    PriorityQueue<Character> maxHeap = new PriorityQueue(Comparator.comparingInt(dicT::get).reversed());
    

【讨论】:

    猜你喜欢
    • 2021-03-01
    • 1970-01-01
    • 2019-04-29
    • 2011-11-19
    • 2013-02-01
    • 2010-10-10
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    相关资源
    最近更新 更多