Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate with HashSet using method reference

I want to know if my List<T> has duplicates elements.

I have seen the method below :

public static <T> boolean areAllUnique(List<T> list){
    return list.stream().allMatch(new HashSet<>()::add);
}

It works and I'm surprised why ? Because it seems a new HashSet<> is created everytime (so basically the method should always return true even if duplicates)

If I write differently the method above, it no longer works :

public static <T> boolean areAllUnique(List<T> list){
    return list.stream().allMatch(t -> {
        return new HashSet<>().add(t);
    });
}

I'm surprised the 1st method works while the other does not. Because for me they look the same

like image 535
AntonBoarf Avatar asked Jan 15 '20 09:01

AntonBoarf


People also ask

How do I allow duplicates in HashSet?

Duplicates: HashSet doesn't allow duplicate values. HashMap stores key, value pairs and it does not allow duplicate keys. If the key is duplicate then the old key is replaced with the new value.

How HashSet detect duplicates?

By using HashSet, a general-purpose Set implementation, we can find duplicates in O(n) time. All you need to do is iterate over an array using advanced for loop and insert every element into HashSet. Since it allows only unique elements, add() method will fail and return false when you try to add duplicates.

Can HashSet have duplicate objects?

HashSets are used to store a collection of unique elements. HashSet cannot contain duplicate values. HashSet allows null value. HashSet is an unordered collection.

What happens if you add a duplicate to a HashSet?

HashSet doesn't allow duplicates. If you try to add a duplicate element in HashSet, the old value would be overwritten. HashSet allows null values, however if you insert more than one nulls, it would override the previous null value.


1 Answers

new HashSet<>()::add is a method reference referencing a specific instance of a HashSet.

It's equivalent to creating an instance of a HashSet outside that method, storing a reference to it in a variable set, and using the method reference set::add instead. i.e. it will always operate on the same HashSet instance.

The lambda expression behaves differently, since the body of the lambda expression is executed each time allMatch() has to apply the Predicate to an element of the Stream. And each time the body is executed, a new HashSet instance is created.

like image 72
Eran Avatar answered Oct 05 '22 20:10

Eran