2012-04-06 42 views
14

Vì vậy, tôi có:Chuyển đổi ArrayList vào mảng 2D chứa độ dài khác nhau của các mảng

ArrayList<ArrayList<String>> 

nào chứa một số x của ArrayLists có chứa một số y của Strings .. Để chứng minh:

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

Trong đó chỉ mục đề cập đến chỉ mục mảng chứa chuỗi.

Làm thế nào tôi có thể chuyển đổi này vào một mảng 2D trông giống như:

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

Cảm ơn bạn rất nhiều.

Trả lời

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

nơi arrayListArrayList<ArrayList<String>> của bạn (hoặc bất kỳ List<List<String>>, thay đổi dòng đầu tiên bên trong for vòng lặp cho phù hợp)

+1

gì nếu tôi có ArrayList và muốn chuyển đổi nó thành một 2D mảng ? – shridatt

+3

xin lỗi, tôi đã bỏ lỡ điều này, bạn có thể đã tìm ra nó ngay bây giờ ... Dù sao, nó chỉ đơn giản là 'String [] [] array2D = new String [arrayList.size()] []; cho (int i = 0; i

5

Bạn có thể sử dụng phương thức toArray() để chuyển đổi ArrayList thành mảng. Vì bạn có ArrayList trong ArrayList, bạn sẽ cần phải lặp qua từng phần tử và áp dụng phương thức này.

Something như thế này: -

ArrayList<ArrayList<String>> mainList = new ArrayList<ArrayList<String>>(); 
// populate this list here 
//more code 

// convert to an array of ArrayLists 
ArrayList<String[]> tempList = new ArrayList<String[]>(); 
for (ArrayList<String> stringList : mainList){ 
    tempList.add((String[])stringList.toArray()); 
} 

//Convert to array of arrays - 2D array 
String [][]list = (String[][])tempList.toArray(); 

Bạn có thể tìm thêm về toArray()here.

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

Bạn có thể sử dụng đoạn mã dưới đây để chuyển đổi Object [] để String []

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

Ví dụ:

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

Chào mừng bạn đến một thế giới với Java 8!

Nó chỉ đưa tôi cả đêm mà không có giấc ngủ để tìm hiểu những gì cần thiết để viết một dòng mã freaking này. Tôi chắc chắn nó đã được ra khỏi một nơi nào đó nhưng tôi không thể tìm thấy nó. Vì vậy, tôi chia sẻ giờ và giờ nghiên cứu của mình, hãy tận hưởng. Woot!

Giả sử:

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

(Hay nói đúng hơn, trong Java 8:

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

)

Sau đó, tất cả các bạn cần là:

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

Bam! Một đường thẳng.

