如何将 if, while, for 逻辑转换为流
how to convert if, while, for logic in to streams
所以,我做了一个程序来按出现次数计算单词,并按des顺序打印它们,如果单词具有相同的频率,它们将按字母顺序排序(也列表包含俄语单词,如果单词具有相同的频率频率,俄语单词将从英语单词下降,俄语单词也将按字母顺序排序)。
如果字长小于4,或者频率小于10,我要去掉
我需要检查单词是否包含 .,!?删除它们,并在没有这些字符的情况下添加它们。例如: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 语句,只使用流。
使用
filter
和 flatMap
用于第一个过滤和替换部分
- 使用
String.replaceAll
一次删除4个字符
- 替换为
" "
而不是 ""
以避免 Hey!you
变成 Heyyou
- 与
\s+
分开,这意味着 space 个字符的序列
groupingBy
和 counting
到 count 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"));
}
所以,我做了一个程序来按出现次数计算单词,并按des顺序打印它们,如果单词具有相同的频率,它们将按字母顺序排序(也列表包含俄语单词,如果单词具有相同的频率频率,俄语单词将从英语单词下降,俄语单词也将按字母顺序排序)。
如果字长小于4,或者频率小于10,我要去掉
我需要检查单词是否包含 .,!?删除它们,并在没有这些字符的情况下添加它们。例如:
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 语句,只使用流。
使用
filter
和flatMap
用于第一个过滤和替换部分- 使用
String.replaceAll
一次删除4个字符 - 替换为
" "
而不是""
以避免Hey!you
变成Heyyou
- 与
\s+
分开,这意味着 space 个字符的序列
- 使用
groupingBy
和counting
到 count occurenceCollectors.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"));
}