在java lambda表达式中,如何通过在列表的每三个元素后添加新行来打印列表?
假设我有一个如下的列表在java lambda表达式中,如何通过在列表的每三个元素后添加新行来打印列表?,java,arraylist,lambda,java-8,Java,Arraylist,Lambda,Java 8,假设我有一个如下的列表 Collection<?> mainList = new ArrayList<String>(); mainList=//some method call// a,b,c d,e,f g,h,i 我得到的结果是 a,b,c,d,e,f,g,h,i 在java中,如何通过在列表中的每三个元素后添加新行来打印此列表,以便打印结果如下 Collection<?> mainList = new ArrayList<String>
Collection<?> mainList = new ArrayList<String>();
mainList=//some method call//
a,b,c
d,e,f
g,h,i
我得到的结果是
a,b,c,d,e,f,g,h,i
在java中,如何通过在列表中的每三个元素后添加新行来打印此列表,以便打印结果如下
Collection<?> mainList = new ArrayList<String>();
mainList=//some method call//
a,b,c
d,e,f
g,h,i
注意:这类似于。但是,在读取文件本身时会对文件进行格式化。
我想在打印输出时执行此操作。旁注:在实际代码中,如果替换
Collection mainList=new ArrayList()代码>按
Collection mainList=new ArrayList()代码>
如果操纵字符串
s,则创建字符串
的集合
,而不是的集合
?
但是文件的格式化是在读取自身时完成的。我想
在打印输出时执行此操作
获取连接的字符串后,应使用replaceAll(“(\\w*,\\w*,\\w*,)”,“$1”+System.lineSeparator())
执行此操作。
Iit将搜索并替换所有由分隔的3个或更多字符组成的序列,
字符由相同的内容($1->组捕获)替换,但将其与行分隔符连接。
除此之外:
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);
}
publicstaticvoidmain(字符串[]args){
集合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(格式化值);
}
输出:
a、 b,c,
d、 e,f
g、 h,我,
j
如果您想坚持使用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);
}
}
从下面的示例中获得更多信息
通过使用收集器,在中加入(“,”
)。groupingBy
收集器,并在最后使用字符串。加入(“\n”,行)
,而不是触发另一个流缩减,从而得出了一个更短的解决方案
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);
}
final Collection rows=mainList.stream()
.collect(收集器.groupingBy(
它->idx.getAndIncrement()/size,
收集者。加入(“,”)
))
.values();
//将新行中的每一行作为字符串写入
最终字符串结果=String.join(“\n”,行);
系统输出打印项次(结果);
}
最后说明
请记住,这不是以所需格式打印元素列表的最有效方法。但是,如果要创建最终结果,任何元素的分区列表都为您提供了灵活性,并且非常容易阅读和理解。另一种方法是创建自定义的收集器
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);
}
}
在我看来,你的问题比结果更重要。这里真正的问题是:如何以X为单位获取流中的元素?在收集器
中没有找到这样的东西,这让我非常惊讶。您可能可以创建自己的收集器,生成列表作为输出。@T.J.Crowder显然Guava和Apache Commons中有一些类可以这样做-@T.J.Crowder收集器。groupingBy(谓词)。values()
可以将列表划分为子列表。我已经建立了我的答案。@SzymonStepniak:啊,我应该想到把计数器放在一个这样的容器里。我不得不怀疑,.collect
是一个终端操作,而你显然只在这个专栏创建任务中使用它们,为什么还要为使用流的开销而烦恼呢?在输出上使用字符串处理看起来像是对meThereplaceAll
的恶意攻击。如果您至少能详细说明用法,那就太好了。详细说明我的评论-正则表达式是内容敏感的,如果单个元素不再匹配,则需要修改,从而使此代码变得脆弱。虽然可能需要更多的代码,但应首先使用结构化数据将元素分组为三组,而不是作为后处理步骤。@Alnitak,我的答案基于op要求。我们还可以用\w*
替换\w
。根据设计原因,代码是脆弱的。如果不需要,为什么还要增加复杂性呢?@Downvoter我可以理解,这种解决问题的方法可能不是每个人都选择的,但它是正确的,而且是有效的。请阅读它:“每当你遇到一篇非常草率、不费力气的帖子,或者一个明显而且可能是危险的错误答案时,请使用你的反对票。”JOOI(我不是流方面的专家)为什么不使用rows=list.stream().collect(Collectors.groupingBy(s->idx.getAndIncrement()/3))
-我看不到AbstractMap
和SimpleEntry
操作添加了什么。我已经试过了,它显然对我有效,但可能有副作用或我不知道的问题。@Alnitak很好,谢谢!它没有任何副作用,但由于创建了中间的不可变项,所以更加冗长。正如您所观察到的,可以通过直接调用.groupingBy(s->idx.getAndIncrement()/size)
来简化它。谢谢你的意见!不客气-还有对Collectors.toList()
的新调用是什么?我觉得在我的实验中没有必要-。groupingBy
已经返回了一个`Map@Alnitak它也可以避免,因为。groupingBy()
在未指定下游时使用它。再次感谢!:)为了获得更多乐趣,请使用收集器。加入(“,”
作为中的下游功能
a, b, c
d, e, f
g, h, i
j