如何通过在java lambda表达式的列表中的每个第3个元素之后添加新行来打印列表?

时间:2017-09-02 09:29:46

标签: java arraylist lambda java-8

假设我有一个列表如下

Collection<?> mainList = new ArrayList<String>();
mainList=//some method call//

目前,我正在将列表中的元素显示为

System.out.println(mainList.stream().map(Object::toString).collect(Collectors.joining(",")).toString());

我得到了结果

a,b,c,d,e,f,g,h,i

如何通过在java中的列表中的每个第3个元素之后添加新行来打印此列表,以便它将打印结果如下

a,b,c
d,e,f
g,h,i

注意:这类似于 How to Add newline after every 3rd element in arraylist in java? 。但是在阅读时自己完成格式化文件。 我想在打印输出时这样做。

3 个答案:

答案 0 :(得分:5)

如果您想坚持使用Java Stream API,那么可以通过将初始列表分区为大小为3的子列表,然后将每个子列表表示为字符串并将结果与​​\n结合来解决您的问题。

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

final class PartitionListExample {

    public static void main(String[] args) {

        final Collection<String> mainList = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i");
        final AtomicInteger idx = new AtomicInteger(0);
        final int size = 3;

        // Partition a list into list of lists size 3
        final Collection<List<String>> rows = mainList.stream()
                .collect(Collectors.groupingBy(
                        it -> idx.getAndIncrement() / size
                ))
                .values();

        // Write each row in the new line as a string
        final String result = rows.stream()
                .map(row -> String.join(",", row))
                .collect(Collectors.joining("\n"));

        System.out.println(result);
    }
}

有第三方库提供实用程序类,使列表分区更容易(例如GuavaApache Commons Collections),但此解决方案仅基于Java 8 SDK构建。

它的作用是:

  • 首先,我们通过按指定的行索引进行分组来收集所有元素,然后将值存储为列表(例如{0=[a,b,c],1=[d,e,f],2=[g,h,i]}
  • 然后我们会列出所有值,例如[[a,b,c],[d,e,f],[g,h,i]]
  • 最后我们将列表列表表示为一个字符串,其中每一行用\n
  • 分隔

输出 Demo

运行以下程序将在输出后打印到控制台:

a,b,c
d,e,f
g,h,i

从以下示例

获取更多信息

Alnitak通过以下示例发挥了更多作用,并通过利用Collectors.joining(",")收集器中的.groupingBy并最终使用String.join("\n", rows)而不是触发另一个流来提出更短的解决方案减少。

        final Collection<String> rows = mainList.stream()
                .collect(Collectors.groupingBy(
                        it -> idx.getAndIncrement() / size,
                        Collectors.joining(",")
                ))
                .values();

        // Write each row in the new line as a string
        final String result = String.join("\n", rows);

        System.out.println(result);
    }

最后的注释

请注意,这不是以所需格式打印元素列表的最有效方法。但是,如果要创建最终结果并且非常容易阅读和理解,那么任何元素的分区列表都会为您提供灵活性。

答案 1 :(得分:2)

附注:在您的实际代码中,如果您替换

,则可以删除map(Object::toString)

Collection<?> mainList = new ArrayList<String>();

Collection<String> mainList = new ArrayList<String>();

如果您操纵String,请创建Collection String而不是Collection ?

  

但是在阅读本身的同时格式化文件。我想   在打印输出时执行此操作。

获得连接的字符串后,使用replaceAll("(\\w*,\\w*,\\w*,)", "$1" + System.lineSeparator())应该完成这项工作 Iit将搜索并替换由,字符分隔的所有3个字符或更多字符的系列($ 1-&gt; group capture),但是将其与行分隔符连接。

除此之外:

String collect = mainList.stream().collect(Collectors.joining(","));    

可以简化为:

String collect = String.join(",", mainList);    

示例代码:

public static void main(String[] args) {
  Collection<String> mainList = Arrays.asList("a","b","c","d","e","f","g","h","i", "j");
  String formattedValues = String.join(",", mainList).replaceAll("(\\w*,\\w*,\\w*,)", "$1" + System.lineSeparator());
  System.out.println(formattedValues);
}

输出:

  

A,B,C,

     

d,E,F,

     

G,H,I,

     

Ĵ

答案 2 :(得分:1)

此处尚未解答的另一种方法是创建自定义game_board[:, x, y]

Collector

说明

这是一个不可并行使用的可变收集器。如果您的必需品要求您并行处理流,则必须将此收集器转换为线程安全,如果您不关心元素的顺序,这很容易。

组合器抛出异常,因为它从不被调用,因为顺序运行流。

import java.util.*; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; import java.util.stream.Collectors; public class PartitionListInPlace { static class MyCollector implements Collector<String, List<List<String>>, String> { private final List<List<String>> buckets; private final int bucketSize; public MyCollector(int numberOfBuckets, int bucketSize) { this.bucketSize = bucketSize; this.buckets = new ArrayList<>(numberOfBuckets); for (int i = 0; i < numberOfBuckets; i++) { buckets.add(new ArrayList<>(bucketSize)); } } @Override public Supplier<List<List<String>>> supplier() { return () -> this.buckets; } @Override public BiConsumer<List<List<String>>, String> accumulator() { return (buckets, element) -> buckets .stream() .filter(x -> x.size() < bucketSize) .findFirst() .orElseGet(() -> { ArrayList<String> nextBucket = new ArrayList<>(bucketSize); buckets.add(nextBucket); return nextBucket; }) .add(element); } @Override public BinaryOperator<List<List<String>>> combiner() { return (b1, b2) -> { throw new UnsupportedOperationException(); }; } @Override public Function<List<List<String>>, String> finisher() { return buckets -> buckets.stream() .map(x -> x.stream() .collect(Collectors.joining(", "))) .collect(Collectors.joining(System.lineSeparator())); } @Override public Set<Characteristics> characteristics() { return new HashSet<>(); } } public static void main(String[] args) { Collection<String> mainList = Arrays.asList("a","b","c","d","e","f","g","h","i", "j"); String formattedValues = mainList .stream() .collect(new MyCollector(mainList.size() / 3, 3)); System.out.println(formattedValues); } } 这一组没有我们感兴趣的内容,您可以通过阅读javadoc

来验证这一点

Characteristics方法将获取我们要插入元素的存储区。该元素将插入到具有空格的下一个存储桶中,否则我们将创建一个新存储桶并将其添加到那里。

supplier非常简单:按finisher加入每个广告素材的内容,然后将广告加入广告资源,

记住

请勿使用此收集器进行处理

输出

System.lineSeparator()