Tôi không chắc nó được so sánh nhanh như thế nào với các tùy chọn khác. Nhưng đây là cách hoạt động:

  1. Lấy một luồng mainList 2D ArrayList. Dòng này hơi giống như một Vector nối với một LinkedList và họ đã có một đứa trẻ.Và đứa trẻ đó, sau này trong cuộc sống, đã lên men trên một số NZT-48. Tôi digress; mainList.stream() đang trả lại luồng gồm ArrayList<String> yếu tố. Hoặc thậm chí là geekier nói: mainList.stream() trả về một Stream<ArrayList<String>>, phân loại.

  2. Gọi hàm .map trên luồng đó sẽ trả lại luồng mới có nội dung khớp với loại mới được chỉ định bởi các thông số được chuyển vào map. Chức năng map này sẽ bí mật từng phần tử trong luồng của chúng tôi cho chúng tôi. Nó có sẵn trong câu lệnh foreach. Để thực hiện điều này; hàm map lấy biểu thức lambda làm tham số của nó. A Lambda expression giống như chức năng một dòng đơn giản. Có hai loại dữ liệu gettin' Jiggy wit it. Đầu tiên là loại dữ liệu trong luồng mà nó được gọi là (mainList.stream()). Loại tiếp theo là loại dữ liệu mà nó sẽ ánh xạ nó ra, nằm ở nửa bên phải của biểu thức lambda: u -> u.toArray(new String[0]). Ở đây u là số nhận dạng bạn chọn giống như khi sử dụng câu lệnh foreach. Nửa đầu tuyên bố điều này như sau: u ->. Và giống như một số foreach, biến số u giờ sẽ là mỗi phần tử trong luồng khi nó lặp qua luồng. Do đó, u là loại dữ liệu mà các phần tử của luồng ban đầu là vì nó là chúng. Nửa bên phải của biểu thức Lambda cho thấy phải làm gì với mỗi phần tử: u.toArray(new String[0]). Với kết quả được lưu trữ ở vị trí hợp pháp của họ trong luồng mới. Trong trường hợp này, chúng ta chuyển đổi nó thành String[] .. bởi vì sau khi tất cả, đây là mảng 2D String .. hoặc đúng hơn từ điểm này trong mã, một mảng 1D là String[] (mảng chuỗi). Hãy nhớ rằng u cuối cùng là một ArrayList. Lưu ý, gọi toArray từ đối tượng ArrayList sẽ tạo một mảng mới của loại được truyền vào nó. Ở đây chúng tôi vượt qua trong new String[0]. Do đó, nó tạo ra một mảng mới kiểu String[] và có chiều dài bằng với chiều dài của ArrayList u. Sau đó nó điền vào mảng chuỗi mới này với nội dung của ArrayList và trả về nó. Mà để lại biểu thức Lambda và trở lại thành map. Sau đó, map thu thập các mảng chuỗi này và tạo luồng mới với chúng, nó có loại liên quan String[] và sau đó trả về nó. Do đó, map trả lại Stream<String[]>, trong trường hợp này. (Vâng, thực tế nó trả về một Stream<Object[]>, gây nhầm lẫn và cần chuyển đổi, xem bên dưới)

  3. Do đó chúng tôi chỉ cần gọi toArray trên luồng chuỗi mới đó. Nhưng gọi số toArray trên Stream<Object[]> hơi khác một chút so với gọi số ArrayList<String>, như chúng tôi đã làm trước đây. Ở đây, chúng ta phải sử dụng một hàm gây nhầm lẫn tham chiếu hàm. Nó lấy loại này: String[][]::new. Chức năng new có loại String[][]. Về cơ bản, vì hàm này được gọi là toArray, nó sẽ luôn là [] của một số loại. Trong trường hợp của chúng tôi vì dữ liệu bên trong là một mảng khác, chúng tôi chỉ thêm vào một số khác []. Tôi không chắc tại sao NZT-48 lại không làm việc này. Tôi đã có thể mong đợi một cuộc gọi mặc định để toArray() sẽ là đủ, thấy rằng một dòng của nó và tất cả. Luồng cụ thể là Stream<String[]>. Bất cứ ai biết tại sao map thực sự trả về một Stream<Object[]> và không phải là một dòng của kiểu trả về bởi biểu thức Lambda bên trong?

  4. Bây giờ, chúng tôi đã nhận được toArray từ luồng mainList hoạt động bình thường của chúng tôi.Chúng tôi chỉ có thể đổ nó vào một biến địa phương dễ dàng đủ: String[][] stringArray = mainList.stream...

Chuyển đổi 2D ArrayList của số nguyên vào mảng 2D ints nguyên thủy

Bây giờ, tôi biết một số bạn được ra khỏi đó đi. "Điều này không làm việc cho ints!" Như trường hợp của tôi. Tuy nhiên, nó hoạt động cho "Ents", xem ở trên. Tuy nhiên, nếu bạn muốn một mảng int nguyên thủy 2D từ một 2D ArrayList của Integer (ví dụ: ArrayList<ArrayList<Integer>>). Bạn phải thay đổi xung quanh bản đồ [trái đất] giữa đó. Hãy nhớ rằng ArrayLists không thể có các kiểu nguyên thủy. Do đó, bạn không thể gọi số toArray trên số ArrayList<Integer> và mong muốn nhận được int[]. Bạn sẽ cần phải vạch ra nó ... một lần nữa.

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

