java8 拆分list,将列表拆分为多个列表,在java 8中具有固定数量的元素

I want to something which is similar to the scala grouped function. Basically, pick 2 elements at a time and process them. Here is a reference for the same :

Lambdas do provide things like groupingBy and partitioningBy but none of them seem to do the same as the grouped function in Scala. Any pointers would be appreciated.

解决方案

It sounds like a problem that is better handled like a low-level Stream operation just like the ops provided by the Stream API itself. A (relative) simple solution may look like:

public static Stream> chunked(Stream s, int chunkSize) {

if(chunkSize<1) throw new IllegalArgumentException("chunkSize=="+chunkSize);

if(chunkSize==1) return s.map(Collections::singletonList);

Spliterator src=s.spliterator();

long size=src.estimateSize();

if(size!=Long.MAX_VALUE) size=(size+chunkSize-1)/chunkSize;

int ch=src.characteristics();

ch&=Spliterator.SIZED|Spliterator.ORDERED|Spliterator.DISTINCT|Spliterator.IMMUTABLE;

ch|=Spliterator.NONNULL;

return StreamSupport.stream(new Spliterators.AbstractSpliterator>(size, ch)

{

private List current;

@Override

public boolean tryAdvance(Consumer super List> action) {

if(current==null) current=new ArrayList<>(chunkSize);

while(current.size()

if(!current.isEmpty()) {

action.accept(current);

current=null;

return true;

}

return false;

}

}, s.isParallel());

}

Simple test:

chunked(Stream.of(1, 2, 3, 4, 5, 6, 7), 3)

.parallel().forEachOrdered(System.out::println);

The advantage is that you do not need a full collection of all items for subsequent stream processing, e.g.

chunked(

IntStream.range(0, 1000).mapToObj(i -> {

System.out.println("processing item "+i);

return i;

}), 2).anyMatch(list->list.toString().equals("[6, 7]")));

will print:

processing item 0

processing item 1

processing item 2

processing item 3

processing item 4

processing item 5

processing item 6

processing item 7

true

rather than processing a thousand items of IntStream.range(0, 1000). This also enables using infinite source Streams:

chunked(Stream.iterate(0, i->i+1), 2).anyMatch(list->list.toString().equals("[6, 7]")));

If you are interested in a fully materialized collection rather than applying subsequent Stream operations, you may simply use the following operation:

List list=Arrays.asList(1, 2, 3, 4, 5, 6, 7);

int listSize=list.size(), chunkSize=2;

List> list2=

IntStream.range(0, (listSize-1)/chunkSize+1)

.mapToObj(i->list.subList(i*=chunkSize,

listSize-chunkSize>=i? i+chunkSize: listSize))

.collect(Collectors.toList());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值