I got 3 classes.
- Angestellte (simply contains some stuff like names etc.)
- Department (only contains a String)
- and ttest (for testing obviously)
I want to put all the workers "Angestellte" into their Departments. So basically the output should be:
Personalabteilung: 4
Buchhaltung: 3
Fertigung: 3
I am trying to put the Map as Map with Department and Long but ultimately I would like to have the Map with String and Long.
I also think my Collectors.counting()
doesn't work that way I put it.
I don't really know how to address my Stream of Strings after I have already mapped it. Thats why I put three ? in the code.
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class ttest {
public static void main(String[] args){
Department d1 = new Department("Personalabteilung");
Department d2 = new Department("Buchhaltung");
Department d3 = new Department("Fertigung");
List<Angestellte> AlleAng = Arrays.asList(
new Angestellte("Sandra","Bullock",d3,3450, "Female"),
new Angestellte("Yutta","Knie",d1,2800, "Female"),
new Angestellte("Ludwig","Herr",d3,3850, "Male"),
new Angestellte("Peter","Pan",d2,1850, "Male"),
new Angestellte("Nicky","Smith",d3,2100, "Female"),
new Angestellte("Herbert","Rotwein",d2,2450, "Male"),
new Angestellte("Sandra","Siech",d1,1100, "Female"),
new Angestellte("Florian","Schwarzpeter",d2,2800, "Male"),
new Angestellte("Herrietta","Glas",d1,2100, "Female"),
new Angestellte("Brock","Builder",d1,6000, "Male"));
Map<Department, Long> DepAnz = AlleAng.stream()
.map(a -> a.getDep())
.collect(Collectors.toMap(a.getDep???, Collectors.counting()));
}
}
3 Answers 3
If you want to group by department and your getter is called getDep()
You can do
Map<Department, Long> DepAnz = AlleAng.stream()
.collect(Collectors.groupingBy(a -> a.getDep(), Collectors.counting()));
-
1It's actually
Angestellte::getDep
(without parentheses). Just as an additional explanation: Themap
function will change the type fromStream<Angestellte>
toStream<Department>
. But this can be skipped as explained in the response.Ray– Ray2016年01月26日 12:33:40 +00:00Commented Jan 26, 2016 at 12:33 -
works for me now, but what if i want to go deeper and get the return String vom Department to have a Map<String, Long> ? thx so farTimo N.– Timo N.2016年01月26日 12:38:37 +00:00Commented Jan 26, 2016 at 12:38
-
@TimoN. Which method can you call on the Department to get the String you want?Peter Lawrey– Peter Lawrey2016年01月26日 12:40:45 +00:00Commented Jan 26, 2016 at 12:40
You need to use a group by:
Map<Department, Long> DepAnz =
AlleAng.stream()
.collect(Collectors.groupingBy(Angestellte::getDep, Collectors.counting()));
The groupingBy(classifier, downstream)
collector is a collector that collects the Stream element into a Map
where the keys are returned by the classifier and the values are the result of applying the downstream collector to all Stream elements having an equal key. In this case, what we want is to count the values so we use Collectors.counting()
as the downstream collector.
If you want to group by the the name of the department instead, you could have, assmuming the getter is called .getName()
to retrieve the name:
Map<String, Long> DepAnz =
AlleAng.stream()
.collect(Collectors.groupingBy(a -> a.getDep().getName(), Collectors.counting()));
This will return a count of all the different name of departements.
Map<String, Long> map = AlleAng.stream().collect(Collectors.toMap(a -> a.getDept().getName(), a -> 1L, (Long acc, Long newValue) -> acc + newValue));
This is such a verbose usage of lambdas to achieve what you need. Use a toMap Collector in order to map a specific key and value based on the actual Angestellte references you have got. Of course, the groupers functions are best suited, but this works as a generic example for map grouping by some criterion