简体   繁体   English

将二维数组转换为由原始数组支持的二维 ArrayList

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM