我正在准备Java 8证书,以下让我感到困惑,也许有人可以帮我解决这个问题? 在该示例中,对Squirrel类进行了建模。它有名字和重量。现在你可以创建一个Comparator类来使用这两个字段对这个东西进行排序。所以首先按名称排序,然后按重量排序。像这样:
public class ChainingComparator implements Comparator<Squirrel> {
public int compare(Squirrel s1, Squirrel s2) {
Comparator<Squirrel> c = Comparator.comparing(s -> s.getSpecies());
c = c.thenComparingInt(s -> s.getWeight());
return c.compare(s1, s2);
}
}
到目前为止一直很好..但是那时令人费解的部分。在代码示例下面,他们声明您可以使用方法链接在一行中编写它。也许我误解了,但当我链接比较和 thenComparing 部分时,我得到一个编译错误。它与被比较的对象类型有关(首先是String,然后是int)。
为什么当我输入一个中间变量而不是链接时它可以工作?是否可以连锁?
答案 0 :(得分:8)
当你链接两者时,编译器无法推断返回的comparing()
比较器的类型参数,因为它取决于返回的thenComparingInt()
比较器本身无法推断。
在comparing()
的lambda参数中指定类型(或使用方法引用),它解决了推理问题,因为可以推断返回的comparing()
类型。 :
Comparator<Squirrel> c = Comparator.comparing((Squirrel s) -> s.getSpecies())
.thenComparingInt(s -> s.getWeight());
请注意,在thenComparingInt()
(或使用方法引用)的lambda参数中指定类型,例如:
Comparator<Squirrel> c = Comparator.comparing(s -> s.getSpecies())
.thenComparingInt((Squirrel s) -> s.getWeight());
将不起作为接收器(这里是链接方法的返回类型)在推理类型计算中不被考虑。
This JDK 8 tutorial/documentation非常清楚地解释道:
注意:请务必注意推理算法仅使用 调用参数,目标类型,可能是一个明显的预期 返回类型以推断类型。推理算法不使用 该计划后期的结果。
答案 1 :(得分:5)
是的,有可能 - 链thenComparing(...)
与compare(...)
和public int compare(Squirrel s1, Squirrel s2) {
return Comparator.comparing(Squirrel::getSpecies)
.thenComparing(Squirrel::getWeight)
.compare(s1, s2);
}
使用方法引用而不是lambda表达式:
list.sort(Comparator.comparing(Squirrel::getSpecies).thenComparing(Squirrel::getWeight));
为什么这样工作?我无法在他的answer中向Brian({3}}更好地解释它。
此外,这可以用1行重写(假设您有一个要排序的松鼠列表):
let spanNumber = document.querySelector('.number1')
let number = spanNumber.textContent
let newNumber = number.split('.').join(',')
spanNumber.innerHTML = newNumber