【发布时间】:2021-04-25 23:47:01
【问题描述】:
使用 Java 我正在尝试创建包含 String 键和 List<String> 值的映射的笛卡尔积。创建列表时,我需要保留键的值,如下所示:
- 来自
Map<String, List<String>>对象 - 到
List<Map<String, String>>对象
我还要求当原始映射中的List<String> 值为空时,在创建笛卡尔积时仍应将其视为单个值,以避免乘以 0 并且不创建映射。比如下面的地图:
{
"Location Number" = {"100", "500"}
"Department Number" = {"11", "22", "33"}
"District Number" = {}
"Preferred Language" = {"en-US"}
}
翻译成:
{
{
"Location Number" = "100"
"Department Number" = "11"
"District Number" = {}
"Preferred Language" = "en-US"
},
{
"Location Number" = "100"
"Department Number" = "22"
"District Number" = {}
"Preferred Language" = "en-US"
},
{
"Location Number" = "100"
"Department Number" = "33"
"District Number" = {}
"Preferred Language" = "en-US"
},
{
"Location Number" = "500"
"Department Number" = "11"
"District Number" = {}
"Preferred Language" = "en-US"
},
{
"Location Number" = "500"
"Department Number" = "22"
"District Number" = {}
"Preferred Language" = "en-US"
},
{
"Location Number" = "500"
"Department Number" = "33"
"District Number" = {}
"Preferred Language" = "en-US"
}
}
下面是我目前用来完成类似翻译的代码,但它没有保留我需要的密钥。我不知道这是否可以在一般情况下使用 Java 8 Streams 来完成。
private static List<List<String>> createRuleListFromMap(Map<String, List<String>> ruleMap) {
List<List<String>> ruleList = new ArrayList<>();
cartesianProduct(ruleMap.values()).forEach(ruleList::add);
return ruleList;
}
private static <T> Stream<List<T>> cartesianProduct(Collection<? extends Collection<T>> collections) {
return cartesianProduct(new ArrayList<Collection<T>>(collections), Collections.emptyList());
}
private static <T> Stream<List<T>> cartesianProduct(List<? extends Collection<T>> collections, List<T> current) {
return collections.isEmpty() ? Stream.of(current) : collections.get(0).stream().flatMap(e -> {
List<T> list = new ArrayList<>(current);
list.add(e);
return cartesianProduct(collections.subList(1, collections.size()), list);
});
}
【问题讨论】:
标签: java list dictionary java-stream cartesian-product