以以下列表为例:
List<String> input = List.of("FOO", "FOO", "FOO", "FOO", "FOO", "BAR", "BAR", "BAZ", "BAZ", "BAZ", "DOO", "DOO");
Run Code Online (Sandbox Code Playgroud)
我需要获取每个元素的相对频率并将其格式化为字符串。为此,我使用了两个步骤,首先创建频率图,然后计算相对百分比和格式:
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);
Run Code Online (Sandbox Code Playgroud)
并得到结果
{BAR=16.67%, DOO=16.67%, FOO=41.67%, BAZ=25.00%}
Run Code Online (Sandbox Code Playgroud)
我被告知要重构上述内容并使用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() ))
));
Run Code Online (Sandbox Code Playgroud) 我正在尝试做的事情的简化示例:
假设我有一个字符串列表,需要根据是否包含特定子字符串的条件将其分为 4 组。如果一个字符串包含Foo它应该属于该组FOO,如果它包含Bar它应该属于该组BAR,如果它包含两者它应该出现在两个组中。
List<String> strings = List.of("Foo", "FooBar", "FooBarBaz", "XXX");
Run Code Online (Sandbox Code Playgroud)
由于字符串被分组到第一个匹配组中,因此上述输入的简单方法无法按预期工作:
Map<String,List<String>> result1 =
strings.stream()
.collect(Collectors.groupingBy(
str -> str.contains("Foo") ? "FOO" :
str.contains("Bar") ? "BAR" :
str.contains("Baz") ? "BAZ" : "DEFAULT"));
Run Code Online (Sandbox Code Playgroud)
结果1是
{FOO=[Foo, FooBar, FooBarBaz], DEFAULT=[XXX]}
Run Code Online (Sandbox Code Playgroud)
期望的结果应该是
{FOO=[Foo, FooBar, FooBarBaz], BAR=[FooBar, FooBarBaz], BAZ=[FooBarBaz], DEFAULT=[XXX]}
Run Code Online (Sandbox Code Playgroud)
经过一段时间的搜索,我找到了另一种方法,它接近我想要的结果,但不太完全
Map<String,List<String>> result2 =
List.of("Foo", "Bar", "Baz", "Default").stream()
.flatMap(str -> strings.stream().filter(s -> s.contains(str)).map(s -> new String[]{str.toUpperCase(), s}))
.collect(Collectors.groupingBy(arr -> arr[0], Collectors.mapping(arr -> arr[1], Collectors.toList())));
System.out.println(result2);
Run Code Online (Sandbox Code Playgroud)
结果2是
{BAR=[FooBar, …Run Code Online (Sandbox Code Playgroud) 我有一个与此堆栈溢出问题类似的用例,并尝试使用它而不将结果存储在 a 中List<List<String>>,而是调用stream()它。
List<List<String>>如果由于类型不匹配而没有将其分配给我,则会出现奇怪的编译时错误。要重现该问题,只需注释掉输出的分配即可。
问题是为什么会出现这个编译错误呢?以及如何修复它?
public static void main(String args[]) {
List<String> input = Arrays.asList("RED", "RED", "BLUE", "BLUE", "BLUE", "BLUE", "RED", "RED");
List<List<String>> output = // if this line commented it doesn't compile
input.stream()
.collect(Collector.of(
ArrayList::new,
(accumulator, item) -> {
if (accumulator.isEmpty()) {
List<String> list = new ArrayList<>();
list.add(item);
accumulator.add(list);
} else {
List<String> last = accumulator.get(accumulator.size() - 1);
if (last.isEmpty() || last.get(0).equals(item)) {
last.add(item);
} else {
List<String> list = new ArrayList<>();
list.add(item); …Run Code Online (Sandbox Code Playgroud) 给定一个订单类,例如:
@ToString
@AllArgsConstructor
@Getter
static class Order {
long customerId;
LocalDate orderDate;
}
Run Code Online (Sandbox Code Playgroud)
和订单列表:
List<Order> orderList = List.of(new Order(1, LocalDate.of(2020,Month.APRIL,21)),
new Order(1, LocalDate.of(2021,Month.APRIL,21)),
new Order(1, LocalDate.of(2022,Month.APRIL,21)),
new Order(2, LocalDate.of(2020,Month.APRIL,21)),
new Order(2, LocalDate.of(2021,Month.APRIL,21)),
new Order(3, LocalDate.of(2020,Month.APRIL,21)),
new Order(3, LocalDate.of(2022,Month.APRIL,21)),
new Order(4, LocalDate.of(2020,Month.APRIL,21)));
Run Code Online (Sandbox Code Playgroud)
我需要获得一份清单,customerId其中列出了最后一次orderDate超过 6 个月的情况。所以对于上面的例子[2,4]。我的想法是首先按 分组customerId,第二个地图到最后orderDate,第三个过滤那些超过 6 个月的地图。我陷入了如何将最近的订单映射到单个订单的第二步orderDate
第一步
Map<Long, List<Order>> grouped =
orderList.stream()
.collect(Collectors.groupingBy(Order::getCustomerId));
Run Code Online (Sandbox Code Playgroud)
第二步(卡在这里如何更改上述内容以仅获取一项作为值)
Map<Long, Order> grouped =
orderList.stream()
.collect(Collectors.groupingBy(Order::getCustomerId, ???));
Run Code Online (Sandbox Code Playgroud)
甚至更好
Map<Long, LocalDate> grouped =
orderList.stream()
.collect(Collectors.groupingBy(Order::getCustomerId, …Run Code Online (Sandbox Code Playgroud) 如何从字符串列表中获取映射,其中索引是键,字符串是值?
如果我有这样一个清单
List<String> list = List.of("foo","bar","baz","doo");
Run Code Online (Sandbox Code Playgroud)
我想要得到一个Map<Integer,String>喜欢
{0=foo, 1=bar, 2=baz, 3=doo}
Run Code Online (Sandbox Code Playgroud)
当我执行以下操作时出现错误
static Map<Integer,String> mapToIndex(List<String> list) {
return IntStream.range(0, list.size())
.collect(Collectors.toMap(Function.identity(), i -> list.get(i)));
}
Run Code Online (Sandbox Code Playgroud)
错误
所需类型:int 提供:Object
当我将其转换为 int 或 Integer 时
static Map<Integer,String> mapToIndex(List<String> list) {
return IntStream.range(0, list.size())
.collect(Collectors.toMap(Function.identity(), i -> list.get((Integer) i)));
}
Run Code Online (Sandbox Code Playgroud)
我明白了
'java.util.stream.IntStream' 中的 'collect(java.util.function.Supplier, java.util.function.ObjIntConsumer, java.util.function.BiConsumer<R,R>)' 无法应用于 '(java .util.stream.Collector<java.lang.Object,capture<?>,java.util.Map<java.lang.Object,java.lang.String>>)'
我缺少什么?