Eu tenho uma estrutura de dados como abaixo. Estou tentando agrupar os objetos de tal forma como Map<String, List<String>>
onde chave é a EntryId e valor é a lista de grupos a que pertence. EntryId é sempre único dentro de um grupo.
Exemplo: EntryId "1111" pertence ao Grupo 1, Grupo 2, Grupo 3. Eu estou usando a velha maneira java 7 para percorrer as listas e verificação. Existe alguma melhor maneira possível, utilizando coletores Java8 / agrupamento para alcançar este objectivo.
List<Group>
onde cada objeto Grupo terá uma lista de objetos de entrada.
[
{
"id":"group1",
"entries":[
{
"entryId":"1111",
"name":"test1"
},
{
"entryId":"2222",
"name":"test2"
},
{
"entryId":"3333",
"name":"test3"
}
]
},
{
"id":"group2",
"entries":[
{
"entryId":"4444",
"name":"test1"
},
{
"entryId":"1111",
"name":"test2"
},
{
"entryId":"2222",
"name":"test3"
}
]
},
{
"id":"group3",
"entries":[
{
"entryId":"1111",
"name":"test1"
},
{
"entryId":"5555",
"name":"test2"
},
{
"entryId":"3333",
"name":"test3"
}
]
}
]
Assim, o esperado posto para fora é esta:
[
{
"1111":[
"group1",
"group2",
"group3"
]
},
{
"2222":[
"group1",
"group2"
]
},
{
"3333":[
"group1",
"group3"
]
},
{
"4444":[
"group2"
]
},
{
"5555":[
"group3"
]
}
]
Eu estou usando abaixo maneira atualmente. que está trabalhando como esperado, mas há uma maneira muito mais simples em Java 8 posso conseguir isso.
public Map<String, List<String>> mapEntries(List<Group> groups) {
Map<String, List<String>> entryMaps = new HashMap<>();
for (Group group : groups) {
for (Entry entry : group.getEntries()) {
List<String> groupsEntryBelongs = new ArrayList<>();
if (groups.iterator().hasNext() && !entryMaps.keySet().contains(entry.getEntryId())) {
updateGroups(groups, entry.getEntryId(), groupsEntryBelongs, entryMaps);
}
}
}
return entryMaps;
}
void updateGroups(List<Group> groups, String id, List<String> groupsEntryBelongs, Map<String, List<String>> entryMaps) {
for (Group group : groups) {
for (Entry entry : group.getEntries()) {
if (entry.getEntryId().equalsIgnoreCase(id)) {
groupsEntryBelongs.add(group.getId());
}
}
}
entryMaps.put(id, groupsEntryBelongs);
}
Você pode fazê-lo da seguinte forma:
Map<String, Set<String>> entryMaps = new LinkedHashMap<>();
groups.forEach(group ->
group.getEntries().forEach(entry ->
entryMaps.computeIfAbsent(
entry.getEntryId().toLowerCase(),
k -> new LinkedHashSet<>())
.add(group.getId())));
Isso repete os grupos, em seguida, entradas e usos de cada grupo Map.computeIfAbsent
para colocar uma entrada com um novo e vazio LinkedHashSet
se a chave não estava presente, retornando quer este conjunto vazio ou a um correspondente que chave. Em seguida, o ID de grupo é adicionado a este conjunto retornado.
Nota: eu estou usando um Set
em vez de um List
para valores, para evitar possíveis duplicatas. E LinkedHashMap
e LinkedhashSet
garantia de inserção de ordem.