【问题标题】:What are practical uses of the java.util.function.Function.identity method?java.util.function.Function.identity 方法的实际用途是什么?
【发布时间】:2019-03-03 02:34:49
【问题描述】:

为什么我应该使用 Function.identity() 当它返回相同的东西而不使用输入做任何事情或以某种方式修改输入时?

Apple apple = new Apple(10, "green");
Function<Apple, Apple> identity = Function.identity();
identity.apply(apple);

这一定有一些我无法弄清楚的实际用法。

【问题讨论】:

    标签: java java-8


    【解决方案1】:

    预期用途是当您使用接受Function 的方法来映射某些内容时,您需要将输入直接映射到函数的输出(“身份”函数)。

    作为一个非常简单的示例,将人员列表映射到从名称到人员的映射:

    import static java.util.function.Function.identity
    
    // [...]
    
    List<Person> persons = ...
    Map<String, Person> = persons.stream()
            .collect(Collectors.toMap(Person::name, identity()))
    

    identity() 函数只是为了方便和可读性。正如彼得在他的回答中指出的那样,您可以只使用t -&gt; t,但我个人认为使用identity() 可以更好地传达意图,因为它没有留下解释的余地​​,比如想知道原作者是否忘记在那个 lambda 中进行转换。我承认这是非常主观的,并且假设读者知道 identity() 做了什么。

    它可能在内存方面有一些额外的优势,因为它重用了单个 lambda 定义,而不是为此调用使用特定的 lambda 定义。我认为在大多数情况下,这种影响可能可以忽略不计。

    【讨论】:

      【解决方案2】:

      例如,您可以将其用于频率计数。

      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());
      }
      

      【讨论】:

      • @Eugene identity()的实现是return t -&gt; t
      • @MarkRotteveel 对。我的意思是this
      • 如果我必须为 lambda 实现编译器,我会让 lambda 成为声明它的类的合成的私有静态字段(使用匿名类),除非它引用的变量的值只能知道在运行时。对于 lambda 是自包含的情况,我不确定您链接的答案是否 100% 正确。
      • @Dici 顺便说一句,这是他们最初想要采用的法律策略(Brian Goetz 对此进行了讨论) - 他们选择不这样做。他们选择使用invokedynamic 并在运行时生成类
      • @Dici 100% 正确,至少在当前实现下,很容易证明...
      【解决方案3】:

      假设您有一个List&lt;String&gt; strings = List.of("abc", "de"),并且您想生成一个Map,其中Key 是List 的值形式,而Value 是它的长度:

       Map<String, Integer> map = strings.stream() 
              .collect(Collectors.toMap(Function.identity(), String::length)) 
      

      通常有些人认为Function.identity()t -&gt; t 可读性差一些,但正如here 解释的那样,这有点不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-02
        • 2019-05-17
        • 2015-04-22
        • 2021-07-22
        • 1970-01-01
        • 1970-01-01
        • 2011-09-20
        相关资源
        最近更新 更多