Tôi đã cố gắng giải phóng nó để dễ đọc. Nhưng bạn có thể thấy ở đây rằng chúng ta phải trải qua toàn bộ quá trình lập bản đồ một lần nữa. Lần này chúng ta không thể chỉ đơn giản gọi toArray trên ArrayList u; như với ví dụ trên. Ở đây, chúng tôi đang gọi số toArray trên số Stream không phải là ArrayList. Vì vậy, vì một lý do nào đó, chúng tôi không phải chuyển nó thành "loại", tôi nghĩ rằng nó dùng steroid của nó. Do đó, chúng tôi có thể chọn tùy chọn mặc định; nơi nó có một hit của NZT-48 và con số ra rõ ràng đối với chúng tôi [run] thời gian này. Tôi không chắc tại sao nó không thể làm điều đó trong ví dụ trên. Oh, thats right .... ArrayLists không dùng NZT-48 như Streams. Chờ đã ... tôi còn nói gì nữa?

Annnyhoow, vì luồng thông minh. Giống như Sheldon, chúng tôi cần một giao thức hoàn toàn mới để giải quyết chúng. Rõ ràng trí thông minh tiên tiến không phải lúc nào cũng dễ dàng giải quyết. Do đó, cần có mapToInt mới để tạo Stream mới mà chúng tôi có thể sử dụng thông minh toArray thông minh hơn. Và biểu thức Lambda i->i Lambda trong mapToInt là một unboxing đơn giản của Integer đến int, bằng cách sử dụng tính năng tự động mở hộp ẩn cho phép int = Integer. Mà, bây giờ, có vẻ như một điều tầm thường câm để làm, như thể trí thông minh có giới hạn của nó. Trong cuộc phiêu lưu của tôi học tất cả những điều này: Tôi thực sự đã cố gắng sử dụng mapToInt(null) vì tôi đã mong đợi một hành vi mặc định. Không phải là một đối số !! (ho Sheldon ho) Sau đó, tôi nói trong cô gái giọng Husker thung lũng hết sức mình, "Afterall, nó gọi mapToInt, tôi sẽ đoán rằng, giống như, 84% thời gian (42 x2) nó sẽ được, như, đã thông qua i->i bởi, giống như, tất cả mọi người, giống như, omgawd! " Không cần phải nói, tôi cảm thấy một chút ... như .. this guy. Dunno tại sao nó không hoạt động theo cách đó!

Vâng, tôi là mắt đỏ và nửa mê sảng và nửa ngủ. Tôi có thể đã phạm một số sai lầm; xin vui lòng troll chúng ra để tôi có thể sửa chữa chúng và cho tôi biết nếu có một cách tốt hơn!

PT

+0

Vì' bản đồ' có một Lambda (có uy tín biết loại dữ liệu của mỗi bên của Lambda), nó sẽ có thể chuyển thông tin kiểu dữ liệu đó trở đi. Vì vậy, mặc dù ramblings điên rồ của tôi, tôi vẫn thực sự muốn một câu trả lời cho hai câu hỏi nêu trên: 1) Tại sao 'map' thực sự trả về một' Stream 'như một hành vi mặc định và không phải là một dòng của loại trả về bởi Lambda biểu hiện bên trong? --- 2) Tại sao 'mapToInt' không có cách sử dụng mặc định là' i-> i'? –

0

hoàn chỉnh nhỏ mã chương trình này sẽ trả lời câu hỏi này trong tự giải thích way.Just dán khá và chạy nó:

import java.util.ArrayList; 
import java.util.List; 

public class ListTo2Darray { 

    public String[][] toArray(List<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<List<?>> mList = new ArrayList(); 

     List<String> a= new ArrayList(); 
     List<String> 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]); 
    } 

} 
Các vấn đề liên quan