我正在尝试创建Map<String,List<Integer>>
。这里的挑战是如果密钥不存在则创建列表,否则使用当前密钥添加新整数以获取当前列表。
我已经完成了一些非常接近的工作,但我不知道如何参考当前地图来获取列表。
List<String> strList = Arrays.asList(new String[]{"even","odd"});
List<Integer> intList = Arrays.asList(new Integer[]{1,2,3,4,5,6,7});
//This is what i want returned: Map<String, List<Integer>> myMap=null;
List<Map.Entry<String,Integer>> list = strList.stream().flatMap(s -> intList.stream()
.map(i -> Maps.immutableEntry(s,i))).collect(Collectors.toList());
需要通过调用下面的函数来创建值,该函数需要3个参数作为当前键,并且值加上当前列表。:
static public List<Integer> testFunc(String key, Integer i, List<Integer>list){
if(list == null){
list = new ArrayList();
}
list.add(i * key.hashCode());
return list;
}
答案 0 :(得分:3)
实现此行为的最简单方法是将Collectors.groupingBy
与您自己的分类器一起使用:
Map<String, List<Integer>> map =
intList.stream()
.collect(Collectors.groupingBy(x -> x % 2 == 0 ? "even" : "odd"));
答案 1 :(得分:0)
你的问题确实需要更清晰。到目前为止你所说的最好的猜测是你有一个键列表,一个输入值列表(整数)一个函数,它接受一个键和一个输入整数,计算一个输出整数并将结果整数添加到一个列表按键映射的值。
听起来你的testFunc必须能够执行各种操作,而不仅仅是“偶数”和“奇怪”。听起来intList
中的值可以在多个List
中使用,而不仅仅是分区为桶,所以在没有更好的细节的情况下使用我的想象力,我认为它可能看起来像像
static Optional<Integer> testFunc(String key, int intVal){
switch(key){
case "even": return Optional.of(intVal).filter(i -> i % 2 == 0); // return intVal if key is "even" and i is even
case "odd": return Optional.of(intVal).filter(i -> i % 2 != 0); // return intVal if key is "odd" and i is odd
case "pos": return Optional.of(intVal).filter(i -> i > 0); // return intVal if key is "pos" and i is positive
case "neg": return Optional.of(intVal).filter(i -> i < 0); // return intVal if key is "neg" and i is negative
default: return Optional.empty();
}
}
我在这里使用Optional
因为给定的整数i
可能不适用于给定的密钥。如果Optional<Integer>
不适用于给定密钥,则过滤器会将Optional.empty()
缩减为i
。
下面的流执行从strList
到给定的整数列表的给定键的直接映射。它通过一次一个地考虑每个键,并从intList中选择应用并将它们收集到List
的值来实现。
List<String> strList = Arrays.asList("even", "odd", "pos", "neg");
List<Integer> intList = Arrays.asList(-3, -2, -1, 0, 1, 2, 3);
Map<String,List<Integer>> results = strList.stream()
.collect(Collectors.toMap(s -> s, s -> intList.stream()
.map(i -> testFunc(s, i)).filter(Optional::isPresent).map(Optional::get)
.collect(Collectors.toList())
));
System.out.println(results);
结果是
{neg=[-3, -2, -1], pos=[1, 2, 3], even=[-2, 0, 2], odd=[-3, -1, 1, 3]}
这是你想要的那种结果吗?
我努力解决的一个问题是希望更加清晰,因为你的“偶数”/“奇怪”的例子似乎将一个谓词应用于intList,只为“偶数”过滤偶数,为奇数过滤奇数“;而你的testFunc示例为intList中的每个值为strList中的每个值映射一个值。如果你的testFunc确实需要映射值和过滤器值,那么使用Streams很难做到这一点,因为map()
和filter()
是单独的流操作。如果map()
对filter()
申请了map()
,Optional
和filter()
可以同时执行,{我在上面的示例中执行了操作,然后应用filter(Optional::isPresent)
来过滤掉testFunc
中不符合布尔测试的内容,然后应用filter(Optional::get)
来展开Integer
来自Optional
包装器。