If you are looking for a ready-to-use data structure which stores elements with counts, then Guava's Multiset
does exactly that.
If you just need to convert a list to a map of counts, please read on.
You can convert a list to a map of counts in a single statement using Java 8 Streams API:
final var list = List.of("12345", "34578", "12345", "98710", "12345");
final var counts = list.stream()
.collect(Collectors.toMap(
Function.identity(), // Map keys are list elements
value -> 1, // Map values are counts, a single item counts "1"
(count1, count2) -> count1 + count2 // On duplicate keys, counts are added
));
Under the hood, this solution uses a hash map (elements to counts) as a data structure.
You may also use the groupingBy
collector, as Peter Lawrey kindly suggested:
final var list = List.of("12345", "34578", "12345", "98710", "12345");
final var counts = list.stream()
.collect(Collectors.groupingBy(
Function.identity(), // Group the elements by equality relation
Collectors.counting() // Map values are counts of elements in the equality groups
));
Sometimes (while learning) it's beneficial to implement everything "by hand" to understand the algorithms. So here a version without Java 8 goodies like streams, collectors and new map methods like Map.compute()
:
final List<Stream> list = List.of("12345", "34578", "12345", "98710", "12345"); // Use ArrayList if you're below Java 9
final Map<String, Integer> counts = new HashMap<>();
for (final String item : list) {
// Note: I'm deliberately NOT using Map.compute() here
// to demonstrate how to do everything "manually"
Integer count = counts.get(item);
if (count == null) {
count = 0;
}
counts.put(item, count + 1);
}