将ArrayList转换为包含不同长度数组的2D数组

所以我有:

ArrayList<ArrayList> 

其中包含x个包含另外y个字符串的ArrayLists。演示:

 Index 0: String 1 String 2 String 3 Index 1: String 4 Index 2: Index 3: String 5 String 6 

其中index指的是包含字符串的数组索引。

如何将其转换为2D数组,如下所示:

 {{String1, String2, String3},{String4}, {}, {String5, String6}} 

非常感谢。

 String[][] array = new String[arrayList.size()][]; for (int i = 0; i < arrayList.size(); i++) { ArrayList row = arrayList.get(i); array[i] = row.toArray(new String[row.size()]); } 

其中arrayList是您的ArrayList> (或任何List> ,相应地更改for循环内的第一行)

欢迎来到Java 8的世界!

它只花了我一整夜都没有睡觉才能学习编写这一段令人毛骨悚然的代码所需要的东西。 我确定它已经出现在某个地方,但我找不到它。 所以我分享我的研究小时数,享受。 活泉!

假设:

 ArrayList> mainList = new ArrayList>(); // populate this list here 

(或者,相反,在Java 8中:

 ArrayList> mainList = new ArrayList(); //Populate 

那么你所需要的只是:

 String[][] stringArray = mainList.stream().map(u -> u.toArray(new String[0])).toArray(String[][]::new); 

巴姆! 一条线。

我不确定与其他选项相比有多快。 但这是它的工作原理:

  1. 获取mainList 2D ArrayList的流。 这个流有点像一个与LinkedList连接的Vector,他们有一个孩子。 那个孩子,在以后的生活中,在一些NZT-48上注意力 。 我离题了; mainList.stream()返回ArrayList元素的流。 或者甚至更mainList.stream()说法: mainList.stream()返回一个Stream> ,sorta。

  2. 在该流上调用.map函数,该函数将返回一个新流,其内容与传递给map的参数指定的新类型相匹配。 此map函数将为我们转换流中的每个元素。 它有一个内置的foreach声明。 为了做到这一点; map函数将lambda表达式作为参数。 Lambda表达式就像一个简单的内联单行函数。 其中有两种数据类型gettin’Jiggy wit it 。 首先是调用它的流中的数据类型( mainList.stream() )。 下一个类型是它将它映射到的数据类型,它位于lambda表达式的右半部分: u -> u.toArray(new String[0]) 。 在这里, u是您选择的标识符,就像使用foreach语句一样。 上半部分如此声明: u -> 。 就像foreach ,变量u现在将成为流中的每个元素,因为它在流中迭代。 因此, u是原始流的元素所属的数据类型,因为它它们。 Lambda表达式的右半部分显示了如何处理每个元素: u.toArray(new String[0]) 。 将结果存储在新流中的合法位置。 在这种情况下,我们将它转​​换为String[] ..因为毕竟,这是一个String的2D数组..或者更确切地说,从代码中的这一点开始,是String[]一维数组(字符串数组)。 请记住, u最终是一个ArrayList 。 注意,从ArrayList对象调用toArray将创建一个传递给它的类型的新数组。 这里我们传入new String[0] 。 因此,它创建一个String[]类型的新数组,其长度等于ArrayList u的长度。 然后它使用ArrayList的内容填充这个新的字符串ArrayList并返回它。 这使得Lambda表达式返回到map 。 然后, map收集这些字符串数组并使用它们创建一个新流,它具有关联的String[]类型然后返回它。 因此,在这种情况下, map返回Stream 。 (嗯,实际上它返回一个Stream ,这很混乱,需要转换,见下文)

  3. 因此,我们只需要在新的字符串数组上调用toArray 。 但是在Stream上调用toArray与在ArrayList上调用它有点不同,就像我们之前做的那样。 在这里,我们必须使用函数引用令人困惑的事情。 它从这里抓取类型: String[][]::new 。 该new函数的类型为String[][] 。 基本上,因为函数被调用toArray ,它将永远是某种类型的[] 。 在我们的例子中,因为里面的数据是另一个数组,我们只是添加另一个[] 。 我不确定为什么NZT-48没有在这个上工作。 我本来期望对toArray()的默认调用就足够了,看到它是一个流和所有。 特定于Stream 。 任何人都知道为什么map实际返回一个Stream而不是Lambda表达式返回的类型的流?

  4. 现在我们从mainList流中获取了toArray正常运行。 我们可以将它简单地转储到局部变量中: String[][] stringArray = mainList.stream...

将整数的2D ArrayList转换为原始整数的2D数组

现在,我知道有些人在那里。 “这不适用于整数!” 就像我的情况一样。 然而,它确实适用于“ Ents ”,见上文。 但是,如果你想从2D ArrayList of Integer一个2D原始int数组(即ArrayList> )。 你必须改变中间[地球]的映射。 请记住,ArrayLists不能具有基本类型。 因此,您无法在ArrayList上调用toArray并期望获得int[] 。 你需要再次将它映射出来。

 int[][] intArray = mainList.stream().map( u -> u.stream().mapToInt(i->i).toArray() ).toArray(int[][]::new); 

为了便于阅读,我试图将其分开。 但是你可以在这里看到我们必须再次完成相同的整个映射过程。 这次我们不能简单地在ArrayList上调用toArray ; 与上面的例子一样。 这里我们在Stream上调用toArray而不是ArrayList 。 因此,出于某种原因,我们不必将它传递给“类型”,我认为它服用大脑类固醇。 因此,我们可以采用默认选项; 在那里它受到了NZT-48的打击,并为我们这个[运行]时间找出了明显的结果。 我不确定为什么它不能在上面的例子中做到这一点。 哦,没错…… ArrayLists不像Streams那样服用NZT-48。 等等……我甚至在这里谈论什么?

Annnyhoow,因为溪流非常聪明。 像谢尔顿一样,我们需要一个全新的协议来处理它们。 显然,高级智能并不总是意味着易于处理。 因此,需要这个新的mapToInt来创建一个新的Stream ,我们可以使用它来更智能地使用。 mapToInti->i Lambda表达式是Integer to int的简单拆箱,使用允许int = Integer的隐式自动拆箱。 现在,这似乎是一件愚蠢的事情,好像情报有其局限性。 在我的冒险中学习所有这些:我实际上尝试使用mapToInt(null)因为我期望一个默认行为。 不是争论!! ( 咳嗽 Sheldon 咳嗽 )然后我用我最好的Husker山谷女孩口音说,“毕竟,它称为mapToInt ,我猜想,就像,84%的时间( 42 x2)它会像,通过i->i和所有人一样,所以喜欢,omgawd!“ 毋庸置疑,我觉得有点……就像…… 这个家伙 。 不知道为什么它不起作用!

好吧,我是红眼,半昏迷,半睡半醒。 我可能犯了一些错误; 请把它们拖出去,这样我就可以解决它们并让我知道是否有更好的方法!

PT

您可以使用toArray()方法将ArrayList转换为数组。 由于您在ArrayList中有ArrayList,因此您需要迭代每个元素并应用此方法。

像这样: –

 ArrayList> mainList = new ArrayList>(); // populate this list here //more code // convert to an array of ArrayLists ArrayList tempList = new ArrayList(); for (ArrayList stringList : mainList){ tempList.add((String[])stringList.toArray()); } //Convert to array of arrays - 2D array String [][]list = (String[][])tempList.toArray(); 

你可以在这里找到更多关于toArray() 信息。

 ArrayList> list= new ArrayList>(); ArrayList a = new ArrayList(); ArrayList b = new ArrayList(); a.add("Hello"); b.add("Hell"); list.add(a); list.add(b); Object[][] array = new Object[list.size()][]; Iterator> iterator = list.iterator(); int i = 0; while(iterator.hasNext()){ array[i] = iterator.next().toArray(); } 

您可以使用以下代码段将Object []转换为String []

 String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class); 

例如:

 public String[][] toArray(List> list) { String[][] r = new String[list.size()][]; int i = 0; for (List next : list) { r[i++] = next.toArray(new String[next.size()]); } return r; } 

这个完整的迷你程序代码以非常不言自明的方式回答这个问题。只需粘贴并运行它:

 import java.util.ArrayList; import java.util.List; public class ListTo2Darray { public String[][] toArray(List> list) { String[][] r = new String[list.size()][]; int i = 0; for (List next : list) { r[i++] = next.toArray(new String[next.size()]); } return r; } public static void main(String[]arg){ String[][] sham; List> mList = new ArrayList(); List a= new ArrayList(); List b= new ArrayList(); a.add("a"); a.add("a"); b.add("b"); b.add("b"); mList.add(a); mList.add(b); ListTo2Darray mt= new ListTo2Darray(); sham= mt.toArray(mList); System.out.println(sham[0][0]); System.out.println(sham[0][1]); System.out.println(sham[1][0]); System.out.println(sham[1][1]); } }