0

I am working on a problem in which I performed many operations on an ArrayList<int[]>. However, the final result should be of type int[][]. Do you have any suggestions on how to achieve this? If you have a solution that involves streams that's good for me. Consider this example:


    public static int[][] findFarmland(int[][] land) {
        var result = new ArrayList<int[]>();
        /**
         * Here you find a code to find farm lands. 
         * @see LeetCode Problem : https://leetcode.com/problems/find-all-groups-of-farmland/ 
         */
        return //array based on the ArrayList result.
    }

2 Answers2

1

The fastest way I know is this:

arrayList.stream().toArray(int[][]::new);

A little use case:

public static void main(String... args) {
     ArrayList<int[]> list = new ArrayList<>();
     list.add(new int[]{1, 2, 3});
     list.add(new int[]{4, 5, 6});
     list.add(new int[]{7, 8, 9});
     
     int[][] array = list.stream().toArray(int[][]::new);
     
     System.out.println(array[1][2]);
 }
0009laH
  • 1,960
  • 13
  • 27
  • this is slower than just calling toArray, i have found someone that measured this: https://stackoverflow.com/questions/42012471/collection-toarray-vs-collection-stream-toarray – Ofek Sep 06 '21 at 00:59
  • @Ofek Nice :) In fact I use this command for its elegance, I never questioned myself about its performances – 0009laH Sep 06 '21 at 05:27
0

You don't need stream for that, just the function toArray:

ArrayList<int[]> list = new ArrayList<>();
//...
int[][] arr = list.toArray(new int[0][]);

The function toArray gets an array of E and return an array of E. (where E is the type of the list)

  • if the length of the input is smaller than list.size() it creates a new array with length list.size()
  • if the length of the input is bigger or equals to list.size(), it just fill it.

You can understand this with this psudo code:

public E[] toArray(E[] arr) {
    if (arr.length < size()) {
        T[] ret = new T[size()];
        for (int i = 0; i < size(); i++)
            ret[i] = get(i);
        return ret;
    } else {
        for (int i = 0; i < size(); i++)
            arr[i] = get(i);
        return arr;
    }
}
Ofek
  • 1,065
  • 6
  • 19
  • Hi @Ofek, Your answer is really interesting the way that I tried to solve this issue by myself includes the use of for loop... Your answer is clearly better than mine. But can you explain it further. I mean the 0 in new int[0][]. – Kotbi Abderrahmane Sep 05 '21 at 22:58
  • @KotbiAbderrahmane the function toArray gets an array. if the array is shorter than list.size(), it creates a new array and fill it. if its longer its write the elements into the array. i will edit the answear so it will be more clear. – Ofek Sep 06 '21 at 00:46
  • I would suggest doing `int[][] arr = list.toArray(int[][]::new)` Then one does not need to worry about the dimension. – WJS Sep 06 '21 at 14:18
  • @Ofek, thank you for your explanation. In fact, I took some time to learn more about this. One great article I came across was this one https://www.baeldung.com/java-collection-toarray-methods . As you said when toArray takes an argument that one will serve as an initial in-memory array. This last will not only be filled but also if its size wasn't sufficient a new array of the required length and the same type is allocated. – Kotbi Abderrahmane Sep 06 '21 at 14:18