【问题标题】:how to convert if, while, for logic in to streams如何将 if、while、for 逻辑转换为流
【发布时间】:2021-10-11 20:44:05
【问题描述】:

所以,我制作了一个程序来按出现次数计算单词,并按des order打印它们,如果单词具有相同的频率,它们将按字母顺序排序(也列表包含俄语单词,如果单词具有相同的频率,俄语单词将从英语单词开始下降,俄语单词也将按字母顺序排序。

  • 如果词长小于4,或者频率小于10,我想去掉。

  • 我需要检查 word 是否包含 .,!?删除它们,并在没有这些字符的情况下添加它们。例如:hello!将被添加hello,或者Bye!将被添加Bye

这是一个很好的例子:

лицами-18
Apex-15
azet-15
xder-15
анатолю-15
андреевич-15
батальона-15
hello-13
zello-13
полноте-13

这是我的代码:

public String countWords(List<String> lines) {

    StringBuilder input = new StringBuilder();
    StringBuilder answer = new StringBuilder();

    for (String line : lines){
        if(line.length() > 3){
            if(line.contains(",")){
                line = line.replace(",", "");
                input.append(line).append(" ");
            }else if (line.contains(".")){
                line = line.replace(".", "");
                input.append(line).append(" ");
            }else if (line.contains("!")){
                line = line.replace("!", "");
                input.append(line).append(" ");
            }else if (line.contains("?")){
                line = line.replace("?", "");
                input.append(line).append(" ");
            }else{
                input.append(line).append(" ");
            }
        }
    }

    String[] strings = input.toString().split("\\s");

    List<String> list = new ArrayList<>(Arrays.asList(strings));

    Map<String, Integer> unsortMap = new HashMap<>();

    while (list.size() != 0){
        String word = list.get(0);
        int freq = Collections.frequency(list, word);
        if (word.length() >= 4 && freq >= 10){
            unsortMap.put(word.toLowerCase(), freq);
        }

        list.removeAll(Collections.singleton(word));
    }

    List<String> sortedEntries = unsortMap.entrySet().stream()
            .sorted(Comparator.comparingLong(Map.Entry<String, Integer>::getValue)
                    .reversed()
                    .thenComparing(Map.Entry::getKey)
            )
            .map(it -> it.getKey() + " - " + it.getValue())
            .collect(Collectors.toList());

    for (int i = 0; i < sortedEntries.size(); i++) {
        if(i<sortedEntries.size()-1) {
            answer.append(sortedEntries.get(i)).append("\n");
        }
        else{
            answer.append(sortedEntries.get(i));
        }
    }

    return answer.toString();

}

所以,如您所见,我的代码运行良好。但是,我想超越这一点,我想编写相同的逻辑而不使用 If、While、For。我想用流或 lambda 编写相同的逻辑。如您所见,我能够编写逻辑的一部分来对列表进行排序。但是,我无法编写具有 if 和 while 循环的其他部分。我是 Streams 的新手,我想知道是否有某种方法可以编写相同的代码,而不使用 for、while、if 语句,而只使用流。

【问题讨论】:

标签: java loops lambda java-stream


【解决方案1】:

使用

  • filterflatMap 用于第一个过滤和更换部件
    • 使用 String.replaceAll 一次删除 4 个字符
    • 替换为" " 而不是"" 以避免Hey!you 变成Heyyou
    • \\s+分割,表示空格字符的序列
  • groupingBycountingcount occurence
  • Collectors.joining 代表answer 建筑物部分

public static String countWords(List<String> lines) {
    return lines.stream()
            .filter(l -> l.length() > 3)
            .map(l -> l.replaceAll("[,.!?]", " ").toLowerCase())
            .flatMap(l -> Arrays.stream(l.split("\\s+")))
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet()
            .stream()
            .filter(e -> e.getKey().length() >= 4 && e.getValue() >= 10)
            .sorted(Comparator.comparingLong(Map.Entry<String, Long>::getValue)
                    .reversed()
                    .thenComparing(Map.Entry::getKey)
            )
            .map(it -> it.getKey() + " - " + it.getValue())
            .collect(Collectors.joining("\n"));
}

【讨论】:

  • 如果有 20 hello 和 15 Hello,我应该打印 35 hello,这就是为什么我需要将它转换为小写
  • 哦,非常感谢!很好的解释。
  • 可能值得修复替换和拆分部分Arrays.stream(l.replaceAll("[,.!?]", " ").split("\\s+")) - 替换为" " 并按空格顺序拆分。
猜你喜欢
  • 1970-01-01
  • 2021-06-06
  • 2012-07-11
  • 2020-04-15
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2018-02-17
  • 2018-03-19
相关资源
最近更新 更多