I have a large list of items that I need to convert into a map of items of same type:
List<Item> items = //10^6 items of different types
Map<Type, List<Item>> itemsByType = new ConcurrentHashMap<>();
for (Item item : items) {
itemsByType.computeIfAbsent(
item.getType(),
i -> new ArrayList<>()
).add(item);
}
Each type is then ordered by long
type identifier; and, each list of type-items is ordered by long
item identifier. And, finally, the ordered list is processed.
This works fine, but I'm wondering if there's a more efficient way to do all of this...?
You can use java-8 groupingBy
Map<Type, List<Item>> itemsByType = items.stream()
.sorted(Comparator) //for any sorting you can use sorted with comparator
.collect(Collectors.groupingBy(Item::getType));
If you want ConcurrentHashMap
you can use groupingByConcurrent
ConcurrentMap<Type, List<Item>> itemsByType = items.stream()
.collect(Collectors.groupingByConcurrent(Item::getType));
You can use the overloaded groupingBy with TreeMap
so the map is already sorted based on key
TreeMap<Type, List<Item>> map = list
.stream()
.collect(Collectors.groupingBy(
Item::Type,
() -> new TreeMap<>(Comparator.comparingLong(Type::getId)),
Collectors.toList()));
You can also collect the map with sorted keys and sorted values in one chain
Map<Type, List<Item>> str = list1.stream()
.collect(
Collectors.groupingBy(
Item::Type,
() -> new TreeMap<>(Comparator.comparingLong(Type::getId)),
Collectors.collectingAndThen(
Collectors.toList(),
list -> list.stream()
.sorted(Comparator.comparingLong(Item::getId))
.collect(Collectors.toList()))));
You could use a MultiMap
, eg, guava's . Here is their code example:
ListMultimap<String, String> multimap = ArrayListMultimap.create();
for (President pres : US_PRESIDENTS_IN_ORDER) {
multimap.put(pres.firstName(), pres.lastName());
}
for (String firstName : multimap.keySet()) {
List<String> lastNames = multimap.get(firstName);
out.println(firstName + ": " + lastNames);
}
... produces output such as:
Zachary: [Taylor]
John: [Adams, Adams, Tyler, Kennedy] // Remember, Quincy!
George: [Washington, Bush, Bush]
Grover: [Cleveland, Cleveland] // Two, non-consecutive terms, rep'ing NJ!
...
A TreeMultimap
has sorted keys and values, which is what you want, if I understood your title correctly.
A Multimap is particularly useful in case you need to check if a certain value is present for a certain key, because that is supported without getting the collection for the key and then searching that:
multimap.containsEntry("John", "Adams");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.