Доступ к вложенным элементам списка и преобразование в список - PullRequest
0 голосов
/ 11 декабря 2018

Я разработал функцию загрузки csv в Spring MVC, используя библиотеку OpenCSV, данные, которые необходимо записать в файл, хранятся ниже класса DTO

public class CsvDataDto {

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

}

Я хочу гибкую и динамическую функциональность, чтобы я инициализировалданные CsvDataDto в моем методе контроллера downloadFile()

// 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<List<Object>>, которые будут добавлены в приведенный выше фрагмент, а также затем преобразовать то же самое в List<String[]>, потому что write() метод Of CsvWriter принимает либо String[], либо List<String[]> в качестве аргумента.

Последний фрагмент, в который будут записываться данныефайл.

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<List<Object>>.Я вижу 7 разных списков, но когда я хочу перебрать этот внутренний список для доступа к данным, JVM не позволила мне сделать это из-за типа Object.

CASE for List<List<Object>>

Я знал, что внутри List есть коллекция list<Object>, основные данные хранятся в каждом внутреннем списке, я хочу получить каждый список, что я пробовал, я упоминал ниже, ноТем не менее, мне не удалось

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<String> header

Мне нужно добавить String[] в List<String[]> records, поэтому мне необходимо извлечь все элементы из List<String> header и затем преобразовать его в String [] и добавьте то же самое в records.Я попробовал это, но не повезло

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

ОЖИДАЕМЫЙ ВЫХОД: 1. Мой CSV-файл имеет заголовки, поэтому мне нужно перебрать заголовок List<String[]>, добавить данные в records.add()и передать то же самое в write().

2. Фактические данные, которые находятся внутри List<List<Object>>, мне нужно перебрать элементы внутри и преобразовать их в String[] и добавить данные в records.add()и передать то же самое на write().

userid, fname,lastname,rollno,gender 

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

1 Ответ

0 голосов
/ 11 декабря 2018

Я полагаю, что вы можете облегчить свою задачу, внеся некоторые изменения в 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<Object> на List<UserInfo> и добавить список в CsvDataDTO<UserInfo> без проблем.Так что позже вы можете получить его, как я упоминал выше в примере

...