Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8分区列表_Java_Java 8_Partitioning - Fatal编程技术网

Java8分区列表

Java8分区列表,java,java-8,partitioning,Java,Java 8,Partitioning,是否可以将纯Jdk8中的列表划分为相等的块(子列表) 我知道使用Guava类是可能的,但是我们可以用纯Jdk吗?我不想为我的项目添加新的JAR,只是为了一个用例 溶液: 迄今为止最好的解决方案是: 我也发现了,但它们仅适用于少数情况: 1.Collectors.partitioningBy()将列表拆分为2个子列表–如下所示: intList.stream().collect(Collectors.partitioningBy(s -> s > 6)); List<Li

是否可以将纯Jdk8中的列表划分为相等的块(子列表)

我知道使用Guava类是可能的,但是我们可以用纯Jdk吗?我不想为我的项目添加新的JAR,只是为了一个用例

溶液

迄今为止最好的解决方案是:

我也发现了,但它们仅适用于少数情况:

1.Collectors.partitioningBy()将列表拆分为2个子列表–如下所示:

intList.stream().collect(Collectors.partitioningBy(s -> s > 6));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
intList.stream().collect(收集器.partitionby(s->s>6));
列表子集=新的ArrayList(groups.values());
2.Collectors.groupingBy()将列表拆分为多个分区:

 Map<Integer, List<Integer>> groups = 
      intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
映射组=
intList.stream().collect(收集器.groupingBy(s->(s-1)/3));
列表子集=新的ArrayList(groups.values());
3.按分隔符拆分:

List<Integer> intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8);

    int[] indexes = 
      Stream.of(IntStream.of(-1), IntStream.range(0, intList.size())
      .filter(i -> intList.get(i) == 0), IntStream.of(intList.size()))
      .flatMapToInt(s -> s).toArray();
    List<List<Integer>> subSets = 
      IntStream.range(0, indexes.length - 1)
               .mapToObj(i -> intList.subList(indexes[i] + 1, indexes[i + 1]))
               .collect(Collectors.toList());
