Is there a class in Java which keeps duplicates but not order of data?

Viewed 102

I am dealing with anagrams so I'm concerned only with the characters present in the string but not their order. I searched for a suitable Collection class but in vain.

Can you please suggest any class that could help me to keep duplicates but ignores order?

3 Answers

You can use a Map<Character,Integer> to count the number of occurrences of each character of a String. If the Maps generated for two Strings are equal, you'll know that the corresponding Strings are anagrams.

For example (here I used Map<Integer,Long> instead of Map<Character,Integer> since it was more convenient):

String one = "animal";
String two = "manila";
Map<Integer,Long> mapOne = one.chars ().boxed().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
Map<Integer,Long> mapTwo = two.chars ().boxed().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
System.out.println ("Is anagram? " + mapOne.equals(mapTwo));

Output:

Is anagram? true

You can use Google guava's HashMultiSet. The equals() method does exactly that:

Compares the specified object with this multiset for equality. Returns true if the given object is also a multiset and contains equal elements with equal counts, regardless of order. This implementation returns true if object is a multiset of the same size and if, for each element, the two multisets have the same count.

Instead of an ordered data structure, one can also dynamically sort the data.

As Unicode symbols, code points, are better than UTF-16 chars, I'll use Unicode ints instead:

int[] canonical(String s) {
    return s.codePoints().sorted().toArray();
}

boolean isAnagram(String s, String t) {
    return Arrays.equals(canonical(s), canonical(t));
}

boolean isAnagram(int[] s, String t) {
    return Arrays.equals(s, canonical(t));
}
Related