3

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?

Stefan Zobel
3,2227 gold badges32 silver badges41 bronze badges
asked Nov 28, 2017 at 3:00
3
  • Can you explain the desired structure a bit? It's not that easy to tell from your code. How do you plan to convert the List<Object[]>? What are the keys and what the values for the map? What is the merge function supposed to do? Commented Nov 28, 2017 at 3:36
  • Am I correct that each Object[] array has an id at index 0 and you want to map this id to the rest whole array like objects[0] => objects. And additionally you want to merge all object-lists that have the same id (objects[0]). Commented Nov 28, 2017 at 3:46
  • yes, And I want to merge all object-lists that have the same id (objects[0]). Commented Nov 28, 2017 at 3:57

2 Answers 2

3

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

answered Nov 28, 2017 at 4:11
Sign up to request clarification or add additional context in comments.

4 Comments

Collectors#groupingBy is actually a nice and clean approach. Never worked with it before but it seems worth to learn.
You may consider using the filter .filter(Objects::nonNull) for removing null values. Just in case you didn't know that method.
@Zabuza yes but we need to filter empty arrays as well right here
@alex please vote and accept this answer if it answers your question
0

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;
}
answered Nov 28, 2017 at 4:14

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.