List intList=Lists.newArrayList(1,2,3,0,4,5,6,0,7,8);
int[]索引=
Stream.of(IntStream.of(-1),IntStream.range(0,intList.size())
.filter(i->intList.get(i)==0),IntStream.of(intList.size())
.flatMapToInt(s->s).toArray();
列表子集=
IntStream.range(0,index.length-1)
.mapToObj(i->intList.subList(索引[i]+1,索引[i+1]))
.collect(Collectors.toList());
4.使用流+计数器:

final List number=Arrays.asList(1,2,3,4,5,6,7);
最终int chunkSize=3;
最终AtomicInteger计数器=新的AtomicInteger();
最终收集结果=numbers.stream()
.collect(Collectors.groupingBy(it->counter.getAndIncrement()/chunkSize))
.values();

使用
子列表()
方法可以轻松完成:

List<String> collection = new ArrayList<>(21);
// fill collection
int chunkSize = 10;
List<List<String>> lists = new ArrayList<>();
for (int i = 0; i < collection.size(); i += chunkSize) {
    int end = Math.min(collection.size(), i + chunkSize);
    lists.add(collection.subList(i, end));
}
列表集合=新的ArrayList(21);
//填充集合
int chunkSize=10;
List lists=新建ArrayList();
for(int i=0;i
尝试使用此代码,它使用Java 8:

public static Collection<List<Integer>> splitListBySize(List<Integer> intList, int size) {

    if (!intList.isEmpty() && size > 0) {
        final AtomicInteger counter = new AtomicInteger(0);
        return intList.stream().collect(Collectors.groupingBy(it -> counter.getAndIncrement() / size)).values();
    }
    return null;
}
publicstaticcollection splitListBySize(List intList,int size){
如果(!intList.isEmpty()&&size>0){
最终AtomicInteger计数器=新的AtomicInteger(0);
返回intList.stream().collect(Collectors.groupingBy(it->counter.getAndIncrement()/size)).values();
}
返回null;
}

我用一个定制的收集器尝试了自己的解决方案。我希望有人会觉得它有用,或者帮助我改进它

class PartitioningCollector<T> implements Collector<T, List<List<T>>, List<List<T>>> {

        private final int batchSize;
        private final List<T> batch;

        public PartitioningCollector(int batchSize) {
            this.batchSize = batchSize;
            this.batch = new ArrayList<>(batchSize);
        }

        @Override
        public Supplier<List<List<T>>> supplier() {
            return LinkedList::new;
        }

        @Override
        public BiConsumer<List<List<T>>, T> accumulator() {
            return (total, element) -> {
                batch.add(element);
                if (batch.size() >= batchSize) {
                    total.add(new ArrayList<>(batch));
                    batch.clear();
                }
            };
        }

        @Override
        public BinaryOperator<List<List<T>>> combiner() {
            return (left, right) -> {
                List<List<T>> result = new ArrayList<>();
                result.addAll(left);
                result.addAll(left);
                return result;
            };
        }

        @Override
        public Function<List<List<T>>, List<List<T>>> finisher() {
            return result -> {
                if (!batch.isEmpty()) {
                    result.add(new ArrayList<>(batch));
                    batch.clear();
                }
                return result;
            };
        }

        @Override
        public Set<Characteristics> characteristics() {
            return emptySet();
        }
    }
类分区收集器实现收集器{
私有最终整数批量大小;
私人最终名单批次;
公共分区收集器(int batchSize){
this.batchSize=batchSize;
this.batch=新的ArrayList(batchSize);
}
@凌驾
公共供应商(){
返回LinkedList::新建;
}
@凌驾
公共双消费者累加器(){
返回值(总计,元素)->{
批量添加(元素);
if(batch.size()>=batchSize){
总计。添加(新阵列列表(批次));
batch.clear();
}
};
}
@凌驾
公共二进制运算符组合器(){
返回(左、右)->{
列表结果=新建ArrayList();
结果:addAll(左);
结果:addAll(左);
返回结果;
};
}
@凌驾
公共函数完成器(){
返回结果->{
如果(!batch.isEmpty()){
结果.添加(新ArrayList(批次));
batch.clear();
}
返回结果;
};
}
@凌驾
公共集特征(){
返回emptySet();
}
}
我们需要将每2个元素分组为键和值对,因此将列表分成2个块,(counter.getAndIncrement()/2)每2次点击的结果相同,例如:

您可以根据分区列表大小调整块大小


Guava Lists类有一个partition()方法,正好可以做到这一点。请参见

您可以查看Guava源代码并相应地执行它…?用普通java编写函数不是问题,但JDK8在流式处理和集合操作方面有一些很棒的特性,我认为它比编写自己的代码要快。但这只是我的假设。我将其标记为可能重复,因为Java-8解决方案也在那里可用。是的,我看到了这个问题,但我错过了Jdk8解决方案,谢谢:)还讨论了这个问题的要点,即操作系统不使用任何外部LIB。您好,欢迎来到StackOverflow。请在回答之前先阅读问题。它说他想使用纯Jdk8。这就是,没有像番石榴这样的图书馆。
class PartitioningCollector<T> implements Collector<T, List<List<T>>, List<List<T>>> {

        private final int batchSize;
        private final List<T> batch;

        public PartitioningCollector(int batchSize) {
            this.batchSize = batchSize;
            this.batch = new ArrayList<>(batchSize);
        }

        @Override
        public Supplier<List<List<T>>> supplier() {
            return LinkedList::new;
        }

        @Override
        public BiConsumer<List<List<T>>, T> accumulator() {
            return (total, element) -> {
                batch.add(element);
                if (batch.size() >= batchSize) {
                    total.add(new ArrayList<>(batch));
                    batch.clear();
                }
            };
        }

        @Override
        public BinaryOperator<List<List<T>>> combiner() {
            return (left, right) -> {
                List<List<T>> result = new ArrayList<>();
                result.addAll(left);
                result.addAll(left);
                return result;
            };
        }

        @Override
        public Function<List<List<T>>, List<List<T>>> finisher() {
            return result -> {
                if (!batch.isEmpty()) {
                    result.add(new ArrayList<>(batch));
                    batch.clear();
                }
                return result;
            };
        }

        @Override
        public Set<Characteristics> characteristics() {
            return emptySet();
        }
    }
private final String dataSheet = "103343262,6478342944, 103426540,84528784843, 103278808,263716791426, 103426733,27736529279, 
103426000,27718159078, 103218982,19855201547, 103427376,27717278645, 
103243034,81667273413";

    final int chunk = 2;
    AtomicInteger counter = new AtomicInteger();
    Collection<List<String>> chuncks= Arrays.stream(dataSheet.split(","))
            .map(String::trim)
            .collect(Collectors.groupingBy(i->counter.getAndIncrement()/chunk))
            .values();
pairs =
 "103218982" -> "19855201547"
 "103278808" -> "263716791426"
 "103243034" -> "81667273413"
 "103426733" -> "27736529279"
 "103426540" -> "84528784843"
 "103427376" -> "27717278645"
 "103426000" -> "27718159078"
 "103343262" -> "6478342944"
IntStream.range(0,6).forEach((i)->System.out.println(counter.getAndIncrement()/2));
prints:
0
0
1
1
2
2