简体   繁体   English

java流列表 <Object[]> 到地图 <Object, List<Object[]> &gt;

[英]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 . 我有List<Object[]>内连接MySQL查询 ,我需要创建一个map key id和value 对象

The Code below works, but how to do it best with Streams ? 下面的代码有效,但如何最好地使用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. 此查询找到所有访问过该事件的人,但对象数组中从0到10的索引可能相同,11-15总是更改。

And I want to merge all object-lists that have the same id (objects[0]). 我想合并所有具有相同id(对象[0])的对象列表。

next for each value in Map > convert to POJO: Map中的每个值的下一个>转换为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 看来你需要在数组Object索引零处按元素分组

Collectors.groupingBy groups by the key Collectors.groupingBy按键分组

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 你可以看到0有两个List<Object[]>值分组

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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