joe*_*e.d 2 java java-8 java-stream
我想得到频率键控的数组值频率图.我能够相反 - 按价值键入地图.尝试切换参数,但grouping by不接受Collector作为第一个参数.
另一个问题,我如何更改Map实现以LinkedHashMap保持数组元素的排序(如果地图由值键入)?
int [] arr = {1, 4, 5, 9, 2, 4, 3, 1, 1, 3, 5, 3, 2, 4, 2, 9, 2, 1};
Map<Integer, Long> collect = Arrays
.stream(arr)
.boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Run Code Online (Sandbox Code Playgroud)
结果是 {1=4, 2=4, 3=3, 4=3, 5=2, 9=2}
我正在寻找的是
{4=1, 3=[4, 3] , 2=[5, 9] ... }这意味着有4次出现1次,3次出现4次,2次出现5次和9次.
我的目标是使用频率作为键获取Map,并将值作为数组元素列表.对于键冲突,请将另一个值添加到值列表中.
一种可能的解决方案是首先创建映射值 - >频率,然后将其收集到另一个映射中,在该映射中按频率进行分组.
Map<Long, List<Integer>> collect =
Arrays.stream(arr)
.boxed()
.collect(collectingAndThen(groupingBy(identity(), counting()),
m -> m.entrySet().stream().collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList())))));
Run Code Online (Sandbox Code Playgroud)
也许更清晰的方式(不是一个班轮)是从你的collect地图开始并使用forEach结合computeIfAbsent:
Map<Long, List<Integer>> result = new HashMap<>();
collect.forEach((value, freq) -> result.computeIfAbsent(freq, u -> new ArrayList<>()).add(value));
Run Code Online (Sandbox Code Playgroud)