当前位置: 首页 > 知识库问答 >
问题:

Java - Stream -每N个元素收集一次

康元凯
2023-03-14

我正在尝试学习java流。我能够进行简单的迭代/过滤/映射/收集等。

当我尝试收集每 3 个元素并打印时,如本例所示,[收集每 3 个元素并打印等等......]

    List<String> list = Arrays.asList("a","b","c","d","e","f","g","h","i","j");

    int count=0;
    String append="";
    for(String l: list){
        if(count>2){
            System.out.println(append);
            System.out.println("-------------------");
            append="";
            count=0;
        }
        append = append + l;
        count++;
    }
    System.out.println(append);

输出:

abc
-------------------
def
-------------------
ghi
-------------------
j

我没有得到任何线索,如何使用流做到这一点。我应该实现自己的收集器来实现这一点吗?

共有3个答案

袁晟
2023-03-14

您可以创建自己的收集器。最简单的方法是调用 Collector.of()。

由于您的用例需要按顺序处理值,因此这里有一个根本不支持并行处理的实现。

public static Collector<String, List<List<String>>, List<List<String>>> blockCollector(int blockSize) {
    return Collector.of(
            ArrayList<List<String>>::new,
            (list, value) -> {
                List<String> block = (list.isEmpty() ? null : list.get(list.size() - 1));
                if (block == null || block.size() == blockSize)
                    list.add(block = new ArrayList<>(blockSize));
                block.add(value);
            },
            (r1, r2) -> { throw new UnsupportedOperationException("Parallel processing not supported"); }
    );
}

试验

List<String> input = Arrays.asList("a","b","c","d","e","f","g","h","i","j");
List<List<String>> output = input.stream().collect(blockCollector(3));
output.forEach(System.out::println);

输出

[a, b, c]
[d, e, f]
[g, h, i]
[j]
封瑞
2023-03-14

如果您的项目中有 Guava,则可以使用 Iterables.partition 方法

import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
...

Stream<List<String>> stream = Streams.stream(Iterables.partition(list, 3));
司徒元明
2023-03-14

您实际上可以使用 IntStream 来模拟列表的分页。

List<String> list = Arrays.asList("a","b","c","d","e","f","g","h","i","j");

int pageSize = 3;

IntStream.range(0, (list.size() + pageSize - 1) / pageSize)
        .mapToObj(i -> list.subList(i * pageSize, Math.min(pageSize * (i + 1), list.size())))
        .forEach(System.out::println);

哪些输出:

[a, b, c]
[d, e, f]
[g, h, i]
[j]

如果您想要生成字符串,您可以使用< code>String.join,因为您处理的是< code >列表

.mapToObj(i -> String.join("", list.subList(i * pageSize, Math.min(pageSize * (i + 1), list.size()))))
 类似资料:
  • 我有一个名为计算的方法,它需要太长时间才能完成。所以我决定将我的信息列表对象部分发送到这个方法。我如何遍历每n个元素?

  • 问题内容: 例如,是否可以选择一组元素中的每个第四个元素? 例如:我有16个元素…我可以写类似的东西。 有一个更好的方法吗? 问题答案: 顾名思义,它允许您使用除常数以外的变量构造算术表达式。您可以执行加法(),减法()和系数乘法(其中是整数,包括正数,负数和零)。 这是重写上面的选择器列表的方法: 有关这些算术表达式如何工作的解释,请参见我对该问题的回答以及规范。 请注意,此答案假设同一父元素内

  • 我有一个这样的数字列表: 如何以优雅的方式总结每个N(让我们假设2)个元素并将列表转换为: 编辑:我想出了以下解决方案: 它是有效的,但我仍然在寻找一个更易读、更简单的方法。

  • 假设我有这样一个列表: 是否可以使用Java8流从该列表中每隔一秒获取一个元素以获得以下内容? 或者甚至每三个元素? 基本上,我正在寻找一个函数来获取流的每n个元素:

  • 这是一个算法问题。如果我错过了Python中任何有帮助的现有函数,请大喊一声。 给定一组元素的,我们可以在Python中使用函数来找到所有唯一的k元素子集。让我们调用包含所有这些子集的集合。请注意,每个这样的子集都有不同的元素。 问题是两步走。首先,给定这些k-不同元素子集,我想组合(其中的一些),这样(组合只是一些子集的超集): > 构图中任意两个子集之间的交集为空 构图中所有子集的并集给出的正

  • 给定一个数字字符串,我想在字符串中的每n位数应用一个操作。这可能与java流? 例如,对于字符串,并对每2个字符应用3的和,结果将是。 上面的结果是,因为总和应用于所有字符。