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
Why Does 'Java -Version' Go to Stderr
Pageloadtimeout in Selenium Not Working
What Are the Best Use Cases for Akka Framework
Java's Date(...) Constructor Is Deprecated; What Does That Mean
In Which Case Do You Use the JPA @Jointable Annotation
Understanding Spring @Configuration Class
Charsequence VS String in Java
How to Use Mdc with Thread Pools
Javamail API to Imail -- Java.Net.Socketexception: Permission Denied: Connect
Does Java Support Let's Encrypt Certificates
Mockito: Invaliduseofmatchersexception
What Is Java Pojo Class, Java Bean, Normal Class
Exception in Thread "Main" Java.Util.Nosuchelementexception
How to Tell Jackson to Ignore a Property for Which I Don't Have Control Over the Source Code