【问题标题】:java 8 lambda generics comparator - compiler warningsjava 8 lambda泛型比较器 - 编译器警告
【发布时间】:2016-07-20 21:25:07
【问题描述】:

这个 lambda 表达式比较 2 个对象:

private static final Comparator NATURAL_ORDER_COMPARATOR1 = 
        (Comparator) (final Object o1, final Object o2) -> ((Comparable) o1).compareTo(o2);

产生这个编译警告:

warning: [unchecked] unchecked call to compareTo(T) as a member of the raw type Comparable
(Comparator) (final Object o1, final Object o2) -> ((Comparable) o1).compareTo(o2);
where T is a type-variable:
T extends Object declared in interface Comparable

这个 lambda 表达式比较 2 T 个对象:

private final Comparator<T> NATURAL_ORDER_COMPARATOR2 = 
        (Comparator<T>) (final T o1, final T o2) -> ((Comparable<T>) o1).compareTo(o2);

产生这个编译警告:

warning: [unchecked] unchecked cast
(Comparator<T>) (final T o1, final T o2) -> ((Comparable<T>) o1).compareTo(o2);
required: Comparable<T>
found:    T
where T is a type-variable:
T extends Object declared in class Tree01

非常感谢您的解释/cmets 解决方案

【问题讨论】:

    标签: java generics lambda java-8 comparator


    【解决方案1】:

    您无法定义可以比较任意Comparables 的Comparator,因为您无法将StringInteger 进行比较,尽管两者都实现了Comparable。您需要一个类型变量来制定约束条件,即Comparator.compare 方法的两个参数必须兼容才能进行比较。

    但是使用字段定义这样的通用Comparator 是不可能的,因为在声明字段时不能引入类型参数。它只能使用工厂方法:

    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return (a,b) -> a.compareTo(b);
    }
    

    public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
        return Comparable::compareTo;
    }
    

    你可以像这样使用

    Comparator<Integer> ci = naturalOrder();
    Comparator<String> cs  = naturalOrder();
    // in the current version of Oracle's JRE/OpenJDK this will print true
    System.out.println(ci==(Object)cs);
    

    这表明使用给定的 JRE,它会生成一个单例实例,在性能方面与存储在字段中的比较器相当。但是从泛型的角度来看,它们具有不兼容的类型,因此无法定义一个包含该比较器并同时与IntegerString 兼容的变量。

    无法声明带有类型参数的字段是为什么Collections.EMPTY_LIST 在引入泛型时得到了Collections.emptyList() 的补充,或者为什么新方法Comparator.naturalOrder() 与您的尝试具有相同的目的,而是一种方法而不是而不是一个字段。

    【讨论】:

    • 谢谢你,霍尔格。这是有道理的,而且解释得很好(总统的程序员)。
    猜你喜欢
    • 2017-10-28
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多