[英]How to store arraylist of LinkedHashMap as value of LinkedHashMap in java
[英]How do sort Entries of the Map<Type,List<String>> by Value and store into a LinkedHashMap
我有以下Item
class:
@AllArgsConstructor
@Getter
public static class Item {
public enum Type { Meat, Fish }
private String name;
private int price;
private Type type;
}
並且有一個項目List
,如下所示:
List<Item> menu = Arrays.asList(
new Item("pork" 800, Item.Type.Meat),
new Item("beef" 700, Item.Type.Meat),
new Item("chicken", 200, Item.Type.meat),
new Item("prawns" 300, Item.Type.Fish),
new Item("salmon", 450, Item.Type.Fish)
);
我需要按Type
對Item
進行分組並存儲到 map 中。
然后我需要按升序對map 條目按Value (在本例中是String
的List
)進行排序並存儲到LinkedHashMap
。
如何根據List<String>
值對map 條目進行排序?
我的代碼:
// grouping items by type
Map<Item.Type, List<String>> map = menu.stream()
.collect(Collectors.groupingBy(
Item:: getType,
Collectors.mapping(Item::getName, Collectors.toList())
));
// a LinkedHashMap to store sorted entries
Map<Item.Type, List<String>> hmap = new LinkedHashMap<>();
// attempting to sort map entries by value and put them
// into the resulting map
map.entrySet().stream()
.sorted(Map.Entry.<Item.Type, List<String>> comparingByValue())
.forEachOrdered(e -> hmap.put(e.getKey(), e.getValue()));
但我得到一個編譯錯誤:
Type parameter 'java.util.List' is not within its bound;
should extend 'java.lang.Comparable<? super java.util.List>'
我認為原因是因為我想要排序的 map 中有一個字符串列表。
當我只有一個String
作為值時(不是List<String>
)。 該代碼運行良好。
Collections 都沒有實現Comparable
接口。 這沒有任何意義,因為它們是數據的容器,如果您需要對數據進行排序,您將在能夠維護順序的集合中對其進行排序。 當您需要對 collections 進行排序時 - 這是一項奇怪的任務。
我說的很奇怪,因為像List
這樣的 collections 不知道如何比較它們的元素,這意味着元素的可比性不是強制性的,並且在實例化列表時不能提供比較器。 因此,不可能為List
建立自然順序,換句話說,列表不“知道”如何與另一個列表進行比較。
您需要為此目的定義一個自定義Comparator
器。
當我只有一個
String
作為值時(不是List<String>
)。 該代碼運行良好。
假設您希望比較您的字符串列表,就好像它們中的每一個都是單個字符串一樣(我們稱之為比較鍵),那么提前生成這樣的字符串並將每個Type
的項目與比較相關聯是明智的關鍵(如果您有不同的比較策略 - 然后相應地調整代碼)。
比較鍵可以在現場(在流中)生成,但它會導致多次重新創建相同的字符串。 在這種情況下,這不是一個大問題,因為Item.Type
是一個枚舉,因此對應於每個枚舉常量的字符串比較鍵的數量是有限的,但提前准備好它們並沒有什么壞處。
List<Item> menu = Arrays.asList(
new Item("pork", 800, Item.Type.Meat),
new Item("beef", 700, Item.Type.Meat),
new Item("chicken", 200, Item.Type.Meat),
new Item("prawns", 300, Item.Type.Fish),
new Item("salmon", 450, Item.Type.Fish)
);
Map<Item.Type, List<String>> itemNamesByType = menu.stream()
.collect(Collectors.groupingBy(
Item:: getType,
Collectors.mapping(Item::getName, Collectors.toList())
));
// generating Comparison Keys for every Type
Map<Item.Type, String> comparisonKeyByType = itemNamesByType.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> String.join("", entry.getValue())
));
Map<Item.Type, List<String>> itemNamesByTypeSorted = itemNamesByType.entrySet().stream()
.sorted(Map.Entry.comparingByKey(
Comparator.comparing(comparisonKeyByType::get)
))
.collect(Collectors.toMap(
Map.Entry::getKey, // keyMapper
Map.Entry::getValue, // valueMapper
(left, right) -> { throw new AssertionError("duplicates not expected"); }, // since the source is an entry set - there shouldn't be duplicate keys (but we need to provide this argument in order to be able to use version of toMap() which allows to provide a mapFactory
LinkedHashMap::new // mapFactory
));
itemNamesByTypeSorted.forEach((k, v) -> System.out.println(k + " -> " + v));
Output:
Meat -> [pork, beef, chicken]
Fish -> [prawns, salmon]
只需實現可用的列表方法
public static void main(String[] args) {
Map<String, List<String>> hmap = new LinkedHashMap<>();
List<String> values = new ArrayList<>();
values.add("d");
values.add("a");
values.add("g");
hmap.put("1", values);
hmap.put("2", values);
System.out.println(hmap); // --> {1=[d, a, g], 2=[d, a, g]}
for(Map.Entry<String,List<String>> entry: hmap.entrySet()){
entry.getValue().sort(Comparator.naturalOrder());
}
System.out.println(hmap); // --> {1=[a, d, g], 2=[a, d, g]}
}
public static void main(String[] args) {
final List menu = Arrays.asList(
new Dish("pork", 800, "Meat"),
new Dish("beef", 700, "Meat"),
new Dish("chicken", 200, "Meat"),
new Dish("prawns", 300, "Fish"),
new Dish("salmon", 450, "Fish"));
Map<String, List<Dish>> hmap = new LinkedHashMap<>();
hmap.put("1", menu);
hmap.put("2", menu);
System.out.println(hmap); // --> {1=[Dish{name='pork', price=800, type='Meat'}, Dish{name='beef', price=700, type='Meat'}, Dish{name='chicken', price=200, type='Meat'}, Dish{name='prawns', price=300, type='Fish'}, Dish{name='salmon', price=450, type='Fish'}], 2=[Dish{name='pork', price=800, type='Meat'}, Dish{name='beef', price=700, type='Meat'}, Dish{name='chicken', price=200, type='Meat'}, Dish{name='prawns', price=300, type='Fish'}, Dish{name='salmon', price=450, type='Fish'}]}
for (Map.Entry<String, List<Dish>> entry : hmap.entrySet()) {
entry.getValue().sort(Comparator.comparing(Dish::getName));
}
System.out.println(hmap); // --> {1=[Dish{name='beef', price=700, type='Meat'}, Dish{name='chicken', price=200, type='Meat'}, Dish{name='pork', price=800, type='Meat'}, Dish{name='prawns', price=300, type='Fish'}, Dish{name='salmon', price=450, type='Fish'}], 2=[Dish{name='beef', price=700, type='Meat'}, Dish{name='chicken', price=200, type='Meat'}, Dish{name='pork', price=800, type='Meat'}, Dish{name='prawns', price=300, type='Fish'}, Dish{name='salmon', price=450, type='Fish'}]}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.