如何将 Collectors.collectingAndThen 与 Collectors.groupingBy 一起使用
How to use Collectors.collectingAndThen with Collectors.groupingBy
以下面的列表为例:
List<String> input = List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR", "BAR", "BAZ", "BAZ", "BAZ", "DOO", "DOO");
我需要获取每个元素的相对频率并将其打印为字符串格式。为此,我使用了 2 个步骤,首先创建一个频率图,然后计算相对百分比和格式:
Map<String, Long> relativeFrequency =
input.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
Map<String, String> relativeFrequency2 = relativeFrequency.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> String.format ( "%.02f%%", entry.getValue() * 100. / input.size() )));
System.out.println(relativeFrequency2);
并得到结果
{BAR=16.67%, DOO=16.67%, FOO=41.67%, BAZ=25.00%}
有人告诉我重构上面的内容并使用 Collectors.collectingAndThen 一次性完成,但我似乎找不到正确的语法(编译错误 Operator '*' cannot be applied to '<lambda parameter>', 'double'
).有人可以帮助更正以下内容以获得与上述相同的结果吗?
Map<String, String> relativeFrequency3 =
input.stream().collect(Collectors.collectingAndThen(Collectors.groupingBy(Function.identity(), Collectors.counting(),
total -> String.format ( "%.02f%%", total * 100. / input.size() ))
));
import java.util.*;
import java.util.stream.*;
import java.util.function.Function;
class Main {
public static void main(String args[]) {
var input = List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR", "BAR", "BAZ", "BAZ", "BAZ", "DOO", "DOO");
var out = input.stream()
.collect(Collectors.groupingBy(
w -> w,
Collectors.collectingAndThen(
Collectors.summingInt(w -> 1),
s -> String.format("%.02f%%", s * 100. / input.size()))
));
System.out.println(out);
}
}
你很接近。
List<String> input =
List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR",
"BAR", "BAZ", "BAZ", "BAZ", "DOO", "DOO");
collectingAndThen
的第一个参数是 counting()
以获得频率。
- 然后通过将频率转换为格式化的百分比来处理该频率。
Map<String, String> map = input.stream().collect(Collectors
.groupingBy(a -> a, Collectors.collectingAndThen(
Collectors.counting(),
count -> "%.2f%%".formatted((double) count
/ input.size() * 100))));
map.entrySet().forEach(System.out::println);
打印每个条目集产生
BAR=16.67%
DOO=16.67%
FOO=41.67%
BAZ=25.00%
以下面的列表为例:
List<String> input = List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR", "BAR", "BAZ", "BAZ", "BAZ", "DOO", "DOO");
我需要获取每个元素的相对频率并将其打印为字符串格式。为此,我使用了 2 个步骤,首先创建一个频率图,然后计算相对百分比和格式:
Map<String, Long> relativeFrequency =
input.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
Map<String, String> relativeFrequency2 = relativeFrequency.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> String.format ( "%.02f%%", entry.getValue() * 100. / input.size() )));
System.out.println(relativeFrequency2);
并得到结果
{BAR=16.67%, DOO=16.67%, FOO=41.67%, BAZ=25.00%}
有人告诉我重构上面的内容并使用 Collectors.collectingAndThen 一次性完成,但我似乎找不到正确的语法(编译错误 Operator '*' cannot be applied to '<lambda parameter>', 'double'
).有人可以帮助更正以下内容以获得与上述相同的结果吗?
Map<String, String> relativeFrequency3 =
input.stream().collect(Collectors.collectingAndThen(Collectors.groupingBy(Function.identity(), Collectors.counting(),
total -> String.format ( "%.02f%%", total * 100. / input.size() ))
));
import java.util.*;
import java.util.stream.*;
import java.util.function.Function;
class Main {
public static void main(String args[]) {
var input = List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR", "BAR", "BAZ", "BAZ", "BAZ", "DOO", "DOO");
var out = input.stream()
.collect(Collectors.groupingBy(
w -> w,
Collectors.collectingAndThen(
Collectors.summingInt(w -> 1),
s -> String.format("%.02f%%", s * 100. / input.size()))
));
System.out.println(out);
}
}
你很接近。
List<String> input =
List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR",
"BAR", "BAZ", "BAZ", "BAZ", "DOO", "DOO");
collectingAndThen
的第一个参数是counting()
以获得频率。- 然后通过将频率转换为格式化的百分比来处理该频率。
Map<String, String> map = input.stream().collect(Collectors
.groupingBy(a -> a, Collectors.collectingAndThen(
Collectors.counting(),
count -> "%.2f%%".formatted((double) count
/ input.size() * 100))));
map.entrySet().forEach(System.out::println);
打印每个条目集产生
BAR=16.67%
DOO=16.67%
FOO=41.67%
BAZ=25.00%