Reputation: 35
I need to convert this code containing multiple for loops and if statements to Java 8 Streams:
public static List<String> removeDuplicateNames(String[] namesArray){
List<String> uniqueNames = new ArrayList<>();
int occurrence = 0;
for(String name: namesArray) {
for (String name2 : namesArray)
if (name.equalsIgnoreCase(name2))
occurrence++;
if (occurrence == 1)
uniqueNames.add(name);
occurrence = 0;
}
return uniqueNames;
}
I need to loop through an array of names and return a list containing only the names that are not duplicate. If a name appears more than once I need to remove it from the final List.
Input -> ["Tom", "George", "Tom", "Mike", "Brian"]
Output -> ["George", "Mike", "Brian"]
Can anyone please help out?
Upvotes: 0
Views: 463
Reputation: 11
List<String> names = Arrays.asList("Tom", "George", "Tom", "Mike", "Brian");
Set<String> namesHavingOnlyOneOccurrence = names.stream().collect(Collectors.groupingBy(o -> o)).entrySet()
.stream()
.filter(stringListEntry -> stringListEntry.getValue().size() == 1)
.map(Map.Entry::getKey)
.collect(Collectors.toSet());
Upvotes: 1
Reputation: 393781
You can group the names which are equal according to equalsIgnoreCase
(by converting all the String
s to lower case), and keep only the groups of size 1:
public static List<String> removeDuplicateNames(String[] namesArray){
return Arrays.stream(namesArray)
.collect(Collectors.groupingBy(String::toLowerCase))
.values()
.stream()
.filter(l -> l.size() == 1)
.map(l -> l.get(0)) // or .flatMap(List::stream)
.collect(Collectors.toList());
}
Test:
System.out.println(removeDuplicateNames(new String[] {"This", "is", "a", "test", "A", "better", "Test"}));
Output:
[better, This, is]
Upvotes: 0
Reputation: 159086
You build a map of name
to frequency count, then get the names with a count of 1.
That is actually also what your non-stream code should have been doing, for better performance.
public static List<String> removeDuplicateNames(String... namesArray) {
return Stream.of(namesArray)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(Entry::getKey)
.collect(Collectors.toList());
}
Test
System.out.println(removeDuplicateNames("This", "is", "a", "test", "a", "real", "good", "test"));
Output
[This, is, real, good]
Upvotes: 1