当我们必须转换一维数组List类型时,我们可以简单地使用Arrays.asList()
。但是在多维数组的背景下,我没有找到任何类似的东西。我必须手动创建一个List<List<T>>
并按照原始多维数组填充值。
有什么体面的方法可以在这些类型之间进行转换? Java 8方式?
答案 0 :(得分:4)
您可以使用Arrays.stream
并映射内部数组:
<T> List<List<T>> toNestedList(T[][] array) {
return Arrays.stream(array)
.map(Arrays::asList)
.collect(Collectors.toList());
}
这将创建一个内部数组流,将它们映射到列表并将所有内部列表收集到一个外部列表。
答案 1 :(得分:1)
当前提出的解决方案将创建一个新列表。这意味着必须遍历数组并必须分配内存。
类似于Arrays#asList
,最好不要在给定数组上创建一个 new 列表,而只创建一个 view 。这样,即使数组包含1000000个元素,创建此列表视图的内存和性能开销实际上也是 zero 。
如何实现此示例:
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.RandomAccess;
public class NestedAsList
{
public static void main(String[] args)
{
String array[][] =
{
{ "This", "is", "an" },
{ "example", "of", }, null,
{ "a", "jagged", "array" }
};
List<List<String>> lists = asLists(array);
lists.forEach(System.out::println);
}
/**
* Returns a <i>view</i> on the given array, as a list where each element is
* a <i>view</i> on the respective array element. When the array contains
* <code>null</code> elements, then the list will contain an empty list at
* this index.
*
* @param array The array
* @return The list view
*/
private static <T> List<List<T>> asLists(T array[][])
{
Objects.requireNonNull(array);
class ResultList extends AbstractList<List<T>> implements RandomAccess
{
@Override
public List<T> get(int index)
{
T[] a = array[index];
if (a == null)
{
// Could return null or the empty list here...
return Collections.emptyList();
}
return Arrays.asList(a);
}
@Override
public int size()
{
return array.length;
}
}
return new ResultList();
}
}
(顺便说一句:我想知道您从哪里获得多维通用数组。如今这应该很少见了……)
注意:答案已基于comment by Holger更新:让返回的列表也实现java.util.RandomAccess
接口以表明答案是有益的具有固定时间索引访问。 Collections
类中的许多静态实用程序方法都会检查给定列表是否为RandomAccess
,并且在这种情况下能够更有效地执行其任务。
不幸的是,为了实现附加接口,必须创建一个新的本地类,但是这取决于结果类的使用方式,这可能是值得的。
asLists
方法的原始实现是此方法,它只是返回了一个新的AbstractList
, not 实现了RandomAccess
接口:
private static <T> List<List<T>> asLists(T array[][])
{
Objects.requireNonNull(array);
return new AbstractList<List<T>>()
{
@Override
public List<T> get(int index)
{
T[] a = array[index];
if (a == null)
{
// Could return null or the empty list here...
return Collections.emptyList();
}
return Arrays.asList(a);
}
@Override
public int size()
{
return array.length;
}
};
}
答案 2 :(得分:0)
以上解决方案是正确的,但不能处理2D数组中的空行,因此我在下面的解决方案中使用Java 8中的stream APIs
,它也适用于空行和通用数组。
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class TwoDArrayToListOfList {
public static void main(String[] args) {
String [][] stringArray = new String[][]{{"John", "Alley", "Neon"}, {null}, {"Huston", "Gary"}, {"Ellen", "James", "Chris", "Jacob"}};
List<List<String>> stringList = getListFrom2DArray(stringArray);
stringList.forEach(list -> list.forEach(System.out::println));
Integer [][] intArray = new Integer[][]{{1,3, 6}, {2, 4}, {null}, {6, 4, 3, 5}, {null}};
List<List<Integer>> intList = getListFrom2DArray(intArray);
intList.forEach(list -> list.forEach(System.out::println));
Double [][] doubleArray = new Double[][]{{1.0,3.9, 6.7}, {2.4, 4.4}, {6.5, 4.1, 3.3, 5.2}, {null}};
List<List<Double>> doubleList = getListFrom2DArray(doubleArray);
doubleList.forEach(list -> list.forEach(System.out::println));
}
private static <T> List<List<T>> getListFrom2DArray(T[][] array) {
return Arrays.stream(Objects.requireNonNull(array)).map(row -> Arrays.asList((row != null) ? row : (T[]) new Object[0])).collect(Collectors.toList());
}
}