Java 8 partition list

后端 未结 5 2205
一个人的身影
一个人的身影 2021-02-18 15:37

Is it possible to partition a List in pure Jdk8 into equal chunks (sublists).

I know it is possible using Guava Lists class, but can we do it with pure Jdk? I don\'t wan

相关标签:
5条回答
  • 2021-02-18 15:50

    That can be done easily using the subList() method:

    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));
    }
    
    0 讨论(0)
  • 2021-02-18 15:51
    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();
    

    result:

    pairs =
     "103218982" -> "19855201547"
     "103278808" -> "263716791426"
     "103243034" -> "81667273413"
     "103426733" -> "27736529279"
     "103426540" -> "84528784843"
     "103427376" -> "27717278645"
     "103426000" -> "27718159078"
     "103343262" -> "6478342944"
    

    We need to group each 2 elements into key, value pairs, so will partion the list into chunks of 2, (counter.getAndIncrement() / 2) will result same number each 2 hits ex:

    IntStream.range(0,6).forEach((i)->System.out.println(counter.getAndIncrement()/2));
    prints:
    0
    0
    1
    1
    2
    2
    

    You may ajust chunk sizee to partition lists sizes.

    0 讨论(0)
  • 2021-02-18 16:04

    I have tried my own solution with a custom made Collector. I hope someone will find it useful, or help me improve it.

    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();
            }
        }
    
    0 讨论(0)
  • 2021-02-18 16:05

    Guava Lists class has a partition() method that does exactly this. See https://guava.dev/releases/21.0/api/docs/com/google/common/collect/Lists.html#partition-java.util.List-int-

    0 讨论(0)
  • 2021-02-18 16:10

    Try using this code, it uses 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;
    }
    
    0 讨论(0)
提交回复
热议问题