为什么我在不使用输入或以某种方式修改输入的情况下返回它收到的相同内容时应该使用Function.identity()?
Apple apple = new Apple(10, "green");
Function<Apple, Apple> identity = Function.identity();
identity.apply(apple);
必须对此有一些实际用途,我无法弄清。
答案 0 :(得分:22)
预期用途是当您使用接受Function
来映射某些内容的方法时,您需要将输入直接映射到该函数的输出(“ identity”函数)。
作为一个非常简单的示例,将人员列表映射到从名称到人员的地图:
import static java.util.function.Function.identity
// [...]
List<Person> persons = ...
Map<String, Person> = persons.stream()
.collect(Collectors.toMap(Person::name, identity()))
identity()
函数只是为了方便和易读。正如Peter在回答中所指出的那样,您可以只使用t -> t
,但我个人认为使用identity()
可以更好地传达意图,因为它没有解释的余地,例如想知道原始作者是否忘记了进行转换。那lambda。我承认这是非常主观的,并且假定读者知道 identity()
的工作。
在重用单个lambda定义而不是为此调用具有特定的lambda定义的情况下,它可能在内存方面具有一些其他优点。我认为在大多数情况下这种影响可以忽略不计。
答案 1 :(得分:13)
例如,您可以将其用于频率计数。
public static <T> Map<T, Long> frequencyCount(Collection<T> words) {
return words.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting());
}
在这种情况下,您要说“分组依据”的关键是集合中的元素(不进行转换)。
我个人有这个简报
import static java.util.stream.Collectors.*;
public static Map<String, Long> frequencyCount(Collection<String> words) {
return words.stream()
.collect(groupingBy(t -> t,
counting());
}
答案 2 :(得分:3)
假设您有一个List<String> strings = List.of("abc", "de")
,并且想要生成一个Map
,其中Key
是值形式,而List是值的长度:
Map<String, Integer> map = strings.stream()
.collect(Collectors.toMap(Function.identity(), String::length))
通常,有些人看到Function.identity()
的可读性比t -> t
差一点,但是正如here所述,这有点不同。