用java中的streams和lambda查找(树)映射中的所有最大值
因此,我必须在java中使用streams和lambda查找映射中的最大值。查找一个最大值不是问题,但如何查找多个最大值? 例子: 元素e=2,i=1,a=2的树形图, 我目前的解决方案是a=2,但我想要a=2,e=2 我的代码:用java中的streams和lambda查找(树)映射中的所有最大值,java,lambda,java-stream,treemap,Java,Lambda,Java Stream,Treemap,因此,我必须在java中使用streams和lambda查找映射中的最大值。查找一个最大值不是问题,但如何查找多个最大值? 例子: 元素e=2,i=1,a=2的树形图, 我目前的解决方案是a=2,但我想要a=2,e=2 我的代码: Map<String, Integer> frequencies = new Treemap<>(); frequencies.put("e", 2);//I don't put the values in like thi
Map<String, Integer> frequencies = new Treemap<>();
frequencies.put("e", 2);//I don't put the values in like this but it'll do to test
frequencies.put("i", 1);
frequencies.put("a", 2);
Optional<Map.Entry<String, Integer>> maxEntry = frequencies.entrySet().stream()
.max(Map.Entry.comparingByValue());//frequencies is the TreeMap<String, Integer>
//I know this only searches one max value, here's my other attempt:
try (Stream<Map.Entry<String, Integer>> stream = frequencies.entrySet().stream()) {
stream
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k, v) -> k, LinkedHashMap::new));
//I don't know what to do here, I somehow would have to get the result into a new list, but it still only returns one result
}
如果我做错了什么,请告诉我。首先,找到最大频率:
Optional<Integer> maxFreqOptional = frequencies.values()
.stream()
.max(Comparator.naturalOrder());
然后,您可以将此频率作为一个值来收集所有条目:
Integer maxFreq = maxFreqOptional.get(); // check if it's empty first
List<String> mostFrequent = frequencies.entrySet()
.stream()
.filter(entry -> entry.getValue().equals(maxFreq))
.map(Map.Entry<String, Integer>::getKey)
.collect(Collectors.toList());
首先,找到最大频率:
Optional<Integer> maxFreqOptional = frequencies.values()
.stream()
.max(Comparator.naturalOrder());
然后,您可以将此频率作为一个值来收集所有条目:
Integer maxFreq = maxFreqOptional.get(); // check if it's empty first
List<String> mostFrequent = frequencies.entrySet()
.stream()
.filter(entry -> entry.getValue().equals(maxFreq))
.map(Map.Entry<String, Integer>::getKey)
.collect(Collectors.toList());
你就快到了:
使用value=frequency作为键,原始键作为值,将入口流收集到树映射中。因此,请使用级联分组方式。然后获取具有最大键的条目:
TreeMap<Integer, List<String>> map = frequencies.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry<String, Integer>::getValue, TreeMap::new, Collectors.toList()
));
Map.Entry<Integer, List<String>> largest = map.lastEntry();
注意:如果您的数据集很大,并且您希望避免构建此反向映射,则您可能更喜欢其他建议的解决方案之一,该解决方案将映射迭代两次:一次查找最大频率,然后再次查找所有相应的条目。您几乎做到了:
使用value=frequency作为键,原始键作为值,将入口流收集到树映射中。因此,请使用级联分组方式。然后获取具有最大键的条目:
TreeMap<Integer, List<String>> map = frequencies.entrySet().stream()
.collect(Collectors.groupingBy(
Map.Entry<String, Integer>::getValue, TreeMap::new, Collectors.toList()
));
Map.Entry<Integer, List<String>> largest = map.lastEntry();
注意:如果您的数据集很大,并且希望避免构建此反向映射,则您可能更喜欢其他建议的解决方案之一,该解决方案将映射迭代两次:一次查找最大频率,然后再次查找所有相应的条目。如果存在,您可以按maxEntry的值进行筛选,以获得所有映射。最大值的条目
List<Map.Entry<String, Integer>> res = frequencies.entrySet().stream()
.filter(e -> e.getValue().equals(maxEntry.get().getValue()))
.collect(Collectors.toList());
在线演示
输出:[a=2,e=2]如果存在,您可以按maxEntry的值进行筛选,以获得所有映射。最大值的输入
List<Map.Entry<String, Integer>> res = frequencies.entrySet().stream()
.filter(e -> e.getValue().equals(maxEntry.get().getValue()))
.collect(Collectors.toList());
在线演示
输出:[a=2,e=2]
因此,我必须在java中使用streams和lambda查找映射中的最大值
这里有一种不用树映射的方法。它对包含的条目进行频率计数
Map<String, Integer> map = Map.of("z", -1, "b", 0, "r", -2,
"s", 0, "j", 1, "a", 2, "i", 1, "e", 2);
Optional<Entry<Integer, List<Entry<String,Integer>>>> opt = map.entrySet()
.stream()
.collect(Collectors.groupingBy(Entry::getValue))
.entrySet().stream().max(Entry.comparingByKey());
System.out.println(opt.isPresent() ? opt.get().getValue() : "Empty List");
为了好玩,你可以绕过初始地图,创建一个条目流。实际上,当您创建初始贴图时,您正在创建入口对象,因此这里不涉及额外的贴图开销
Builder<Entry<String, Integer>> entryStream = Stream.builder();
entryStream.add(Map.entry("b", 0));
entryStream.add(Map.entry("r", -2));
entryStream.add(Map.entry("s", 0));
entryStream.add(Map.entry("j", 1));
entryStream.add(Map.entry("a", 2));
entryStream.add(Map.entry("i", 1));
entryStream.add(Map.entry("e", 2));
因此,我必须在java中使用streams和lambda查找映射中的最大值
这里有一种不用树映射的方法。它对包含的条目进行频率计数
Map<String, Integer> map = Map.of("z", -1, "b", 0, "r", -2,
"s", 0, "j", 1, "a", 2, "i", 1, "e", 2);
Optional<Entry<Integer, List<Entry<String,Integer>>>> opt = map.entrySet()
.stream()
.collect(Collectors.groupingBy(Entry::getValue))
.entrySet().stream().max(Entry.comparingByKey());
System.out.println(opt.isPresent() ? opt.get().getValue() : "Empty List");
为了好玩,你可以绕过初始地图,创建一个条目流。实际上,当您创建初始贴图时,您正在创建入口对象,因此这里不涉及额外的贴图开销
Builder<Entry<String, Integer>> entryStream = Stream.builder();
entryStream.add(Map.entry("b", 0));
entryStream.add(Map.entry("r", -2));
entryStream.add(Map.entry("s", 0));
entryStream.add(Map.entry("j", 1));
entryStream.add(Map.entry("a", 2));
entryStream.add(Map.entry("i", 1));
entryStream.add(Map.entry("e", 2));
因为您只需要匹配最大值的条目,所以将映射的所有条目分组到反向映射中并没有任何好处。您只需放弃其值与最大值不匹配的所有条目 以下是使用lambdas的一种简洁方法:
Integer max = frequencies.isEmpty() ?
Integer.MIN_VALUE :
Collections.max(frequencies.values());
List<String> result = new ArrayList<>();
frequencies.forEach((k, v) -> { if (v.equals(max)) result.add(k); });
因为您只需要匹配最大值的条目,所以将映射的所有条目分组到反向映射中并没有任何好处。您只需放弃其值与最大值不匹配的所有条目 以下是使用lambdas的一种简洁方法:
Integer max = frequencies.isEmpty() ?
Integer.MIN_VALUE :
Collections.max(frequencies.values());
List<String> result = new ArrayList<>();
frequencies.forEach((k, v) -> { if (v.equals(max)) result.add(k); });
.collectCollectors.groupingByMap.Entry::getValue,Collectors.mappingMap.Entry::getKey,Collectors.toList仅供参考这是树映射,不是树映射…再次收集到树映射并获取所需结果的最后一个条目..collectCollectors.groupingByMap.Entry::getValue,Collectors.mappingMap.Entry::getKey,Collectors.toList仅供参考,这是TreeMap,而不是TreeMap…再次收集到TreeMap并获取所需结果的最后条目。@fps谢谢。这是Collectors.GroupingBy如果没有映射,这应该可以真正用于生成树映射。@fps谢谢。它是Collectors.GroupingBy如果没有映射,这应该可以真正用于生成树映射。