[英]Converting 2D array into 2D ArrayList that is backed by the original array
I have looked through various examples on how to do this and I have got to this stage.我已经浏览了有关如何执行此操作的各种示例,并且已经到了这个阶段。 My data import is copied into the array list but I am not seeing the data where I thought it would be.
我的数据导入被复制到数组列表中,但我没有看到我认为的数据。
When I use a 2D array it displays the imported data fine, but I want to be able to make changes to the data, hence the array list.当我使用二维数组时,它可以很好地显示导入的数据,但我希望能够对数据进行更改,因此是数组列表。 I need the data to populate two things, first a Java Table and then I will reuse the data in an export to a spreadsheet.
我需要数据来填充两件事,首先是 Java 表,然后我将在导出到电子表格中重用数据。 If you can just help me with the conversion of 2D array to a 2D (if this is what I need)
ArrayList
that would be great.如果您可以帮助我将二维数组转换为二维(如果这是我需要的)
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));
}
}
DataImport.dataImport(filepath)
array displays the correct file path and data when deepToString
is called as a check.当
deepToString
作为检查时, DataImport.dataImport(filepath)
数组显示正确的文件路径和数据。 So I know the data is there.所以我知道数据在那里。 I'm new to Java and stuck fast on this one.
我是 Java 的新手,并且坚持使用这个。 I modified my output to show the counters and array list when the loop completes and it now contains the data from data import, but each cell is in a separate list when what I need are rows and columns.
我修改了我的 output 以在循环完成时显示计数器和数组列表,它现在包含来自数据导入的数据,但是当我需要的是行和列时,每个单元格都在一个单独的列表中。 So it is definitely the way I am populating the array list that I need help with.
所以这绝对是我填充需要帮助的数组列表的方式。
I don't know if DataImport.dataImport(file_path)
is a very fast call, but you shouldn't call it repeatedly, even if it is.我不知道
DataImport.dataImport(file_path)
是否是一个非常快速的调用,但你不应该重复调用它,即使它是。 Only calling it once will also improve the code readability.只调用一次也会提高代码的可读性。
Since you want a 2D array converted to a 2D list, you certainly don't want to use Collections.singleton()
.由于您希望将 2D 数组转换为 2D 列表,因此您当然不想使用
Collections.singleton()
。 Instead, you'd want to create a list inside the outer loop.相反,您希望在外循环内创建一个列表。
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);
}
The inner loop can be eliminated using the Arrays.asList()
helper method:可以使用
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)));
If you'd like to use Java 8 Streams, you'd do it like this:如果你想使用 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()));
So in the end and after understanding the method posted by Akif Hadziabdic, I developed my own solution.所以最后,在了解了 Akif Hadziabdic 发布的方法之后,我开发了自己的解决方案。 I have posted it below just in case anyone else is having the same issue.
我把它贴在下面,以防其他人遇到同样的问题。 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.
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. So simple here is the code:
代码很简单:
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 a fixed size . 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]]
You can implement a custom asList
method using the Arrays#asList
method for the rows of the 2D array and then for the array itself:您可以使用
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) Do the DataImport.dataImport(file_path) only once before loops, no need to read it all the time inside the loop a) 在循环之前只执行一次 DataImport.dataImport(file_path),无需在循环内一直读取它
var rawData = DataImport.dataImport(file_path)
b) Second j-loop should iterate till rawData[i].lenght
b) 第二个 j 循环应该迭代到
rawData[i].lenght
c) Most important. c) 最重要的。 You should create outer list BEFORE i-loop, inner List BEFORE j-loop.
您应该在 i-loop 之前创建外部列表,在 j-loop 之前创建内部列表。 And inside j-loop add data to inner list.
并在 j-loop 内部将数据添加到内部列表。 After j-loop - add this inner list to outer.
在 j-loop 之后 - 将此内部列表添加到外部。
Something like就像是
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.