0

I need to round robin multiple ArrayLists in java. Is there any simple way to achieve it?

lists = [1,2,3], [4,5], [6,7,8]

Result should be:

[1,4,6,2,5,7,3,8]
Tyr1on
  • 1,999
  • 2
  • 13
  • 20

2 Answers2

1

tl;dr

Loop the list of lists, looping for the maximum size. Pull the nth element from each list. The shorter lists will throw an exception when we ask for the nth element beyond their size; just ignore that exception.

List < List < Integer > > listOfLists =
        List.of(
                List.of( 1 , 2 , 3 ) ,
                List.of( 4 , 5 ) ,
                List.of( 6 , 7 , 8 )
        );
OptionalInt longestLength = listOfLists.stream().mapToInt( List :: size ).max();
int limit = longestLength.orElse( 0 );

int initialCapacity = listOfLists.stream().mapToInt( List :: size ).sum();
List < Integer > results = new ArrayList <>( initialCapacity );

for ( int i = 0 ; i < limit ; i++ )
{
    for ( List < Integer > listOfIntegers : listOfLists )
    {
        try
        {
            Integer integer = listOfIntegers.get( i );
            results.add( integer );
        }
        catch ( IndexOutOfBoundsException e )
        {
            // Do nothing. Swallow exception. We expect to fall out of bounds on shorter lists.
        }
    }
}
return List.copyOf( results ) ;

This approach might be improved by checking to see if we went past the end of the shorter arrays, rather than throwing an exception. But in this case I do not see much point in that.

Details

Define our lists.

List < List < Integer > > listOfLists =
        List.of(
                List.of( 1 , 2 , 3 ) ,
                List.of( 4 , 5 ) ,
                List.of( 6 , 7 , 8 )
        );

listOfLists.toString() = [[1, 2, 3], [4, 5], [6, 7, 8]]

Determine the longest length of the lists.

OptionalInt longestLength = listOfLists.stream().mapToInt( List :: size ).max();
int limit = longestLength.orElse( 0 ); 

longestLength.toString() = OptionalInt[3]

limit = 3

Build a list to capture our results.

int initialCapacity = listOfLists.stream().mapToInt( List :: size ).sum();
List < Integer > results = new ArrayList <>( initialCapacity );

Loop through each list, ignoring any IndexOutOfBoundsException thrown on the shorter lists.

for ( int i = 0 ; i < limit ; i++ )
{
    for ( List < Integer > listOfIntegers : listOfLists )
    {
        try
        {
            Integer integer = listOfIntegers.get( i );
            results.add( integer );
        }
        catch ( IndexOutOfBoundsException e )
        {
            // Do nothing. Swallow exception. We expect to fall out of bounds on shorter lists.
        }
    }
}

See this code run live at IdeOne.com.

results = [1, 4, 6, 2, 5, 7, 3, 8]

Return an unmodifiable list of those numbers.

return List.copyOf( results ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

If you want to create a 1d array filled with data from the columns of a jagged 2d array, you can use two nested streams: first by columns, and then by rows. If you don't know the number of columns beforehand, then you can iterate until the columns are still present at least in one row.

int[][] arr2 = {{1, 2, 3}, {4, 5}, {6, 7, 8}};

int[] arr1 = IntStream
        // iterate over the columns of a 2d array
        .iterate(0, i -> i + 1)
        // take an array of values from each column Stream<int[]>
        .mapToObj(i -> Arrays
                // iterate over the array rows
                .stream(arr2)
                // filter those rows where this column is present
                .filter(row -> row.length > i)
                // take value from the column
                .mapToInt(row -> row[i])
                // return an array
                .toArray())
        // until the columns are still present
        .takeWhile(arr -> arr.length > 0)
        // flatten to a single stream
        .flatMapToInt(Arrays::stream)
        // return an array
        .toArray();

// output
System.out.print(Arrays.toString(arr1)); // [1, 4, 6, 2, 5, 7, 3, 8]

See also: Efficient way to choose data from several Lists with round robin algorithm