Edit
Here is a genericized example of tobias_k's response:
import java.util.*;
import java.util.stream.Collectors;
public class ArrayUtils {
public static void main(String[] args) {
List<String> values = List.of("Value1", "vALue1", "vALue2", "valUE2");
List<String> deduped = dedupeCaseInsensitive(values);
System.out.println(deduped); // [Value1, vALue2]
}
/* Higher-order function */
public static List<String> dedupeCaseInsensitive(List<String> collection) {
return dedupeWith(collection, String.CASE_INSENSITIVE_ORDER);
}
public static <E> List<E> dedupeWith(List<E> list, Comparator<E> comparator) {
Set<E> seen = new TreeSet<>(comparator);
return list.stream().filter(s -> seen.add(s)).collect(Collectors.toList());
}
}
Original edit
Here is a stream version:
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ArrayUtils {
public static void main(String[] args) {
String[] items = {"Value1", "vALue1", "vALue2", "valUE2"};
String[] result = dedupeCaseInsensitive(items);
// Print the resulting array.
System.out.println(Arrays.toString(result));
}
public static String[] dedupeCaseInsensitive(String[] items) {
return Arrays.stream(items)
.collect(Collectors.toMap(
String::toLowerCase,
Function.identity(),
(o1, o2) -> o1,
LinkedHashMap::new))
.values()
.stream()
.toArray(String[]::new);
}
}
Original response
You can dedupe with case-insensitive logic by populating a Map
, grabbing its values and sorting them.
import java.util.*;
public class ArrayUtils {
public static void main(String[] args) {
String[] items = {"Value1", "vALue1", "vALue2", "valUE2"};
String[] result = dedupeCaseInsensitive(items);
// Print the resulting array.
System.out.println(Arrays.toString(result));
}
public static String[] dedupeCaseInsensitive(String[] items) {
Map<String, String> map = new HashMap<String, String>();
// Filter the values using a map of key being the transformation,
// and the value being the original value.
for (String item : items) {
map.putIfAbsent(item.toLowerCase(), item);
}
List<String> filtered = new ArrayList<>(map.values());
// Sort the filtered values by the original positions.
Collections.sort(filtered,
Comparator.comparingInt(str -> findIndex(items, str)));
return collectionToArray(filtered);
}
/* Convenience methods */
public static String[] collectionToArray(Collection<String> collection) {
return collection.toArray(new String[collection.size()]);
}
public static int findIndex(String arr[], String t) {
return Arrays.binarySearch(arr, t);
}
}
If you use a LinkedHashMap
, you do not need to sort, because the items retain their insertion order.
import java.util.*;
public class ArrayUtils {
public static void main(String[] args) {
String[] items = {"Value1", "vALue1", "vALue2", "valUE2"};
String[] result = dedupeCaseInsensitive(items);
// Print the resulting array.
System.out.println(Arrays.toString(result));
}
public static String[] dedupeCaseInsensitive(String[] items) {
Map<String, String> map = new LinkedHashMap<String, String>();
// Filter the values using a map of key being the transformation,
// and the value being the original value.
for (String item : items) {
map.putIfAbsent(item.toLowerCase(), item);
}
return collectionToArray(map.values());
}
/* Convenience methods */
public static String[] collectionToArray(Collection<String> collection) {
return collection.toArray(new String[collection.size()]);
}
}}