我正在为Java8证书做准备,下面的内容让我有点困惑,也许有人能帮我?在这个例子中,一个Squirrel类被建模。它有一个名称和一个权重。现在你可以创建一个比较器类来使用这两个字段对它进行排序。所以首先按名称排序,然后按权重排序。类似于这样:
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);
}
}
到现在为止,一直都还不错。。但接下来是令人困惑的部分。在代码示例下面,它们声明您可以使用方法链接在一行中编写此代码。也许我误解了,但当我将比较部分和thencomparating部分链接起来时,我得到了一个编译错误。这与所比较对象的类型有关(首先是字符串,然后是int)。
为什么当我放入一个中间变量时它会工作,而当链接时它不会工作?那么,有没有可能连锁呢?
是的,这是可能的-链<代码>比较(…) 与<代码>然后比较(…) 和与比较(…) 使用方法引用而不是lambda表达式:
public int compare(Squirrel s1, Squirrel s2) {
return Comparator.comparing(Squirrel::getSpecies)
.thenComparing(Squirrel::getWeight)
.compare(s1, s2);
}
为什么会这样?我无法比Brian在回答类似问题时解释得更好。
此外,这可以用1行重写(假设您有一个要排序的松鼠列表):
list.sort(Comparator.comparing(Squirrel::getSpecies).thenComparing(Squirrel::getWeight));
当您链接两者时,编译器无法推断返回的比较器的类型参数,因为它依赖于返回的比较器本身无法推断出来的比较器。
在lambda参数中指定comparing()
(或使用方法引用)的类型,这样可以推断出comparing()
的返回类型,从而解决推断问题:
Comparator<Squirrel> c = Comparator.comparing((Squirrel s) -> s.getSpecies())
.thenComparingInt(s -> s.getWeight());
请注意,在lambda参数中指定类型,例如:
Comparator<Squirrel> c = Comparator.comparing(s -> s.getSpecies())
.thenComparingInt((Squirrel s) -> s.getWeight());
将不起作用,因为在推理类型计算中未考虑接收方(此处为链式方法的返回类型)。
本JDK 8教程/文档很好地解释了这一点:
注意:需要注意的是,推理算法仅使用调用参数、目标类型和可能的明显理论收益类型来推断类型。推理算法不使用程序后期的结果。
我有一个ArrayList,需要按降序排序。我用java来实现它。util。流动流动排序(比较器)方法。以下是根据Java API的描述: 返回由该流的元素组成的流,根据提供的
问题内容: 假设我有一对班 我希望先按第一个值排序,然后再按第二个值排序。现在,如果我这样做 一切正常,列表按对的第一个值排序,但是如果我这样做 它因错误而失败 好的,所以它可能无法推断参数,所以如果我这样做 它因错误而失败 为什么它对compare()而不是compare()。thenComparing()有效? 问题答案: 该错误似乎与的通用参数有关。一种解决方法是尝试使用显式类型: 请注意,
我想用Lambda对列表排序: 但我得到了这个编译错误:
假设我有一个双人课 我希望对它进行排序,首先是第一个值,然后是第二个值。现在,如果我这样做 一切都很好,列表按对的第一个值排序,但如果我这样做 它因错误而失败 好吧,所以它可能无法推断参数,所以如果我这样做 它因错误而失败 为什么它适用于comparing()而不适用于comparing()。然后比较()?
问题内容: 用于比较的Python文档说: 可以任意链接比较,例如与等效,不同之处在于比较仅被评估一次(但在两种情况下都被发现为假,则根本不评估)。 所以像(人为的例子): 只要求输入一次。这很有道理。和这个: 仅询问 是否 介于1和10之间,并且仅打印“ woo!”。 if 也在10到20之间(证明它们可以“任意链接”)。这也是有道理的。 但是我仍然很好奇在lexer / parser / co
问题内容: 我想知道Java链接器如何工作。具体来说,它将类,接口,包,方法等以何种顺序组合为jvm可执行格式。我在这里找到了一些信息,但是关于链接顺序的信息并不多。 问题答案: 没有Java“链接器”之类的东西。但是,存在类加载器的概念,该类加载器给出了“某处”中的java字节代码数组,可以创建类的内部表示形式,然后可以与etc 一起使用。 在这种情况下,接口只是特殊的类。加载类后,方法和字段将