java 8 lambda 泛型比较器 - 编译器警告

标签 java generics lambda java-8 comparator

此 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

非常感谢您的决议以及解释/评论

最佳答案

您无法定义可以比较任意 ComparableComparator,因为您无法将 String 进行比较整数,尽管两者都实现了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()与您的尝试实现相同的目的,是一种方法而不是一个字段。

关于java 8 lambda 泛型比较器 - 编译器警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38491121/

相关文章:

java - Spring 测试MVC : How to use object as Request Parameters

java - 处理泛型方法中的特定类型采用并返回相同的泛型类型

java - 静态类/接口(interface)的 Guice 泛型配置错误

c# - foreach(... in ...) 或 .ForEach();就是那个问题

java - RFC 2388 多部分 POST 的服务器实现与 RFC 2047 冲突?

java - 使用 CXF 拦截器进行错误处理 - 更改响应消息

java - TelephonyManager.getLine1Number() 返回 null

c# - 注入(inject)通用接口(interface)

c# - 存在于列表中的 lambda 表达式

C# Linq 结果 ToDictionary 帮助