1

I have an ArrayList which I need to convert into a 2D array. I need to achieve this using Java stream.

private static ArrayList<Integer> GLOBALLIST;
Integer[][] TwoDArray = new Integer[2][8];
GLOBALLIST = Lists.newArrayList(36,40,44,48,52,56,60,64,100,104,108, 112,116,120,124,128);
AtomicInteger counter = new AtomicInteger(0);
        TwoDArray = (Integer[][]) ((GLOBALLIST.stream()
                .collect(Collectors.groupingByConcurrent(it -> counter.getAndIncrement() / 8))
                .values()).toArray(new Integer[2][8]));

This is giving error stating ObjectList cannot be converted to Integer[][]

  • How did you declare `2DList` ?? – Rafael Palomino Jul 17 '18 at 16:45
  • updated the code to show that. – Arnav Sahay Jul 17 '18 at 16:46
  • can you show us simple example, what is the input and what is the expected output please! – Youcef LAIDANI Jul 17 '18 at 17:02
  • Why did you create `2DList` as a 2x8 array? Especially considering you have 28 values. So how do you expect the 28 values to become a 2D array? 1x28? 2x14? 4x7? Row-wise, column-wise, spiral, something else? – Andreas Jul 17 '18 at 17:13
  • 2
    `2DList` is not a valid variable name. Further, you are creating lots of obsolete arrays. – Holger Jul 17 '18 at 19:35
  • You should give a minimal, complete and verifiable (compiling) example, see [help Center](https://stackoverflow.com/help/mcve) how to ask. It might be missing some parts, it might be not working as expected - but at least you should show that you tried on your own – milbrandt Jul 17 '18 at 20:39
  • The GlobalList will have only 16 elements...have edited my question...also changed the name of the variable – Arnav Sahay Jul 18 '18 at 05:23

3 Answers3

1

When your starting point is an ArrayList, i.e. a List supporting random access, like

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,144,149,153,157,161,165,169,173,177));

you can simply use

Integer[][] array = IntStream.range(0, (list.size()+7)/8)
    .mapToObj(ix -> list.subList(ix*=8, Math.min(ix+8,list.size())).toArray(new Integer[0]))
    .toArray(Integer[][]::new);

System.out.println(Arrays.deepToString(array));
[[36, 40, 44, 48, 52, 56, 60, 64], [100, 104, 108, 112, 116, 120, 124, 128], [132, 136, 140, 144, 149, 153, 157, 161], [165, 169, 173, 177]]
Holger
  • 285,553
  • 42
  • 434
  • 765
0

If u use guava then one solution here:

ArrayList<Integer> GLOBALLIST;
    GLOBALLIST = Lists.newArrayList(36,40,44,48,52,56,60,64,100,104,108, 112,116,120,124,128,132,136,140,144,149,153,157,161,165,169,173,177);
    int[][] twoDList = Lists.partition(GLOBALLIST,8)
            .stream()
            .map(Ints::toArray)
            .map(a -> Arrays.copyOf(a, 8))
            .toArray(int[][]::new);

I used below guava dependency in gradle:
compile 'com.google.guava:guava:22.0'

GolamMazid Sajib
  • 8,698
  • 6
  • 21
  • 39
0

With a slight modification to the blockCollector in this answer, you can do it like this:

public static Integer[][] toArray2D(Collection<Integer> list, int blockSize) {
    return list.stream()
               .collect(blockCollector(blockSize))
               .stream()
               .map(sublist -> sublist.toArray(new Integer[sublist.size()]))
               .toArray(length -> new Integer[length][]);
}
public static <T> Collector<T, List<List<T>>, List<List<T>>> blockCollector(int blockSize) {
    return Collector.of(
            ArrayList<List<T>>::new,
            (list, value) -> {
                List<T> block = (list.isEmpty() ? null : list.get(list.size() - 1));
                if (block == null || block.size() == blockSize)
                    list.add(block = new ArrayList<>(blockSize));
                block.add(value);
            },
            (r1, r2) -> { throw new UnsupportedOperationException("Parallel processing not supported"); }
    );
}

Test

List<Integer> list = Arrays.asList(36,40,44,48,52,56,60,64,100,104,108, 112,116,120,124,128,132,136,140,144,149,153,157,161,165,169,173,177);
Integer[][] r = toArray2D(list, 8);
System.out.println(Arrays.deepToString(r));

Output

[[36, 40, 44, 48, 52, 56, 60, 64], [100, 104, 108, 112, 116, 120, 124, 128], [132, 136, 140, 144, 149, 153, 157, 161], [165, 169, 173, 177]]
Andreas
  • 154,647
  • 11
  • 152
  • 247