英文:
Java-8 Streams: Convert List<{String,List<String>}> to Map<String, List<String>>
问题
import java.util.*;
class Tag {
private String tagName;
private List<String> items;
// Constructor, getters, and setters
}
public class Main {
public static void main(String[] args) {
List<Tag> tagList = Arrays.asList(
new Tag("popular", Arrays.asList("Item1", "Item2", "Item3", "Item4")),
new Tag("expensive", Arrays.asList("Item2", "Item4", "Item5")),
new Tag("mostwanted", Arrays.asList("Item1", "Item2", "Item5"))
);
Map<String, List<String>> resultMap = new HashMap<>();
for (Tag tag : tagList) {
for (String item : tag.getItems()) {
resultMap.computeIfAbsent(item, k -> new ArrayList<>()).add(tag.getTagName());
}
}
System.out.println(resultMap);
}
}
Note: The code above assumes you have a proper constructor, getters, and setters for the Tag
class. Also, please make sure to import the necessary packages (java.util.*
) to use the required classes and interfaces.
英文:
I have a Tag class which contains a list of Items
class Tag {
private String tagName
private List<String> items
}
I have a list of Tags in which each tag a list of items
List<Tag> tagList = [
{"tagName": "popular", "items": ["Item1","Item2","Item3","Item4"]},
{"tagName": "expensive" , "items": ["Item2","Item4","Item5"]},
{"tagName": "mostwanted", "items": ["Item1","Item2","Item5"]}
]
I wan to convert this to a map which have the items as key and tagName as values.
expected output :
{
"Item1" : ["popular","mostwanted"],
"Item2" : ["popular","expensive","mostwanted"],
"Item3" : ["popular","mostwanted"],
"Item4" : ["popular","expensive"],
"Item5" : ["expensive","mostwanted"]
}
I tried various combination of stream/faltmap/groupingBy, but I didnt get the expected output. Can you please help. Thanks
答案1
得分: 2
你可以使用 flatMap
将 items
展开,然后使用 SimpleEntry
创建 item
和 tagName
的配对。然后使用 groupingBy
按 item
进行分组,将 tagName
映射为 tagName
列表。
Map<String, List<String>> tagMap = tagList.stream()
.flatMap(t -> t.getItems()
.stream()
.map(item -> new AbstractMap.SimpleEntry<>(item, t.getTagName())))
.collect(Collectors.groupingBy(m -> m.getKey(),
Collectors.mapping(m -> m.getValue(), Collectors.toList())));
英文:
You can flat the items
using flatMap
then create pair of item
and tagName
using SimpleEntry
. Then grouping by item
using groupingBy
and map tagName
to get list of tagName
Map<String, List<String>> tagMap = tagList.stream()
.flatMap(t -> t.getItems()
.stream()
.map(item -> new AbstractMap.SimpleEntry<>(item, t.getTagName())))
.collect(Collectors.groupingBy(m -> m.getKey(),
Collectors.mapping(m -> m.getValue(), Collectors.toList())));
答案2
得分: 1
这里是一种使用 [tag:java-8] 中的新特性(如 Map::computeIfPresent
和 Map::computeIfAbsent
)的过程化方法,但不使用 [tag:java-stream]:
Map<String, List<String>> map = new HashMap<>();
tagList.forEach(tag -> {
String tagName = tag.getTagName();
tag.getItems().forEach(item -> {
map.computeIfPresent(item, (k, v) -> { v.add(tagName); return v; });
map.computeIfAbsent(item, k -> new ArrayList<>(Arrays.asList(tagName)));
});
});
map.forEach((k, v) -> System.out.println(k + " " + v));
如果您想要对这些项从 Item1
排序到 Item5
,请使用不同的实现:
Map<String, List<String>> map = new TreeMap<>();
此外,只要 Item3
仅出现一次,您的预期输出就不匹配:
Item1 [popular, mostwanted]
Item2 [popular, expensive, mostwanted]
Item3 [popular]
Item4 [popular, expensive]
Item5 [expensive, mostwanted]
英文:
Here is a procedural way to go using new features from [tag:java-8] such as Map::computeIfPresent
and Map::computeIfAbsent
, but without [tag:java-stream]:
Map<String, List<String>> map = new HashMap<>();
tagList.forEach(tag -> {
String tagName = tag.getTagName();
tag.getItems().forEach(item -> {
map.computeIfPresent(item, (k, v) -> { v.add(tagName); return v; });
map.computeIfAbsent(item, k -> new ArrayList<>(Arrays.asList(tagName)));
});
});
map.forEach((k, v) -> System.out.println(k + " " + v));
If you want to sort these items from Item1
to Item5
, use the different implementation:
Map<String, List<String>> map = new TreeMap<>();
Moreover, your expected output doesn't match as long as there is only one occurence of Item3
:
Item1 [popular, mostwanted]
Item2 [popular, expensive, mostwanted]
Item3 [popular]
Item4 [popular, expensive]
Item5 [expensive, mostwanted]
</details>
专注分享java语言的经验与见解,让所有开发者获益!
评论