【发布时间】:2014-04-24 03:33:17
【问题描述】:
下面是我专门为在 Java 8 Stream 中使用自定义 Comparator 和 max 而编写的代码。
import java.math.BigDecimal;
import java.util.*;
public class BigDecimalMax {
public static BigDecimal getBigDecimalMax(List<forTest> list) {
return list.stream()
.filter(t -> t.id % 2 == 0)
.max(forTestComparator::compare) //<-- syntax error ----------
.orElse(null);
}
public static class forTestComparator implements Comparator<forTest> {
@Override
public int compare(forTest val1, forTest val2) {
return val1.value.compareTo(val2.value);
}
}
public static void main(String[] args) {
List<forTest> lst = new ArrayList<>();
Random rn = new Random();
BigDecimalMax bdm = new BigDecimalMax();
for (int i=1; i<22; ++i) {
lst.add(bdm.new forTest(i, BigDecimal.valueOf(rn.nextLong())));
}
System.out.println(getBigDecimalMax(lst));
}
class forTest {
public int id;
public BigDecimal value;
forTest(int id, BigDecimal value) {
this.id = id;
this.value = value;
}
@Override
public String toString() {
return "forTest{" +
"id=" + id +
", value=" + value +
'}';
}
}
}
我在一个我不理解的方法引用上遇到语法错误。
Error:(15, 18) java: incompatible types: invalid method reference
cannot find symbol
symbol: method compare(BigDecimalMax.forTest, BigDecimalMax.forTest)
location: class BigDecimalMax.forTestComparator
而 IntelliJ IDEA 抱怨 Non-static method cannot be referenced from a static context。
我到底做错了什么?
补充说明(2014 年 4 月 24 日):
我现在明白语法错误的原因了。谢谢。
这里真的需要自定义
Comparator吗?
因为BigDecimal 实现了Comparable 但不 似乎实现了Comparator(它有CompareTo() 但没有 Compare())我认为自定义Comparator 是必要的。这就是为什么我不能只使用Comparator.comparing(ft -> ft.value)。我的逻辑有问题吗?
【问题讨论】:
-
这里不需要自定义比较器。首先,这是 API 的一个令人困惑的领域,因为名称都非常相似。首先,BigDecimal 实现了 Comparable 是正确的,但 Stream.max() 需要一个 Comparator。 Comparator.comparing() 的单参数重载就是这样做的。此外,ForTest 类(原始版本)也没有实现。所以你需要提供一个 lambda
ft -> ft.value来从 ForTest 中提取一个 BigDecimal(它是 Comparable),然后将此 lambda 传递给单参数 Comparator.comparing() 以在给定 Comparable 实例的情况下创建一个 Comparator。 -
@StuartMarks - 我实际上读了几次
comparingdescription,但只有在阅读了你的答案(也是好几次)之后,我才意识到它的意思。所以,comparaing充当了Comparator和Comparable之间的桥梁,对吧? -
是的,这是描述它的好方法。不幸的是,签名中的文档和泛型非常复杂,因此仅通过阅读文档来学习用法非常困难。然后你看到一个例子然后“啊哈!”我希望。
标签: java max java-8 comparator java-stream