java - 使用 Java Streams 获取嵌套在 HashMap 中的元素最多的集合

标签 java java-8 hashmap set java-stream

情况是这样的: 我需要在某些日期登记人们的投票。简而言之,提出一个日期,然后人们投票选出他们想要的日期。

数据结构如下:

private HashMap<LocalDateTime, Set<Vote>> votes;

一票是:

public class Vote {
    private String name;
    private VoteType vote;

    public Vote(String name, VoteType vote) {
        super();
        this.name = name;
        this.vote = vote;
    }
}

其中 VoteType 只是一个枚举:

public enum VoteType {YES, NO, MAYBE}

现在我已经制作了一个流,返回可用性的票数 (VoteType):

public Map<LocalDateTime, Integer> voteCount(VoteType targetVote) {
    return this.votes.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> new Integer(
            e.getValue().stream().filter(v -> v.getVote() == targetVote).collect(Collectors.toList()).size())));
}

所以我的问题是: 我如何使用 Java Streams 获得获得最多"is"的日期。

/* Returns the date that got the most 'YES' votes */
public LocalDateTime winningDate() {
    // TODO
}

谢谢你的帮助!

最佳答案

So my question is: How can I get, using Java Streams, the date that got the most 'YES'.

这将是一个漫长的...

  1. 我们需要到达一个有Stream<LocalDateTime>的位置所以我们稍后可以按日期分组应用 counting下游收集器获取特定日期的票数,我们可以通过 flatMap 完成此结构.
  2. 我们只需要保留投票类型为YES的对象
  3. 我们按日期对结果进行分组,并将值作为 YES 的数量在特定日期投票。
  4. 我们流过 entrySet并找到 max投票日期

代码:

/* Returns the date that got the most 'YES' votes */
public Optional<LocalDateTime> getWinningDate() {
    return votes.entrySet() // Set<Entry<LocaleDateTime, Set<Vote>>
            .stream() // Stream<Entry<LocaleDateTime, Set<Vote>>
            .flatMap(e -> e.getValue().stream().filter(a -> a.getVote() == VoteType.YES)
                         .map(x -> e.getKey())) // Stream<LocalDateTime>
           .collect(groupingBy(Function.identity(), counting())) // Map<LocaleDateTime, Long>
           .entrySet() // Set<Entry<LocaleDateTime, Long>>
           .stream() // Stream<Entry<LocaleDateTime, Long>>
           .max(Comparator.comparingLong(Map.Entry::getValue)) // Optional<Entry<LocaleDateTime, Long>>
           .map(Map.Entry::getKey); // Optional<LocalDateTime>
}
  • 请注意,我已将方法返回类型更改为 Optional<LocaleDateTime> ,我本可以返回 .map(Map.Entry::getKey).orElse(null)因此,您可以保持当前方法的返回类型为 LocalDateTime但这感觉很糟糕,所以 我决定推迟决定在“没有值(value)”的情况下做什么 案例”给客户。
  • 我已将方法名称更改为 getWinningDate以提高可读性。

至于处理 Optional<T> ,在你的情况下,如果你想要一个 null getWinningDate 情况下的值返回一个空的 Optional,你可以安全地解包它:

LocalDateTime winningDate = getWinningDate().orElse(null);

或者如果您想提供默认日期:

LocalDateTime winningDate = getWinningDate().orElse(defaultDate);

或者如果您确定总会有结果,那么只需调用 get() .

LocalDateTime winningDate = getWinningDate().get();

等..

关于java - 使用 Java Streams 获取嵌套在 HashMap 中的元素最多的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53771319/

相关文章:

java - 如何逐条读取一个 Stream?

ruby - 按键排序散列,在 Ruby 中返回散列

json - 将 hashmap 转换为 JSON 对象时从 Gson 获取 stackoverflowerror

java - 为什么 getValue() 函数不适用于 HashMap?

java - Spring Boot Thymeleaf 无法解析模板

java - Guava 中 ForwardingMap 的用途是什么?

java-8 - 如何在 stream.collect(Collectors) 中指定具体的集合类型

java - 了解 Java 8 Lambda 表达式

java - 在 Java 中使用 `apache-commons` 、 `guava` 或其他一些流行的库将迭代器转换为可变列表的方法

java - 将项目导入 Eclipse 后出现“必须覆盖父类(super class)方法”错误