【问题标题】:Comparator - thenComparing() method produces 'no instance(s) of type variable(s) U exist so that Object conforms to Comparable<? super U>'Comparator - thenComparing() 方法产生\'不存在 U 类型变量的实例,因此 Object 符合 Comparable<?超级U>\'
【发布时间】:2022-09-23 03:33:46
【问题描述】:

Comparator 的方法thenComparing() 的正确用法是什么?为什么它在我的代码中不能正常工作?我不太明白我收到错误的原因:

no instance(s) of type variable(s) U exist so 
that Object conforms to Comparable<? super U>

那是产生错误的代码:

Map<Integer, Long> sortedCards = new LinkedHashMap<>();
List<Card> cards = // initializing the list

cards.stream().collect(
    Collectors.groupingBy(
        card -> card.kind.rank,
        Collectors.counting()
    ))
    .entrySet().stream()
    .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())
                     .thenComparing(Map.Entry::getKey))
    .forEachOrdered(e -> sortedCards.put(e.getKey(), e.getValue()));

我的Card 班级:

public static class Card implements Comparable<Card> {

    private Kind kind;
    
    // constructors, getters, etc.
}

Kind 枚举:

public enum Kind {

    TWO(1, \"2\"), THREE(2, \"3\"), FOUR(3, \"4\"), // etc.;
    
    public int rank;
    // constructors, getters, etc.
}

    标签: java java-stream comparator


    【解决方案1】:

    您遇到的编译错误的原因是类型推断问题。

    当您在构造比较器时链接方法时,编译器无法从目标类型推断方法引用的类型。

    您可以通过使用解决它类型见证,即提供类型钥匙价值在尖括号&lt;K,V&gt; 中爆炸性地出现(这些是comparingByValue() 声明的类型,它产生链中的第一个比较器):

    Map.Entry.<Integer, Long>comparingByValue(Comparator.reverseOrder())
        .thenComparing(Map.Entry::getKey)
    

    此外,最好使用collect() 并作为流执行的结果生成Map 而不是forEachOrdered(),然后通过填充预先创建的映射副作用.它使您的代码更加冗长且缺乏表达力,因为您需要单独实例化生成的集合,并且违反了文档中列出的准则。

    方法forEach()forEachOrdered() 作为最后的手段存在,它是灰心将它们用作collect()reduce() 等归约操作的替代,更多信息请参阅API documentation,注意代码示例。

    如果我们使用collect(),这就是它的样子:

    Map<Integer, Long> sortedCards = cards.stream()
        .collect(Collectors.groupingBy(card -> card.kind.rank, Collectors.counting()))
        .entrySet().stream()
        .sorted(Map.Entry.<Integer, Long>comparingByValue(Comparator.reverseOrder())
            .thenComparing(Map.Entry::getKey))
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            Map.Entry::getValue,
            (left, right) -> {
                throw new AssertionError("duplicate keys are not expected");
            },
            LinkedHashMap::new
        ));
    

    【讨论】:

    • @Magda您的意思是通过以下方式订购钥匙成为下降?您可以使用另一种风格的thenComparing(),它期望功能+比较器.thenComparing(Map.Entry::getKey, Comparator.reverseOrder()))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-16
    • 2022-10-18
    • 2017-12-04
    • 2017-04-22
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    相关资源
    最近更新 更多