欢迎来到 Java 8 的世界!
我只花了一整夜不睡觉的时间就学会了写这行代码需要什么。我确定它已经在某个地方,但我找不到它。所以我分享我的研究时间和时间,享受。哇!
假设:
ArrayList<ArrayList<String>> mainList = new ArrayList<ArrayList<String>>();
// populate this list here
(或者,更确切地说,在 Java 8 中:
ArrayList<ArrayList<String>> mainList = new ArrayList();
//Populate
)
那么你只需要:
String[][] stringArray = mainList.stream().map(u -> u.toArray(new String[0])).toArray(String[][]::new);
砰!一条线。
我不确定它与其他选项相比有多快。但这就是它的工作原理:
获取mainList
2D ArrayList 的流。这个流有点像一个连接了 LinkedList 的 Vector 并且他们有了一个孩子。那个孩子,在以后的生活中,服用了一些NZT-48。我离题了;mainList.stream()
正在返回一个ArrayList<String>
元素流。或者用更极客的话来说:mainList.stream()
返回 a Stream<ArrayList<String>>
, sorta。
调用该.map
流上的函数,该函数将返回一个新流,其内容与传入的参数指定的新类型相匹配map
。这个map
函数将为我们隐藏流中的每个元素。它有一个内置foreach
语句。为了做到这一点;该map
函数将 lambda 表达式作为其参数。Lambda 表达式就像一个简单的内联单行函数。它有两种数据类型。首先是调用它的流中的数据类型 ( mainList.stream()
)。下一个类型是它将映射到的数据类型,它位于 lambda 表达式的右半部分u -> u.toArray(new String[0])
:这u
是您选择的标识符,就像使用foreach
陈述。前半部分是这样声明的u ->
:和 a 一样foreach
,变量u
现在将是流中的每个元素,因为它遍历流。因此,u
是原始流的元素的数据类型,因为它就是它们。Lambda 表达式的右半部分显示了如何处理每个元素:u.toArray(new String[0])
. 结果将存储在新流中的应有位置。在这种情况下,我们将其转换为String[]
.. 因为毕竟这是String
.. 的 2D 数组,或者更确切地说,从代码中的这一点开始,String[]
(字符串数组)的 1D 数组。请记住,这u
最终是一个ArrayList
. 请注意,toArray
从ArrayList
object 将创建一个传入它的类型的新数组。这里我们传入new String[0]
。因此,它创建了一个新的类型数组,String[]
其长度等于 ArrayList 的长度u
。然后它用 的内容填充这个新的字符串数组ArrayList
并返回它。留下 Lambda 表达式并返回到map
. 然后,map
收集这些字符串数组并用它们创建一个新流,它具有关联的类型String[]
,然后返回它。因此,在这种情况下,map
返回 a 。Stream<String[]>
(嗯,实际上它返回 a Stream<Object[]>
,这是令人困惑的,需要转换,见下文)
因此,我们只需要调用toArray
新的字符串数组流。但是调用toArray
aStream<Object[]>
与调用 an 有点不同ArrayList<String>
,就像我们之前所做的那样。在这里,我们不得不使用一个函数引用令人困惑的东西。它从中获取类型:String[][]::new
. 该new
函数具有 type String[][]
。基本上,由于该函数被称为toArray,它总是[]
某种类型的。在我们的例子中,因为里面的数据是另一个数组,所以我们只是添加到另一个[]
. 我不确定为什么 NZT-48 不能在这个上工作。我原以为默认调用toArray()
就足够了,因为它是一个流和所有。一个流就是专门的Stream<String[]>
。任何人都知道为什么map
实际上返回一个Stream<Object[]>
而不是内部 Lambda 表达式返回的类型的流?
现在我们toArray
从我们的mainList
流中得到了正确的行为。我们可以简单地将其转储到一个局部变量中:String[][] stringArray = mainList.stream...
将 2D ArrayList of Integers 转换为 2D 原始整数数组
现在,我知道你们中的一些人正在外面。“这对整数不起作用!” 就像我的情况一样。然而,它确实适用于“ Ents ”,见上文。但是,如果你想要一个2D的(即)的 2D 原始int
数组。你必须改变那个中[地球]映射。请记住,ArrayLists 不能有原始类型。因此,您不能调用并期望获得. 您将需要将其映射出来......再次。ArrayList
Integer
ArrayList<ArrayList<Integer>>
toArray
ArrayList<Integer>
int[]
int[][] intArray = mainList.stream().map( u -> u.stream().mapToInt(i->i).toArray() ).toArray(int[][]::new);
为了便于阅读,我试图将其隔开。但是您可以在这里看到,我们必须再次经历相同的整个映射过程。这次我们不能简单地调用toArray
ArrayList u
;和上面的例子一样。在这里,我们调用toArray
a Stream
not an ArrayList
。因此,出于某种原因,我们不必将其传递给“类型”,我认为它正在服用大脑类固醇。因此,我们可以采用默认选项;它需要 NZT-48 的打击,并在这个 [运行] 时间为我们找出显而易见的东西。我不确定为什么它不能在上面的例子中做到这一点。哦,没错.... ArrayLists 不像 Streams 那样采用 NZT-48。等等……我到底在说什么?
Annnyhoow,因为流非常聪明。像Sheldon一样,我们需要一个全新的协议来处理它们。显然,先进的智能并不总是意味着容易处理。因此,需要这个新mapToInt
的来制作一个Stream
我们可以更智能地使用它的新的toArray
。中的i->i
Lambda 表达式是对tomapToInt
的简单拆箱,使用允许的隐式自动拆箱。现在,这似乎是一件愚蠢的小事,好像智力有其局限性。在我冒险学习这一切的过程中:我实际上尝试使用,因为我期望一个默认行为。不是争论!!(咳谢尔顿咳)然后我用我最好的胡斯克说Integer
int
int = Integer
mapToInt(null)
山谷女孩口音,“毕竟,它被称为mapToInt
,我猜,像,84% 的时间(42 x2)它会,像,路过i->i
,像,每个人,像,天哪!” 不用说,我觉得有点……像……这家伙。我不知道,为什么它不能那样工作。
嗯,我红眼了,半昏迷半睡着。我可能犯了一些错误;请把它们拖出来,这样我就可以修复它们,如果有更好的方法,请告诉我!
PT