Я бы сначала десериализовал JSON в List
людей. После этого я бы сгруппировал их по имени.
Main. java
package q61078696;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
try {
List<Person> people = loadJSON("q61078696/people.json", Person.class);
Map<String, List<Person>> groupedByName = people.stream()
.collect(Collectors.groupingBy(Person::getName));
System.out.println(groupedByName);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String loadJSON(String resourceName) {
InputStream is = Main.class.getClassLoader().getResourceAsStream(resourceName);
String jsonString = null;
try (Scanner scanner = new Scanner(is, StandardCharsets.UTF_8.name())) {
jsonString = scanner.useDelimiter("\\A").next();
}
return jsonString;
}
public static <E> List<E> loadJSON(String resourceName, Class<E> clazz) throws IOException {
ObjectMapper mapper = new ObjectMapper();
String jsonString = loadJSON(resourceName);
CollectionType typeReference = TypeFactory.defaultInstance().constructCollectionType(List.class, clazz);
return mapper.readValue(jsonString, typeReference);
}
}
Выход
{Tom=[{ "name": "Tom", "age": 28 }], Bob=[{ "name": "Bob", "age": 42 }, { "name": "Bob", "age": 21 }], Mary=[{ "name": "Mary", "age": 35 }]}
Person. java
package q61078696;
public class Person {
private String name;
private int age;
public Person() {
this(null, 0);
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return String.format("{ \"name\": \"%s\", \"age\": %d }", this.name, this.age);
}
}
чел. json
[
{ "name" : "Bob", "age" : 42 },
{ "name" : "Bob", "age" : 21 },
{ "name" : "Mary", "age" : 35 },
{ "name" : "Tom", "age" : 28 }
]
Зависимости
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
Дополнительная информация
Если вы хотите отобразить по имени и избежать группировки (игнорируя дублирования) .
Это выдаст IllegalStateException
, потому что есть дубликаты ключей, чтобы избежать этого, вам нужно будет получить доступ к карте.
Map<String, Person> groupedByName = people.stream()
.collect(Collectors.toMap(Person::getName, Function.identity()));
Вы можете избежать этого, указав mergeFunction
Map<String, Person> groupedByName = people.stream()
.collect(Collectors.toMap(
Person::getName, // keyMapper
Function.identity(), // valueMapper
(o1, o2) -> o1, // mergeFunction (keep the first occurrence)
TreeMap::new) // mapSupplier
);
Вы также можете указать supplier
в 4-м параметре. Я выбрал TreeMap
, чтобы сохранить имена ключей в порядке.
См .: https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap - java .util.function.Function- java .util.function.Function- java .util.function.BinaryOperator-