【问题标题】:How create Map<String,List<Long>> java 8 with single stream?如何使用单流创建 Map<String,List<Long>> java 8?
【发布时间】:2018-07-25 08:11:45
【问题描述】:

我必须创建一个Map&lt;String,List&lt;Long&gt;&gt;(可能是单流)和课程的key= namevalue= number 课程被选为第一选择(列表的第一个条目),第二个选择(第二个条目列表的),第三个选择(列表的第三个条目), 例如:Chemstry, List&lt; 4,6,7&gt;

我试过这个但给了我错误:

return courses.values().stream()  
              .collect(groupingBy(Course::getNome,TreeMap::new, collectingAndThen(Course::getchoice, counting()));

【问题讨论】:

  • 请提供出现错误的代码,包括Courses 的一些示例...
  • “但给了我错误” — 哪些错误?
  • 没有代码示例,没有错误。如果您不自助,我们如何帮助您?
  • 这不是一个坏问题,但您已经将其表述为非常难以理解的方式。我会加一个,因为我喜欢它

标签: java list dictionary java-stream long-integer


【解决方案1】:

分组和计数相当简单,但进入列表需要更多的工作。这是通过collectingAndThen 流式传输计数的一种方法:

courses.values()
        .stream()
        .collect(groupingBy(
                Course::getName,
                collectingAndThen(
                        groupingBy(Course::getChoice, counting()),
                        counts -> IntStream.range(0, 3)
                                .mapToObj(i -> counts.getOrDefault(i + 1, 0L))
                                .collect(toList()))))

Ideone Demo

编辑:@Eugene 暗示我误解了要求。如果您想列出所有选项而不是前三个选项,只需将 3 替换为 Collections.max(counts.keySet())

【讨论】:

  • 如果课程是A = 1; A = 1, A = 3,输出地图应该是[A = {2, 0, 1}],不确定您的代码是否可以...
  • 很好,但是,您仍然假设通过 IntStream.range 最多有 3 个值,我认为正确的方法是先计算最大值并解决这个问题
  • @Eugene 我没有假设任何事情。 getOrDefault() 涵盖缺失值。
  • 如果您在 Map 中添加另一个条目会怎样,例如 courses.put(Math.random(), new Course("a", 5));
  • 这不是节省 4 个字符,而是 每个元素 执行一个算术指令。
【解决方案2】:

只是为了好玩,如果您愿意分两步完成:

static Map<String, List<Long>> group(Map<?, Course> courses) {

    Map<String, List<Long>> m = courses.values()
            .stream()
            .collect(Collectors.collectingAndThen(
                    Collectors.toMap(
                            Course::getName,
                            Course::getChoice,
                            Math::max),
                    map -> map.entrySet().stream()
                            .collect(Collectors.toMap(
                                         Entry::getKey,
                                         e -> new ArrayList<>(Collections.nCopies(e.getValue(), 0L))))

    ));

    courses.values()
            .forEach(x -> {
                List<Long> l = m.get(x.getName());
                l.set(x.getChoice() - 1, l.get(x.getChoice() - 1) + 1);
            });

    return m;

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多