相关疑难解决方法(0)

Java 8 lambdas,Function.identity()或t-> t

我对该Function.identity()方法的用法有疑问.

想象一下以下代码:

Arrays.asList("a", "b", "c")
          .stream()
          .map(Function.identity()) // <- This,
          .map(str -> str)          // <- is the same as this.
          .collect(Collectors.toMap(
                       Function.identity(), // <-- And this,
                       str -> str));        // <-- is the same as this.
Run Code Online (Sandbox Code Playgroud)

是否有任何理由你应该使用Function.identity()而不是str->str(反之亦然).我认为第二种选择更具可读性(当然是品味问题).但是,有没有"真正的"理由为什么应该首选?

java lambda java-8

211
推荐指数
3
解决办法
10万
查看次数

为什么添加".map(a - > a)"允许这个编译?

这与我对"流减少不兼容类型"的回答有关.我不知道为什么我的建议有用,而霍尔格正确地向我施压.但即使他似乎也没有清楚解释它为何起作用.那么,让我们问它自己的问题:

以下代码无法编译javac(对于下面的ideone链接,这是sun-jdk-1.8.0_51根据http://ideone.com/faq):

public <T> Object with(Stream<Predicate<? super T>> predicates) {
  return predicates.reduce(Predicate::or);
}
Run Code Online (Sandbox Code Playgroud)

这是正确的:或者将这个流中的两个谓词组合在一起就像写:

Predicate<? super T> a = null;
Predicate<? super T> b = null;
a.or(b);  // Compiler error!
Run Code Online (Sandbox Code Playgroud)

但是,它确实在intellij中编译,尽管在Predicate::or方法引用上有原始类型警告.显然,它也会在eclipse中编译(根据原始问题).

但是这段代码确实:

public <T> Object with(Stream<Predicate<? super T>> predicates) {
  return predicates.map(a -> a).reduce(Predicate::or);
                // ^----------^ Added
}
Run Code Online (Sandbox Code Playgroud)

Ideone demo

尽管我想要尝试这个,但我并不完全清楚为什么这会起作用.我的手工波形解释是,.map(a -> a)行为类似于"强制转换",并为类型推断算法提供了更多的灵活性来选择允许reduce应用的类型.但我不确定那种类型到底是什么.

请注意,这不等于使用.map(Function.identity()),因为它被约束为返回输入类型.ideone demo

任何人都可以解释为什么这可以参考语言规范,或者如Holger建议的那样,它是一个编译器错误?


更详细一点:

该方法的返回类型可以更具体一些; 我在上面省略了它,以便返回类型上令人讨厌的泛型不会妨碍:

public <T> …
Run Code Online (Sandbox Code Playgroud)

java generics language-specifications java-8

23
推荐指数
1
解决办法
514
查看次数

标签 统计

java ×2

java-8 ×2

generics ×1

lambda ×1

language-specifications ×1