#java #jackson
#java #jackson
Вопрос:
Возможно, это самый глупый вопрос на всем сайте. Я новичок в Java и JSON, и мне нужна помощь. Я использую API Jackson. Программа получает файл JSON. Из него мне нужно получить:
- Список людей в возрасте от 20 до 30 лет, отсортированных по имени
- Уникальный список городов;
- Количество людей с возрастным интервалом 0-10, 11-20, 21-30 и так далее.
На данный момент я узнал, как перевести файл json в список java
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
List<Data> data = Arrays.asList(mapper.readValue(Paths.get("C:\data.json").toFile(), Data[].class));
System.out.println(data);
} catch (JsonParseException jsonParseException) {
jsonParseException.printStackTrace();
} catch (JsonMappingException jsonMappingException) {
jsonMappingException.printStackTrace();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
Был создан класс для чтения файла json
public class Data {
private int id;
private String firstName;
private String lastName;
private String dateOfBirth;
private String city;
public Data(int id, String firstName, String lastName, String dateOfBirth, String city) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
this.city = city;
}
public Data() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "[id = " id ", firstName = " firstName ", lastName = " lastName ", dateOfBirth = " dateOfBirth ", city = " city "]";
}
}
Файл Json выглядит следующим образом
[
{
"id": "1",
"firstName": "Lesley",
"lastName": "Bryan",
"dateOfBirth": "11/28/61",
"city": "Southampton–Portsmouth"
},
{
"id": "2",
"firstName": "Edward",
"lastName": "Houston",
"dateOfBirth": "10/5/92",
"city": "Southampton–Portsmouth"
},
{
"id": "3",
"firstName": "Donald",
"lastName": "Ross",
"dateOfBirth": "12/10/79",
"city": "Glasgow"
},
{
"id": "4",
"firstName": "Peter",
"lastName": "Kelly",
"dateOfBirth": "3/17/04",
"city": "Birmingham–Wolverhampton"
},
{
"id": "5",
"firstName": "Anthony",
"lastName": "McKinney",
"dateOfBirth": "3/6/68",
"city": "Liverpool"
},
{
"id": "6",
"firstName": "David",
"lastName": "Stewart",
"dateOfBirth": "4/11/73",
"city": "Leeds–Bradford"
},
{
"id": "7",
"firstName": "Christopher",
"lastName": "Austin",
"dateOfBirth": "12/28/74",
"city": "Birmingham–Wolverhampton"
},
{
"id": "8",
"firstName": "Alvin",
"lastName": "Hodge",
"dateOfBirth": "11/25/58",
"city": "Newcastle upon Tyne–Sunderland"
},
{
"id": "9",
"firstName": "Gerald",
"lastName": "Higgins",
"dateOfBirth": "6/28/55",
"city": "Liverpool"
},
{
"id": "10",
"firstName": "Amos",
"lastName": "Owens",
"dateOfBirth": "1/16/01",
"city": "Manchester-Salford"
},
{
"id": "11",
"firstName": "Christian",
"lastName": "Bishop",
"dateOfBirth": "11/14/50",
"city": "Nottingham"
},
{
"id": "12",
"firstName": "Robert",
"lastName": "Caldwell",
"dateOfBirth": "12/8/80",
"city": "Manchester-Salford"
},
{
"id": "13",
"firstName": "Brian",
"lastName": "Heath",
"dateOfBirth": "9/23/02",
"city": "Newcastle upon Tyne–Sunderland"
},
{
"id": "14",
"firstName": "Mark",
"lastName": "Anthony",
"dateOfBirth": "1/8/92",
"city": "London"
},
{
"id": "15",
"firstName": "Mark",
"lastName": "Watson",
"dateOfBirth": "7/27/91",
"city": "Nottingham"
},
{
"id": "16",
"firstName": "Charles",
"lastName": "Stafford",
"dateOfBirth": "1/26/90",
"city": "Birmingham–Wolverhampton"
},
{
"id": "17",
"firstName": "Steven",
"lastName": "Merritt",
"dateOfBirth": "12/4/63",
"city": "Leeds–Bradford"
},
{
"id": "18",
"firstName": "John",
"lastName": "Holmes",
"dateOfBirth": "4/22/52",
"city": "Southampton–Portsmouth"
},
{
"id": "19",
"firstName": "Mervin",
"lastName": "Lewis",
"dateOfBirth": "10/27/95",
"city": "Birmingham–Wolverhampton"
},
{
"id": "20",
"firstName": "Peter",
"lastName": "Marsh",
"dateOfBirth": "12/10/63",
"city": "Glasgow"
},
{
"id": "21",
"firstName": "Piers",
"lastName": "Harrington",
"dateOfBirth": "4/27/85",
"city": "London"
},
{
"id": "22",
"firstName": "Matthew",
"lastName": "O’Brien’",
"dateOfBirth": "1/19/59",
"city": "Manchester-Salford"
}
]
Пожалуйста, скажите мне, в какой последовательности действий выполнить задачу. Еще раз прошу прощения за такое глупое сообщение.
P.S.: Все имена, фамилии и даты из файла json были получены случайным образом.
Ответ №1:
Во-первых, вам необходимо обновить Data
класс, чтобы облегчить обработку возрастов и возрастных групп:
- Измените тип
dateOfBirth
toLocalDate
, обновите конструктор / getter / предоставьте пользовательский сеттер для обработки дат в 20-м веке - Добавьте методы для получения возраста в годах и возрастной группы в виде строки:
- Обновление
toString
до возраста печати
class Data {
// ...
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "M/d/yy")
private LocalDate dateOfBirth;
public LocalDate getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(LocalDate dob) {
if (dob.isAfter(LocalDate.now())) {
dob = dob.minusYears(100);
}
this.dateOfBirth = dob;
}
@JsonIgnore
public int getAge() {
return Period.between(dateOfBirth, LocalDate.now()).getYears();
}
@JsonIgnore
public String getAgeGroup() {
int age = getAge();
if (age < 11) {
return "0..10";
}
return (age/10*10 1) ".." ((age/10 1) * 10);
}
@Override
public String toString() {
return "[id = " id ", age=" getAge() ", firstName = " firstName ", lastName = " lastName ", dateOfBirth = " dateOfBirth ", city = " city "]";
}
}
Затем вы можете получить требуемые подмножества данных из входного списка:
// get people aged from 20 to 30 sorted by last name/first name
List<Data> age20to30 = data
.stream()
.filter(p -> p.getAge() >= 20 amp;amp; p.getAge() < 30)
.sorted(Comparator.comparing(p -> p.getLastName() " " p.getFirstName()))
.collect(Collectors.toList());
age20to30.forEach(System.out::println);
// get sorted list of unique cities (using TreeSet as a SortedSet)
Set<String> cities = data
.stream()
.map(Data::getCity)
.collect(Collectors.toCollection(TreeSet::new));
cities.forEach(System.out::println);
// get stats by age groups
Map<String, Long> byAges = data
.stream()
.collect(Collectors.groupingBy(Data::getAgeGroup, TreeMap::new, Collectors.counting()));
System.out.println(byAges);
Вывод
[id = 14, age=28, firstName = Mark, lastName = Anthony, dateOfBirth = 1992-01-08, city = London]
[id = 2, age=27, firstName = Edward, lastName = Houston, dateOfBirth = 1992-10-05, city = Southampton–Portsmouth]
[id = 19, age=24, firstName = Mervin, lastName = Lewis, dateOfBirth = 1995-10-27, city = Birmingham–Wolverhampton]
[id = 15, age=29, firstName = Mark, lastName = Watson, dateOfBirth = 1991-07-27, city = Nottingham]
Birmingham–Wolverhampton
Glasgow
Leeds–Bradford
Liverpool
London
Manchester-Salford
Newcastle upon Tyne–Sunderland
Nottingham
Southampton–Portsmouth
{11..20=3, 21..30=4, 31..40=3, 41..50=3, 51..60=4, 61..70=5}
Комментарии:
1. Не удается создать экземпляр
com.testsample.Data
(не существует создателей, подобных конструктору по умолчанию): не удается выполнить десериализацию из значения объекта (нет создателя на основе делегата или свойства) в [Источник: (Файл); строка: 3, столбец: 3] (через цепочку ссылок: java.lang. Объект [][0])2. Похоже, существует проблема со структурой файла JSON. Я дважды проверил синтаксический анализ данных, приведенных выше, в виде строки и внутри файла, и он работал нормально.