Хотя в целом я не одобряю использование Map
для хранения полей для объекта, если количество свойств велико и может даже варьироваться в разных файлах CSV (например, в некоторых файлах есть университет, в котором учился человек,другое - нет), тогда может быть уместно использовать Map
для хранения свойств.
В этом случае можно определить простой класс Person
:
public class Person {
Map<String, String> props = new HashMap<>();
public void addProperty(String propertyName, String value) {
// could add error checking to ensure propertyName not null/emtpy
props.put(propertyName, value);
}
/**
* returns the value of the property; may return null
*/
public String getProperty(String propertyName) {
return props.get(propertyName);
}
}
Если этоизвестно, что определенные атрибуты / свойства будут всегда загружаться, тогда могут быть добавлены методы доступа, такие как getName()
:
public String getName() {
return props.get("name");
}
public int getAge() {
String age = props.get("age");
// or throw exception if missing
return (age != null ? Integer.parseInt(age) : -1);
}
Хотя обратите внимание, я бы ожидал, что имя не будет единственной записью для большинства наборов данных, так какобычно это фамилия, имя и т. д. Тем не менее шаблон для ограниченного числа обычно ожидаемых значений одинаков.Кроме того, вы можете адаптироваться так, чтобы вы могли получать целочисленные значения непосредственно для некоторых известных полей.
Затем, когда вы анализируете файл, вы сохраняете строку заголовка с определениями атрибутов.Затем для каждой строки, которую вы впоследствии прочитали, вы создаете новый объект Person
, а затем добавляете свойства по порядку.
List<Person> allPersons = new ArrayList<>();
while ( (line = READ_NEXT_LINE) ) {
// NOTE: this is not a safe way to handle CSV files; should really
// use a CSV reader as fields could have embedded commas
attrs[] = line.split(",");
Person p = new Person();
for (int i = 0; i < titleRow.length; ++i) {
p.addProperty(titleRow[i], attrs[i]);
}
allPersons.add(p);
}
Затем можно получить определенный Person
на Person myPerson = allPersons.get(index_of_person)
иво многом схоже с тем, как вы использовали бы Javascript
, вы можете сделать String val = myPerson.getProperty("age")
.
Если вам нужно выполнить поиск по заданному атрибуту, вы можете затем выполнить поток / цикл по allPersons
и проверитьэквивалентность, основанная на данном свойстве.
// find all people of a given age
List<Person> peopleAge20 = allPersons.stream()
.filter(p -> p.getAge() == 20)
.collect(Collectors.toList());
System.out.println(peopleAge20);
// summary statics (average age) for all people
IntSummaryStatistics stats =
allPersons.stream().mapToInt(p -> p.getAge()).summaryStatistics();
System.out.printf("Average age: %f\n", stats.getAverage());
Обратите внимание, что этот подход нарушает идею Javabean
, но это может или не может быть проблемой в зависимости от ваших требований.