【问题标题】:Access nested List elements and convert into List<String[]>访问嵌套的 List 元素并转换为 List<String[]>
【发布时间】:2018-12-11 09:46:46
【问题描述】:

我使用 OpenCSV 库在 Spring MVC 中开发了 csv 下载功能,需要写入文件的数据由下面的 DTO 类保存

public class CsvDataDto {

    private String fileName;
    List<String> header=new ArrayList<>();;
    private String heading;
    List<List<Object>> data=new ArrayList<>();
//getters and setters

}

我想要灵活和动态的功能,所以,我在我的控制器方法downloadFile()中初始化了CsvDataDto的数据

// Download Method snippet
if (type.equals("csv")) {
            CsvDataDto dataDTO = new CsvDataDto();
            dataDTO.setFileName("Table_Data");
            dataDTO.getHeader().add("User Id");
            dataDTO.getHeader().add("First Name");
            dataDTO.getHeader().add("Last Name");
            dataDTO.getHeader().add("Roll No");
            dataDTO.getHeader().add("Email ID");
            dataDTO.getHeader().add("Gender");
            List<UserInfo> list = userInfoDao.findById(tableId);
            for (UserInfo infoList : list) {
                List<Object> newList = new ArrayList<>();
                newList.add(infoList.getUserId());
                newList.add(infoList.getFirstName());
                newList.add(infoList.getLastName());
                newList.add(infoList.getRollNo());
                newList.add(infoList.getEmail());
                newList.add(infoList.getGender());
                dataDTO.getData().add(newList);

            }

到这里一切都很好,我卡住的那一刻是访问List&lt;List&lt;Object&gt;&gt;中的元素,这些元素将添加到上面的sn-p中,然后将其转换为List&lt;String[]&gt;,因为write() CsvWriter 的方法将 String[]List&lt;String[]&gt; 作为参数。

将数据写入文件的最终片段。

List<String[]> records = new ArrayList<>();
        String csvFileName = csvDataDto.getFileName();
CSVWriter writer = new CSVWriter(new FileWriter(csvFileName));

        String[] headerArr = new String[csvDataDto.getHeader().size()];
        headerArr = csvDataDto.getHeader().toArray(headerArr);
        records.add(headerArr);

        for (List<Object> objList : csvDataDto.getData()) {
            System.out.println("object list:" + objList);
            String[] fileData = new String[objList.size()];
            fileData = objList.toArray(fileData);
            records.add(fileData);
        }
        writer.writeAll(records);
        writer.close();

上面的逻辑需要改进,因为我下载的文件是空白的。 当我调试List&lt;List&lt;Object&gt;&gt;.我可以看到 7 个不同的列表,但是当我想遍历该内部列表以访问数据时,由于类型为 Object,JVM 不允许我这样做。

List&lt;List&lt;Object&gt;&gt; 的案例

我知道list&lt;Object&gt;里面有list&lt;Object&gt;的集合List,主要数据存储在每个内部列表中,我想获取我尝试过的每个列表,我在下面提到,但我仍然没有成功

for(List<Object> objList : csvDataDto.getData())
{
for(UserInfo info:(UserInfo)objList ){ // NOT ALLOWED CHANGE TYPE TO Object
}
}

如果我这样做,那么我将无法获取像 getId()getName()getRollNo() 这样的记录

 for(List<Object> objList : csvDataDto.getData())
    {
    for(Object obj:objList ){ // I didn't found any of my getter, just found all mthod of Object class itself

    }
    }

List&lt;String&gt; header 的类似情况

我需要在List&lt;String[]&gt; records 中添加String[],所以我有必要从List&lt;String&gt; header 中获取所有元素,然后将其转换为String[] 并在records 中添加相同的元素。我试过了,但没有运气

String[] headerArr = new String[csvDataDto.getHeader().size()];
        headerArr = csvDataDto.getHeader().toArray(headerArr);
        records.add(headerArr);

预期输出: 1. 我的 Csv 文件有标题所以,我需要迭代 List&lt;String[]&gt; 标题,将数据添加到 records.add(),并将其传递给 write()

2.List&lt;List&lt;Object&gt;&gt;里面的实际数据,我需要迭代里面的元素,把它们转换成String[],然后把数据添加到records.add()中,然后传递给write()

userid, fname,lastname,rollno,gender 

1     , john,   doe   ,1001,   M     
2     , Rose,   Mary  ,1002,   F
3     , Jack,   Jill  ,1003,   M

【问题讨论】:

  • 你试过用 flatMap 吗?如果没有检查:mkyong.com/java8/java-8-flatmap-example
  • 你能用我的场景演示一下吗
  • CsvDataDto 是你定义的吗?你能修改那个类还是来自某个 API?
  • CsvDataDao 是我的自定义 DTO 类
  • 为什么不使用泛型而不是对象?类似 CsvDataDao 这样您就可以访问 Foo 方法而不必强制转换对象

标签: list csv spring-mvc export-to-csv opencsv


【解决方案1】:

我相信您可以通过对 CsvDataDto 进行一些更改来促进您的任务

你可以这样做

public class CsvDataDto<T> {

    private String fileName;
    List<String> header=new ArrayList<>();
    private String heading;
    List<List<T>> data=new ArrayList<>();
//getters and setters

}

这种方法的好处是您不必处理可能导致错误的对象和转换。

例如,当您提到时,您必须循环的任何地方:

for(List<Object> objList : csvDataDto.getData())
    {
    for(Object obj:objList ){ // I didn't found any of my getter, just found all mthod of Object class itself

    }
    }

你将拥有

for(List<FooClass> objList : csvDataDto<FooClass>.getData())
    {
    for(FooClass obj:objList ){ 
       ... //here you can access the methods of FooClass, 
    }
    }

更改您的 DTO 设计可以使您的任务更轻松。

FooClass 代表你选择的一个类,所以可以是任何东西,在你的情况下它可能是UserInfo

因此,当您在第一步中执行此操作时:

    // Download Method snippet
if (type.equals("csv")) {
            CsvDataDto dataDTO = new CsvDataDto();
            dataDTO.setFileName("Table_Data");
            dataDTO.getHeader().add("User Id");
            dataDTO.getHeader().add("First Name");
            dataDTO.getHeader().add("Last Name");
            dataDTO.getHeader().add("Roll No");
            dataDTO.getHeader().add("Email ID");
            dataDTO.getHeader().add("Gender");
            List<UserInfo> list = userInfoDao.findById(tableId);
            for (UserInfo infoList : list) {
                List<Object> newList = new ArrayList<>();
                newList.add(infoList.getUserId());
                newList.add(infoList.getFirstName());
                newList.add(infoList.getLastName());
                newList.add(infoList.getRollNo());
                newList.add(infoList.getEmail());
                newList.add(infoList.getGender());
                dataDTO.getData().add(newList);

            }

您可以将List&lt;Object&gt; 替换为List&lt;UserInfo&gt; 并将列表添加到CsvDataDTO&lt;UserInfo&gt; 中没有任何问题。 所以稍后你可以像我在上面的例子中提到的那样检索它

【讨论】:

  • hmm 我认为这是有道理的,但我为 Listheader 提出了一个案例,我迭代相同并将其转换为 String[],但仍然没有将数据写入我的csv文件,这是怎么回事
  • 我明白,不幸的是需要调试代码并在那里才能更有用。
  • 但是,这仍然不是通用的,因为每次我需要更改不同对象的代码时,您能建议我如何使该方法适用于任何类型
  • 使用泛型是正确的选择,而不是使用对象。请参阅泛型的好处。但是在这里我们必须首先了解为什么您的文件是空白的。当你做 writer.writeAll(records);您可以调试并查看它实际上充满了信息的记录吗?
  • 写这样的下载方法的目的只是为了让下载功能通用,
猜你喜欢
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-13
相关资源
最近更新 更多