[英]Converting 2D array into 2D ArrayList that is backed by the original array
我已經瀏覽了有關如何執行此操作的各種示例,並且已經到了這個階段。 我的數據導入被復制到數組列表中,但我沒有看到我認為的數據。
當我使用二維數組時,它可以很好地顯示導入的數據,但我希望能夠對數據進行更改,因此是數組列表。 我需要數據來填充兩件事,首先是 Java 表,然后我將在導出到電子表格中重用數據。 如果您可以幫助我將二維數組轉換為二維(如果這是我需要的) ArrayList
,那就太好了。
ArrayList<ArrayList<String>> student_data = new ArrayList<ArrayList<String>>();
System.out.println(DataImport.dataImport(file_path).length);
System.out.println(Arrays.deepToString(DataImport.dataImport(file_path)));
for (int i = 0; i < DataImport.dataImport(file_path).length; i++) {
for (int j = 0; j <= 249; j++) {
student_data.add(new ArrayList<String>(Collections.singleton(
DataImport.dataImport(file_path)[i][j])));
System.out.println(student_data.get(i, j));
}
}
當deepToString
作為檢查時, DataImport.dataImport(filepath)
數組顯示正確的文件路徑和數據。 所以我知道數據在那里。 我是 Java 的新手,並且堅持使用這個。 我修改了我的 output 以在循環完成時顯示計數器和數組列表,它現在包含來自數據導入的數據,但是當我需要的是行和列時,每個單元格都在一個單獨的列表中。 所以這絕對是我填充需要幫助的數組列表的方式。
我不知道DataImport.dataImport(file_path)
是否是一個非常快速的調用,但你不應該重復調用它,即使它是。 只調用一次也會提高代碼的可讀性。
由於您希望將 2D 數組轉換為 2D 列表,因此您當然不想使用Collections.singleton()
。 相反,您希望在外循環內創建一個列表。
String[][] data = DataImport.dataImport(file_path);
System.out.println(data.length);
System.out.println(Arrays.deepToString(data));
ArrayList<ArrayList<String>> student_data = new ArrayList<>();
for (String[] row : data) {
ArrayList<String> list = new ArrayList<>();
for (String value : row) {
list.add(value);
}
student_data.add(list);
}
可以使用Arrays.asList()
輔助方法消除內部循環:
String[][] data = DataImport.dataImport(file_path);
ArrayList<ArrayList<String>> student_data = new ArrayList<>();
for (String[] row : data)
student_data.add(new ArrayList<>(Arrays.asList(row)));
如果你想使用 Java 8 Streams,你可以這樣做:
String[][] data = DataImport.dataImport(file_path);
List<List<String>> student_data = Arrays.stream(data)
.map(row -> Arrays.stream(row).collect(Collectors.toList()))
.collect(Collectors.toList()));
所以最后,在了解了 Akif Hadziabdic 發布的方法之后,我開發了自己的解決方案。 我把它貼在下面,以防其他人遇到同樣的問題。 Using guidance from Multi Dimensional ArrayList in Java I simply had to create a new arraylist within the first row iteration within the existing arraylist. 代碼很簡單:
ArrayList<ArrayList<String>> student_data = new ArrayList<ArrayList<String>>();
for (int i = 0; i < DataImport.dataImport(file_path).length; i++) {
student_data.add(new ArrayList<>());
for (int j = 0; j <= 249; j++) {
student_data.get(i).add(DataImport.dataImport(file_path)[i][j]);
}
}
You can use the following methods in sequence: Arrays.stream
, then Arrays::asList
and Collectors.toUnmodifiableList
to convert a multidimensional array to the same list that is backed by the original array and has a fixed size , since the array is always of一個固定的大小。
String[][] array = {{"str1", "str2"}, {"str3"}, {"str4", "str5", "str6"}};
List<List<String>> list = Arrays
// returns a sequential stream over the array rows
.stream(array)
// returns a fixed-size list backed by the
// specified array row, disallows null
// values when the array row is null
.map(Arrays::asList)
// so as not to confuse the list itself and
// its internal lists, i.e. array rows, disallows
// null values when the array row is null
.collect(Collectors.toUnmodifiableList());
// changing the data in the list
list.get(1).set(0, "str33");
// you can't add data to the inner lists and to
// the list itself, only modify existing data
// list.get(1).add("str34");
// list.add(Arrays.asList("str71"));
// UnsupportedOperationException
// output
System.out.println(Arrays.deepToString(array));
System.out.println(list);
//[[str1, str2], [str33], [str4, str5, str6]]
//[[str1, str2], [str33], [str4, str5, str6]]
您可以使用Arrays#asList
方法為二維數組的行和數組本身實現自定義asList
方法:
/**
* Returns a fixed-size list backed by the specified array. Changes made to
* the array will be visible in the returned list, and changes made to the
* list will be visible in the array...
*
* @param array the 2D array by which the list will be backed
* @param <T> the class of the objects in the 2D array
* @return a list view of the specified array
* @throws NullPointerException if the specified array is 'null',
* or one of its rows is 'null'
* @see Arrays#asList(Object[])
*/
public static <T> List<List<T>> asList(T[][] array) {
return Arrays.asList(Arrays.stream(array)
.map(Arrays::asList).<List<T>>toArray(List[]::new));
}
// test
public static void main(String[] args) {
String[][] array = {{"A", "B"}, {"C", "D", null}};
List<List<String>> list = asList(array);
System.out.println(Arrays.deepToString(array));
// [[A, B], [C, D, null]]
System.out.println(list);
// [[A, B], [C, D, null]]
list.get(1).set(2, "E");
System.out.println(Arrays.deepToString(array));
// [[A, B], [C, D, E]]
System.out.println(list);
// [[A, B], [C, D, E]]
}
a) 在循環之前只執行一次 DataImport.dataImport(file_path),無需在循環內一直讀取它
var rawData = DataImport.dataImport(file_path)
b) 第二個 j 循環應該迭代到rawData[i].lenght
c) 最重要的。 您應該在 i-loop 之前創建外部列表,在 j-loop 之前創建內部列表。 並在 j-loop 內部將數據添加到內部列表。 在 j-loop 之后 - 將此內部列表添加到外部。
就像是
var rawData = DataImport.dataImport(file_path)
var studentList = new List<List<>>
for (int i = 0; i < rawData.lenght; i++) {
var innerList = new List<>;
for (int j = 0; i < rawData[i].lenght; j++) {
innerList.add(rawData[i][j])
}
studentList.add(innerList);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.