Я создал простой конвертер, который берет String fileName и преобразует строки из файла .csv в List<Cat>. Проблема, с которой я столкнулся сейчас, заключается в том, что теперь есть Dog, и мне не разрешено копировать и вставлять метод, чтобы просто изменить тип возвращаемого значения на List<Dog>.
Я пытался использовать возвращаемый тип List<Object>, чтобы попытаться разобрать его на Cat или Dog после преобразования, но он мне не позволяет. Я ищу общее решение этой проблемы, если это возможно.
Что я пробовал:
@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;
}
@VitalyChura Кажется, что можно добавить Cat или Dog в List<Object>, но впоследствии его нельзя проанализировать в List<Dog>. «Объект не может быть преобразован в собаку».




Вы можете использовать Java Generics
Создайте класс утилиты 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> csvUtils = new CsvUtils<>();
List<Dog> myDogs = csvUtils.read("MyDogs_V1.csv", "dog");
// do something else
}
public void doSomeStuffWithMyCats(final String fileName) throws IOException {
CsvUtils<Cat> csvUtils = new CsvUtils<>();
List<Cat> myCats = csvUtils.read("MyCats_V1.csv", "cat");
// do something else
}
Моё мнение:
Мне не нравится ваша реализация convertToObject:
1.
//Why are you creating a new instance of Cat here?
Cat cat = new Cat();
// This method is called createCat...
// Why did you pass an instance of Cat? this will update the cat, not create a new cat.
// It is also supposed to return the cat created.
createCat(attributes, cat);
objList.add(cat);
Метод createCat может возвращать объект Cat, а нового кота можно создать внутри метода, поэтому вы можете удалить его из параметра.
тогда вы можете написать:
Cat cat = createCat(attributes);
objList.add(cat);
или в одну строку:
objList.add(createCat(attributes));
2.
если в следующем месяце вы добавите лошадь в проект, вам нужно будет изменить реализацию, добавив регистр переключения «лошадь», а также вам необходимо реализовать новый метод createHorse (атрибуты String [], объект String).
Представьте, если в следующем году в вашем проекте нужно будет обрабатывать всех животных, вы сойдете с ума.
Вам нужно максимально абстрагироваться, чтобы избежать этой проблемы. Вам вовсе не обязательно реализовывать алгоритм самостоятельно. Существует множество библиотек, которые преобразуют файл CSV в объект Java.
Например: (Apache Commons CSV, OpenCSV, парсер CSV SimpleFlatMapper, jackson-dataformat-csv, uniVocity-parsers, deephaven-csv), но есть и многие другие!
Документация для дженериков:
Я пытался использовать тип возвращаемого значения List<Object>, чтобы попытаться проанализировать его в Cat или Dog после преобразования, но это не позволит мне. Что именно происходит, не компилируется?