StackFlowed StackFlowed - 2 months ago 8
Java Question

Removing duplicates from List which uses generics

Problem : I have a utility function which takes in a generic list to remove duplicates, Now when I use it for

List<String>
the match should case insensitive. The code uses streams (Java 8+) and i want to keep it that way.

Note : code is in JAVA 8+

Code :

public static <T> List<T> removeDuplicates(List<T> inputList) {
List<T> result = null;
if (inputList != null && inputList.size() > 0) {
result = inputList.parallelStream().distinct().collect(Collectors.toList());
}
return result;
}


EG:

List<String> inputList = new ArrayList<String>();
inputList.add("a");
inputList.add("A");
inputList.add("abc");
inputList.add("ABC");
inputList.add("c");


When we call
removeDuplicates(inputList)
and print it

Values:

a
abc
c


I don't really care if it choose
ABC
over
abc
or
A
over
a
but it should be there only once.

Is there an elegant way of solving this issue without doing an
instanceof
check ?

Answer

If the caller knows the type of T at compile time, you can have it pass an optional Comparator<T> to the method, and filter out duplicates using a TreeSet:

public static <T> List<T> removeDuplicates(List<T> inputList) {
    // null uses natural ordering
    return removeDuplicates(inputList, null);
}

public static <T> List<T> removeDuplicates(List<T> inputList, Comparator<? super T> comparator) {
    Set<T> set = new TreeSet<>(comparator);
    set.addAll(inputList);
    return new ArrayList<>(set);
}

public static void main(String[] args) {
    System.out.println(removeDuplicates(Arrays.asList(1, 2, 2, 3)));
    System.out.println(removeDuplicates(Arrays.asList("a", "b", "B", "c"), String.CASE_INSENSITIVE_ORDER));
}

Output:

[1, 2, 3]
[a, b, c]
Comments