Reputation: 9008
I came across this code on HackerRank, and I really confused myself by understanding this piece of code, which does check uniqueness of the elements in the array using HashMap.
Now to give you an insight, I know how to do this, and it is easy too. But this code is different and I really need to learn how and what it does actually.
int[] seq = new int[]{3,2,1,3};
Integer[] tmp = new Integer[seq.length];
for (int i = 0; i < seq.length; ++i) {
tmp[i] = Integer.valueOf(seq[i]);
}
/* THIS PIECE OF CODE, HOW THIS WORKS AND WHAT IT DOES???*/
if (!((new LinkedHashSet<Integer>(Arrays.asList(tmp))).size() == seq.length)) {
throw new AssertionError("not all values are unique");
}
All I could make out is it converts the arrays into the list of tmp
Arrays.asList(tmp)
2. Converts it to the LinkedHashSet
LinkedHashSet<Integer>(Arrays.asList(tmp))
3. Then finds the size of the HashSet
(LinkedHashSet<Integer>(Arrays.asList(tmp))).size()
4. Compares it to the length of the array seq.
(new LinkedHashSet<Integer>(Arrays.asList(tmp))).size() == seq.length)
And if the length is not equal to the array seq
, then how come the elements are unique?
Upvotes: 2
Views: 998
Reputation: 16908
The code you posted does the following:
Converts the Integer[]
to a List<Integer>
. So that a Set
object can be easily constructed out of the List<Integer>
. This is because the LinkedHasSet
has a constructor which accepts another Collection
type and constructs a set from it using its values.
Converts the List<Integer>
to LinkedHashSet<Integer>
and when that happens, if there were duplicate Integer
s in the List<Integer>
as lists can have duplicates, that would be eliminated in the resulting set.
Now in the final step the size of the LinkedHashSet<Integer>
is calculated if the size is not equal to the length
of the original array seq
then it means some elements in the LinkedHashSet<Integer>
was duplicate and were removed on conversion.
QUESTION: And if the length is not equal to the array seq, then how come the elements are unique?
That is because if the resulting LinkedHashSet<Integer>
has fewer elements compared to the initial Integer[]
then it would mean that duplicate objects were eliminated. And if they are equal it would mean that no objects were eliminated and all of them were unique.
If you want to do the check in fewer lines of code you can do this using the Streams
API:
int[] seq = new int[]{3,2,1,3};
System.out.println(String.format("Array has duplicates: %b",
Arrays.stream(seq).distinct().count() != seq.length));
This would give you Array has duplicates: true
as it has duplicates in the seq
array.
Upvotes: 1
Reputation: 393886
This code creates a LinkedHashSet
that contains all the elements of the original array (boxed from int
to Integer
).
Since a LinkedHashSet
(like all Set
s) contains no duplicate elements, the original array has no duplicates if and only if the size of the Set
is equal to the length of the array.
If the array had any duplicates, the size of the Set
would have been smaller than the array's length, since the duplicates would have been eliminated when the LinkedHashSet
is initialized.
Upvotes: 5