使用流对 AbstractMap 的三个最大数字求和
Summing three biggest numbers of an AbstractMap using streams
我有一个问题。如何计算这个结构的三个最大最大值?
public static AbstractMap.SimpleEntry<String, Long> sum3max(List<AbstractMap.SimpleEntry<String, Long>> list){... }
预期输出应如下所示:
List<AbstractMap.SimpleEntry<String, Long>> list = new ArrayList<>();
list.add(new AbstractMap.SimpleEntry<>("apple", 20L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 30L));
list.add(new AbstractMap.SimpleEntry<>("apple", 10L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 20L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 10L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 40L));
list.add(new AbstractMap.SimpleEntry<>("apple", 60L));
list.add(new AbstractMap.SimpleEntry<>("apple", 5L));
// apple = 90 because we are counting 60+20+10 (three biggest numbers of all apples)
// tomato = 90 because 30+20+40 (three biggest numbers of all tomatos )
System.out.println(sum3max(list)); // should be apple=90, because 'a' in apple is alphabetically smaller than 't' in tomato
你能帮帮我吗?我试过这样的东西,但它只适用于对所有值求和,而不仅仅是三个最大的值。
var map = list.stream().collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,Collectors.summingLong(AbstractMap.SimpleEntry::getValue)));
Map.Entry<String, Long> maxEntry = map.entrySet().stream()
.max(Map.Entry.comparingByValue()).get();
return new AbstractMap.SimpleEntry<>(maxEntry.getKey(), maxEntry.getValue());
这是一种流式传输值的方法。
首先,创建一个 lambda 作为 finisher
来对列表中最大的 3 个值求和。后面会用到。
终结者
- finisher 拿了一个 long 的列表,returns 一个 long
- 首先将值倒序排列
- 限制为 3 或更少并映射到长
- 然后将它们相加 return 总和
Function<List<Long>, Long> sum =
lst -> lst.stream().sorted(Comparator.reverseOrder())
.limit(3).mapToLong(Long::longValue).sum();
流式传输条目
- 流式传输条目列表。
- 将
fruit
和 value list of longs
键控的项目分组
longs
需要通过 Collectors.mapping
从他们的条目中提取。
- 然后使用
collectingAndThen
首先将这些多头收集到列表中
- 后面是前面定义的
finisher
到return的长和
Map<String,Long> map =
list.stream()
.collect(Collectors.groupingBy(Entry::getKey,
Collectors.mapping(Entry::getValue,
Collectors.collectingAndThen(
Collectors.toList(),
sum::apply))));
map.entrySet().forEach(System.out::println);
打印
apple=90
tomato=90
我的解决方案允许少于三个数字的项目。也可以过滤掉此类列表。我选择允许他们。
我有一个问题。如何计算这个结构的三个最大最大值?
public static AbstractMap.SimpleEntry<String, Long> sum3max(List<AbstractMap.SimpleEntry<String, Long>> list){... }
预期输出应如下所示:
List<AbstractMap.SimpleEntry<String, Long>> list = new ArrayList<>();
list.add(new AbstractMap.SimpleEntry<>("apple", 20L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 30L));
list.add(new AbstractMap.SimpleEntry<>("apple", 10L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 20L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 10L));
list.add(new AbstractMap.SimpleEntry<>("tomato", 40L));
list.add(new AbstractMap.SimpleEntry<>("apple", 60L));
list.add(new AbstractMap.SimpleEntry<>("apple", 5L));
// apple = 90 because we are counting 60+20+10 (three biggest numbers of all apples)
// tomato = 90 because 30+20+40 (three biggest numbers of all tomatos )
System.out.println(sum3max(list)); // should be apple=90, because 'a' in apple is alphabetically smaller than 't' in tomato
你能帮帮我吗?我试过这样的东西,但它只适用于对所有值求和,而不仅仅是三个最大的值。
var map = list.stream().collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey,Collectors.summingLong(AbstractMap.SimpleEntry::getValue)));
Map.Entry<String, Long> maxEntry = map.entrySet().stream()
.max(Map.Entry.comparingByValue()).get();
return new AbstractMap.SimpleEntry<>(maxEntry.getKey(), maxEntry.getValue());
这是一种流式传输值的方法。
首先,创建一个 lambda 作为 finisher
来对列表中最大的 3 个值求和。后面会用到。
终结者
- finisher 拿了一个 long 的列表,returns 一个 long
- 首先将值倒序排列
- 限制为 3 或更少并映射到长
- 然后将它们相加 return 总和
Function<List<Long>, Long> sum =
lst -> lst.stream().sorted(Comparator.reverseOrder())
.limit(3).mapToLong(Long::longValue).sum();
流式传输条目
- 流式传输条目列表。
- 将
fruit
和value list of longs
键控的项目分组longs
需要通过Collectors.mapping
从他们的条目中提取。- 然后使用
collectingAndThen
首先将这些多头收集到列表中 - 后面是前面定义的
finisher
到return的长和
Map<String,Long> map =
list.stream()
.collect(Collectors.groupingBy(Entry::getKey,
Collectors.mapping(Entry::getValue,
Collectors.collectingAndThen(
Collectors.toList(),
sum::apply))));
map.entrySet().forEach(System.out::println);
打印
apple=90
tomato=90
我的解决方案允许少于三个数字的项目。也可以过滤掉此类列表。我选择允许他们。