Just try this out to get the answer:
Object object = ...;
Supplier<String> s1 = object::toString;
Supplier<String> s2 = object::toString;
System.out.println(s1.equals(s2));
And the answer is... unfortunately not.
OF course if you keep the same reference (i.e. the same object), it will work; but if, as the example above, you request two lambdas, although they seem to be identical, they will never be equal.
Therefore reference = object::method
and then later remove(reference)
will obviously work, but remove(sameObject::sameMethod)
from a collection will never work if it is written literaly as such.
The answer is also no for constructor (e.g. ArrayList::new) and unbound methods (e.g. Object::toString). It seems that a new lambda is constructed each time you use a lambda expression.
As @Hitobat points it out, this unequality makes sense if you think about what exactly are lambdas and where do they come from. Basicly, Supplier<String> x = myObject::toString
is a syntactic suggar for Supplier<String> x = new Supplier<String>( ... )
. Without a proper Object.equals overloading, two instances of an anonymous class are obviously different. As many people probably, I though that there was a kind of cache of frequently used lambdas somewhere to make it more efficient; well, not at all.