【问题标题】:Stream to generate Map with Integer key and Set of values流以使用整数键和值集生成 Map
【发布时间】:2020-06-02 17:18:18
【问题描述】:

我最近偶然发现了一个有趣的 Stream 挑战,要求 创建一个 Java (8) 流,从输入文件中读取整数并生成一个映射,将数字映射到其对应的最小素因子

到目前为止我的看法:

Map<Integer, String> map = Files.lines(Path.of("nums.txt")).filter(s -> Integer.parseInt(s) > 2).map(Integer::parseInt)
                    .collect(Collectors.toMap(i -> {
                        if(i == 2) return 2;
                        var divisors = IntStream.rangeClosed(2, i).filter(j -> i % j== 0).boxed()
                                .collect(Collectors.toList());
                        return divisors.stream().filter(integer -> {
                            for(int ii = 2; ii < Math.sqrt(integer); ii++) {
                                if(integer % ii == 0) return false;
                            }
                            return true;
                        }).findFirst().orElse(-1);
                    }, String::valueOf
                    , (s1, s2) -> s1 + ";" + s2));

现在没有合并 BiFunction 我会得到重复的键异常,所以为了避免我 从上面做了解决方法,它用分号连接类似的映射值。

我发现这种解决方案有点蹩脚,但我想知道,我的地图是否有可能有一个 Set 实现其第二个类型参数并将类似的映射值收集到一个集合中。

主要问题是如果例如。我在 KeyMapper 函数中实例化了新的 HashMap,它总是会为每个重复的键返回一个新的,因此两个 HashSet 的合并尝试总是徒劳的

附注关于流本身的反馈也很受欢迎,我不确定这种方法是否过于复杂。

【问题讨论】:

  • 假设文件包含8 9 10 11,您给出的描述(“将数字映射到其对应的最小素数”)听起来结果应该是[8=2, 9=3, 10=2, 11=11],对吗?因为您的代码似乎想用[2=8;10, 3=9, 11=11] 构建一个结果,但这不符合您给出的描述。
  • 仅供参考: 1) 您应该翻转 filtermaps 呼叫,因此您不必呼叫 parseInt 两次。 --- 2) divisors.stream()... 逻辑是不必要的,因为最小的除数本质上是一个素数,所以你不必检查它。
  • 提示: 要将Set 作为映射值,请使用groupingBy​() 而不是toMap,如Collectors.groupingBy​(keyMapper, Collectors.toSet())
  • 同意@Andreas,您似乎有向后映射。输入包含重复的数字是没有意义的(为什么两次产生相同的答案?)所以永远不应该有重复的键。您对问题的描述表明情况确实如此。
  • 我可能混淆了映射表达式,所以是的,您的示例的等待结果将类似于 [2=[8,10],3=[9],11=[11]] .另外,谢谢你的建议!

标签: java dictionary stream set


【解决方案1】:

很遗憾,此类问题需要解释。例如,如果有人做了这样的事情怎么办?

String file = "<number file>";
try {
    Map<Integer, List<Integer>> factors = new HashMap<>();
            Files.lines(Path.of(file)).map(Integer::parseInt).forEach(n-> {

                //code here to fill the map factors
            });
} catch (IOException ie) {
    ie.printStackTrace();
}

或者类似的东西

String file = "<number file>";
try {
    Map<Integer, List<Integer>> factors =
            Files.lines(Path.of(file)).map(Integer::parseInt)
                    .collect(Collectors.toMap(i -> i,
                            i -> primeFactors(i)));
} catch (IOException ie) {
    ie.printStackTrace();
}

public static List<Integer> primeFactors(int i) {
    List<Integer> factors = new ArrayList<>();
    // code here to find the factors
    return factors;
}

有几种先进的算法可以分解合数。这些算法不一定适合stream 处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-19
    • 2015-05-11
    • 1970-01-01
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多