以循环方式加入 java 中的列表

Join lists in java in round robin fashion

我需要在 java 中轮询多个 ArrayList。有什么简单的方法可以实现吗?

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

结果应该是:

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

如果你想创建一个一维数组填充来自一个锯齿状二维数组的列的数据,你可以使用两个嵌套流:首先按列,然后按行。如果您事先不知道列数,则可以迭代,直到列仍然至少出现在一行中。

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]

另请参阅:Efficient way to choose data from several Lists with round robin algorithm

tl;博士

循环列表的列表,循环最大大小。从每个列表中拉出第 n 个元素。当我们要求超出其大小的第 n 个元素时,较短的列表将抛出异常;忽略那个例外。

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 ) ;

这种方法可能会得到改进,方法是检查我们是否越过较短数组的末尾,而不是抛出异常。但在这种情况下,我认为这没有多大意义。

详情

定义我们的列表。

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]]

确定列表的最长长度。

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

longestLength.toString() = OptionalInt[3]

limit = 3

建立一个列表来记录我们的结果。

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

遍历每个列表,忽略较短列表中抛出的任何 IndexOutOfBoundsException

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.
        }
    }
}

看到这个 code run live at IdeOne.com

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

Return 这些数字的 unmodifiable list

return List.copyOf( results ) ;