使用 Stream API 对列表中的项目进行分组

问题描述 投票:0回答:2

我正在尝试使用 Stream 对列表中的项目进行分组。

public static void main(String[] args) {
        List<String> l = Arrays.asList("A", "C", "B", "A", "B");

        Map<String, List<String>> b = l.stream().collect(Collectors.groupingBy(Function.identity()));
        System.out.println(b.toString());
    }

这将返回

{A=[A, A], B=[B, B], C=[C]}

但是,我怎样才能获得每个元素的索引。 类似这样的,

{A=[(A,0), (A,3)], B=[(B,2), (B,4)], C=[(C,1)]}

java java-stream grouping collectors
2个回答
0
投票

您可以将

groupingBy
List::get(int index)
一起使用,如下所示:

Map<String, List<Integer>> result = IntStream.range(0, l.size())
        .boxed()
        .collect(Collectors.groupingBy(l::get));

输出

{A=[0, 3], B=[2, 4], C=[1]}

如您所见,响应与您的预期略有不同。我认为显示

(B,2)
是多余的。


编辑

由于OP坚持显示相同的输出,我建议创建一个包含字母和索引的自定义对象,如下所示:

@AllArgsConstructor
class MyOutput{
    private String letter;
    private Integer index;

    @Override
    public String toString() {
        return "(" + letter + "," + index + ')';
    }
}

您的信息流应如下所示:

Map<String, List<MyOutput>> response = IntStream.range(0, l.size())
        .boxed()
        .collect(groupingBy(l::get, mapping(i -> new MyOutput(l.get(i), i), toList())));

输出

{A=[(A,0), (A,3)], B=[(B,2), (B,4)], C=[(C,1)]}

0
投票

这是如何做你想做的事。

  • 首先,声明一条记录来保存数据。
  • 然后传输信息并创建该记录的实例。
  • 然后使用 groupingBy 将其分组到地图中。
record Pair(String letter, int index) {
    @Override
    public String toString() {
        return "(%s, %d)".formatted(letter, index);
    }
}


List<String> l = Arrays.asList("A", "C", "B", "A", "B");



Map<String, List<Pair>> result = IntStream.range(0, l.size())
        .mapToObj(i -> new Pair(l.get(i), i))
        .collect(Collectors.groupingBy(Pair::letter));

result.entrySet().forEach(System.out::println);

打印

A=[(A, 0), (A, 3)]
B=[(B, 2), (B, 4)]
C=[(C, 1)]
© www.soinside.com 2019 - 2024. All rights reserved.