简体   繁体   中英

java stream List<Object[]> to Map<Object, List<Object[]>>

I have List<Object[]> inner join MySQL query , I need to create a map key id and value object .

The Code below works, but how to do it best with Streams ?

Map<Object, List<Object[]>> convert(List<Object[]> objects) {
    Map<Object, List<Object[]>> objectListMap = objects.stream()
        .collect(Collectors.toMap(obj -> obj[0], obj -> {
            List<Object[]> list = new ArrayList<>();
            list.add(obj);
            return list;
        }, (obj1, obj2) -> {
            obj1.addAll(obj2);
            return obj1;
        }));
    return objectListMap;
}


Object[] objects structure:
objects[0] = person id
...
objects[10] = event id
...
objects[15] = event name

This query found all the person with the event visited, but the index in the objects array from 0 to 10 may be the same, 11-15 always change.

And I want to merge all object-lists that have the same id (objects[0]).

next for each value in Map > convert to POJO:

PersonWithEvent converToEntity(List<Object[]> objects) {
Optional< PersonWithEvent > personWithEvent =                     
objects.stream()
.findFirst().map(obj -> {
    PersonWithEvent p = new PersonWithEvent();
    p.setId((Integer) obj[0]);
    ...
    return p;
});
personWithEvent.ifPresent(p -> {
    List<PersonEvent> personEvents = objects.stream()
            .map(obj -> {
                PersonEvent pe = new PersonEvent();
                pe.setName((String) obj[2]);
                ...
                return pe;
            })
            .collect(Collectors.toList());
    p.setPersonEvents(personEvents);
 });
 return personWithEvent.get();

And Is it possible to do it for one stream?

It seems you need to group by element at index zero of an array Object

Collectors.groupingBy groups by the key

Map<Object, List<Object[]>> map = objects.stream()
    .collect(Collectors.groupingBy(o -> o[0]));

with null and empty checks

Map<Object, List<Object[]>> map = objects.stream()
    .filter(o -> o != null && o.length != 0)
    .collect(Collectors.groupingBy(o -> o[0]));

Example

List<Object[]> objects = new ArrayList<>();
objects.add(new Object[] { 0, 1, 2, 3, 4, 5 });
objects.add(new Object[] { 1, 1, 2, 3, 4, 5 });
objects.add(new Object[] { 2, 1, 2, 3, 4, 5 });
objects.add(new Object[] { 0, 6, 7, 8, 9 });

Map<Object, List<Object[]>> map = objects.stream()
    .collect(Collectors.groupingBy(o -> o[0]));

System.out.println(map);

output is like

{
    0 = [[Ljava.lang.Object;@378bf509,
            [Ljava.lang.Object;@5fd0d5ae],
    1 = [[Ljava.lang.Object;@2d98a335],
    2 = [[Ljava.lang.Object;@16b98e56]
}

you can see 0 has two List<Object[]> values grouped by

I would make the whole procedure more explicit and clean. Using a mixed-style with lots of comments and good variable names.

This should help a lot when it comes down to reading, understanding and maintaining your code.

Map<Object, List<Object[]>> convert(List<Object[]> entities) {
    Map<Object, List<Object[]>> idToEntitesWithSameId = new HashMap<>();

    entities.forEach(entity -> {
        // Create an entry for each entity,
        // merge with entities of same id
        Object id = entity[0];

        // Get current value or empty list
        List<Object[]> entitiesWithId = idToEntitesWithSameId
            .computeIfAbsent(id, ArrayList::new);

        // Add own entity, merge with other
        // entities of same id
        Arrays.stream(entity).forEach(entitiesWithId::add);
    });

    return idToEntitesWithSameId;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM