【问题标题】:Is it possible to create a csv to object converter using java generics是否可以使用 java 泛型创建 csv 到对象转换器
【发布时间】:2022-11-11 03:14:14
【问题描述】:

我创建了一个简单的转换器,它采用String fileName 并将.csv 文件中的行转换为List<Cat>。我现在面临的问题是现在还有一个Dog,并且我不允许复制和粘贴该方法以将返回类型更改为List<Dog>

我尝试使用返回类型List<Object> 尝试在转换后将其解析为CatDog,但它不会让我这样做。如果可能的话,我正在寻找这个问题的通用解决方案。

我尝试了什么:

@Data
@Entity
@Table(name = "cat")
public class Cat implements Serializable {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @Column(columnDefinition = "int(10)", nullable = false)
    int id;

    @Column(columnDefinition = "varchar(20)", nullable = false)
    String name;    
}

@Data
@Entity
@Table(name = "dog")
public class Dog implements Serializable {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @Column(columnDefinition = "int(10)", nullable = false)
    int id;

    @Column(columnDefinition = "varchar(20)", nullable = false)
    String name;    
}

public List<Object> convertToObject(String fileName, String object) {
    List<Object> objList = new ArrayList();
    Path pathToFile = Paths.get(fileName);

    try (BufferedReader br = Files.newBufferedReader(pathToFile)) {
        int index = 1;

        // read the first line from the text file
        String line = br.readLine();

        // loop until all lines are read
        while (line != null) {

            if (index > 1) {
                switch (object) {
                    case "cat" : {
                        // use string.split to load a string array with the values from
                        // each line of
                        // the file, using a comma (,) as the delimiter
                        String[] attributes = line.split(",");

                        Cat cat = new Cat();

                        createCat(attributes, cat);

                        // adding Cat into ArrayList
                        objList.add(cat);   
                    }

                    case "dog" : {
                        // use string.split to load a string array with the values from
                        // each line of
                        // the file, using a comma (,) as the delimiter
                        String[] attributes = line.split(",");

                        Dog dog = new Dog();

                        createDog(attributes, dog);

                        // adding Dog into ArrayList
                        objList.add(dog);   
                    }
                }
            }

            // read next line before looping
            // if end of file reached, line would be null
            line = br.readLine();

            index++;
        }

    } catch (IOException ex) {
        ex.printStackTrace(System.out);
    }

    return objList;
}

【问题讨论】:

  • 我尝试使用返回类型 List<Object> 在转换后尝试将其解析为 Cat 或 Dog,但它不会让我这样做。到底发生了什么,它不编译吗?
  • @VitalyChura 似乎可以将 Cat 或 Dog 添加到 List<Object>,但之后无法解析为 List<Dog>。 “对象不能转换为狗”。

标签: java spring csv spring-mvc generics


【解决方案1】:

您可以使用 Java 泛型

创建一个 CSV 实用程序类。

public class CsvUtils<T> {

    public List<T> read(final String fileName, final String object) throws IOException {
        
        // put your logic here to read the csv file (convertToObject method)
      
    }

}

然后你可以简单地以这种方式使用它:

    public void doSomeStuffWithMyDogs() throws IOException {
         
         CsvUtils<Dog> csv = new CsvUtils<>();
         List<Dog> myDogs = csvUtils.read("MyDogs_V1.csv", "dog");
      
         // do somthing else

    }

    public void doSomeStuffWithMyCats(final String fileName) throws IOException {
        
         CsvUtils<Cat> csvUtils = new CsvUtils<>();
         List<Cat> myCats = csvUtils.read("MyCats_V1.csv", "cat");
      
         // do somthing else

    }

我的意见:
我不喜欢你的 convertToObject 实现:
1.

//Why are you creating a new instance of Cat here?
Cat cat = new Cat();

// this method is called createCat, so it is supposed to return a object.
createCat(attributes, cat);

objList.add(cat);

方法 createCat 可以返回一个 Cat 对象,并且可以在方法内部创建新的 cat,因此您可以将其从参数中删除。

然后你可以写:

Cat cat = createCat(attributes);
objList.add(cat);

或在一行中:

objList.add(createCat(attributes));
  1. 如果下个月将Horse 添加到项目中,则需要更改实现,添加switch case“horse”,并且还需要实现一个新方法createHorse(String[] attributes, String object)。

想象一下,如果明年,你的项目需要处理所有的动物,你会发疯的。

你需要尽可能的抽象来避免这个问题。 您根本不需要自己实现算法。有很多库可以将 CSV 文件解析为 Java 对象。

例如:(Apache Commons CSV、OpenCSV、SimpleFlatMapper CSV 解析器、jackson-dataformat-csv、uniVocity-parsers、deephaven-csv),但还有更多!

泛型文档:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多