简体   繁体   English

将具有条件逻辑的多个 for 循环转换为 Java 8 流

[英]Convert multiple for loops with conditional logic to Java 8 streams

I need to convert this code containing multiple for loops and if statements to Java 8 Streams :我需要将此包含多个 for 循环和 if 语句的代码转换为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?任何人都可以帮忙吗?

You build a map of name to frequency count, then get the names with a count of 1.您构建一个name到频率计数的映射,然后获得计数为 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]
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());

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:您可以根据equalsIgnoreCase对相等的名称进行equalsIgnoreCase (通过将所有String转换为小写),并仅保留大小为 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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM