Java 8 Lambdas Group List into Map

Java 8 lambdas group list into map

Use the simple groupingBy variant:

Map<String, List<Pojo>> map = pojos
.stream()
.collect(
Collectors.groupingBy(Pojo::getKey)
);

Java 8 lambdas group list into map - different key if more than one list item per key

You can try using collectingAndThen with groupingBy as downstream as :

private Map<String, List<RelationShip>> groupAndMapRelationships(List<RelationShip> relationShips) {
return relationShips.stream()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(RelationShip::getRelationshipType),
map -> map.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(
e.getValue().size() == 1 ?
e.getKey().getRelationship() : e.getKey().getRelationshipPlural(),
e.getValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))));
}

where the minimal POJOs I'd considered would look like :

@Getter
class RelationShip {
String personA;
String personB;
RelationshipType relationshipType;
}

@Getter
class RelationshipType {
String relationship;
String relationshipPlural;
}

Java 8 ListV into MapK, V

Based on Collectors documentation it's as simple as:

Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(Choice::getName,
Function.identity()));

Grouping and summing a list into a map using Lambda

Collectors.groupingBy Allows you to reduce a list to a map where the key is some manipulation of the list's element and the value is some aggregate function applied to a manipulation of the element.
In your case, you could use something like this:

SimpleDateFormat monthFormatter = new SimpleDateFormat("MMM");
Map<String, Double> moveMap =
moveTracking.stream()
.collect(Collectors.groupingBy
(m -> monthFormatter.format(m.getTime()),
Collectors.summingDouble(MoveTrack::getMovementAmount)));

Grouping by List of Map in Java 8

You need to flatMap the entry set of each Map to create a Stream<Map.Entry<String, Long>>. Then, this Stream can be collected with the groupingBy(classifier, downstream) collector: the classifier returns the key of the entry and the downstream collector maps the entry to its value and collects that into a List.

Map<String, List<Long>> map = 
list.stream()
.flatMap(m -> m.entrySet().stream())
.collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));

This code needs the following static imports:

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;

With your full example:

public static void main(String[] args) {
Map<String, Long> m1 = new HashMap<>();
m1.put("A", 1l);
m1.put("B", 100l);

Map<String, Long> m2 = new HashMap<>();
m2.put("A", 10l);
m2.put("B", 20l);
m2.put("C", 100l);

List<Map<String, Long>> beforeFormatting = new ArrayList<>();
beforeFormatting.add(m1);
beforeFormatting.add(m2);

Map<String, List<Long>> afterFormatting =
beforeFormatting.stream()
.flatMap(m -> m.entrySet().stream())
.collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));

System.out.println(afterFormatting); // prints {A=[1, 10], B=[100, 20], C=[100]}
}

Java Streams group list entries based on a property but collect a property of object in Map

Use Collectors.mapping:

Map<String, List<Project>> res = results
.stream()
.collect(Collectors.groupingBy(
Detail::getTitle,
Collectors.mapping(Detail::getProject, Collectors.toList())));

Group a List of HashMaps to a list of HashMaps based on a key java streams

Basically if Map contains key x then do a group by based on value

  List<List<Map<String, String>>> result =  l.stream()
.filter(m->m.containsKey("x")) // filter map with `x` key
.collect(Collectors.groupingBy(m->m.get("x").split("#")[1])) // if map contains `x` as key then group by the value after `#`
.entrySet().stream()
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder())) //sort on requirement
.map(Entry::getValue)
.collect(Collectors.toList());

output

[[{x=bbb#123, y=asasdfaff, z=2sadada22}], [{x=aaa#123, y=saadaad, z=7asasada89}], [{x=bbb#000, y=asasadafa, z=daasaada}]]

Java 8, Lambda: Sorting within grouped Lists and merging all groups to a list

If I get you right, you want a List<Student> (not a map) where students are grouped by their locations and sorted by ids inside groups and where groups are also sorted by ids, not by location names. This is possible, but requires one grouping and two sortings:

//first, use your function to group students
Map<String, List<Student>> studlistGrouped = students.stream()
.collect(Collectors.groupingBy(Student::getLocation, Collectors.toList()));

//then sort groups by minimum id in each of them
List<Student> sorted = studlistGrouped.entrySet().stream()
.sorted(Comparator.comparing(e -> e.getValue().stream().map(Student::getId).min(Comparator.naturalOrder()).orElse(0)))
//and also sort each group before collecting them in one list
.flatMap(e -> e.getValue().stream().sorted(Comparator.comparing(Student::getId))).collect(Collectors.toList());

This will produce following:

Student{id='1726', name='John', location='New York'}
Student{id='3442', name='Mark', location='New York'}
Student{id='5223', name='Michael', location='New York'}
Student{id='2234', name='Andrew', location='Los Angeles'}
Student{id='4321', name='Max', location='California'}
Student{id='7765', name='Sam', location='California'}

Maybe this can be done more elegantly, suggestions are welcome

EDIT: At the time this answer was written there was no mention about Grouping based on the order of the Elements in the origin List in the OPs question. So my assumption was to sort both list and groups by ids. For solutions based on the order in the original list see other answers, for example, the Holgers one

Java 8 Lambda List to MapInt, ListString

There is a dedicated version of groupingBy() for your use case:

Map<Integer, List<String>> result = customerSuperUserList.stream()
.collect(Collectors.groupingBy(
UserBasicInfoDto::getUserSeqId,
Collectors.mapping(UserBasicInfoDto::getAcctAgencyNumber, toList())));

The key point of this is to use the helper mapping collector, using which you can override the default groupingBy behaviour.

Mapping a list to Map Java 8 stream and groupingBy

You could do it like this:

Map<String, List<String>> library = 
books.stream()
.flatMap(b -> b.getAttribute().entrySet().stream())
.collect(groupingBy(Map.Entry::getKey,
mapping(Map.Entry::getValue, toList())));

From the Stream<Book>, you flat map it with the stream of each map it contains so that you have a Stream<Entry<String, String>>. From there you group the elements by the entries' key and map each entry to its value that you collect into a List for the values.



Related Topics



Leave a reply



Submit