java lambda 函数是否唯一(不同的 hashCode 且不等于)?

Are java lambda functions unique (different hashCode and not equals)?

我想知道 java lambda 函数是否总是唯一的? 如果是,是什么让它与众不同?

在这个伪代码中,我有两个 Consumer 和一些代码但不相等,hashCodes 也不同。

    Consumer<String> c1 = s -> {
        System.out.println(s);
    };
    Consumer<String> c2 = s -> {
        System.out.println(s);
    };

    System.out.println(c1.hashCode());  
    System.out.println(c2.hashCode());
    System.out.println(c1.equals(c2)); // false:  is it always false?

我想在一个 Set 中存储一个 lambda 列表,我不确定如果我不小心得到了两个具有相同 hashCode 的 lambda 函数,我是否会丢失一些元素。

根据JLS 15.27.4(强调我的):

The value of a lambda expression is a reference to an instance of a class with the following properties:

  • [...]
  • The class overrides no other methods of the targeted functional interface type or other interface types mentioned above, although it may override methods of the Object class.

因为它说“可以”,所以 lambda 的 class 可能有 equalshashCode 的自定义实现,也可能没有,具体取决于实现。

另请注意:

These rules are meant to offer flexibility to implementations of the Java programming language, in that:

  • A new object need not be allocated on every evaluation.

  • Objects produced by different lambda expressions need not belong to different classes (if the bodies are identical, for example).

  • Every object produced by evaluation need not belong to the same class (captured local variables might be inlined, for example).

  • If an "existing instance" is available, it need not have been created at a previous lambda evaluation (it might have been allocated during the enclosing class's initialization, for example).

一个实现可能会看到您的两个 lambda 具有相同的主体,并且只为您的 lambda 生成一个 class。 class 的 equals 方法可以被重写为 return true,对于任何也是 class 实例的对象。它甚至可以为您的两个 lambda 使用相同的对象!在任何一种情况下,如果您将两个 lambda 都添加到您的集合中,您的集合将只有一个元素。