【问题标题】:Java 8: Comparator comparingDouble type mismatchJava 8:比较器比较双重类型不匹配
【发布时间】:2015-10-11 17:38:46
【问题描述】:
final int[] brr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 };

for (int i : brr) {
    System.out.println(Math.sin(i));
}

final int leastIdx = Arrays.stream(brr).min(Comparator.comparingDouble(i -> Math.sin(i))).get();

leastIdx 应该返回为 4 但我无法编译它。 任何见解都值得赞赏。

The method min() in the type IntStream is not applicable for the 
arguments (Comparator.comparingDouble((<no type> i) -> Math.sin(i)))

【问题讨论】:

    标签: java java-8 comparator java-stream


    【解决方案1】:

    IntStream#min 不带比较器;它只是在流中找到最小的int。您必须转换为Stream&lt;Integer&gt;

    Arrays.stream(brr).boxed()
            .min(comparingDouble(i -> Math.sin(i)))
            .get();
    

    或使用reduce 计算最小值:

    Arrays.stream(brr)
            .reduce((x,y) -> Math.sin(x) > Math.sin(y) ? y : x )
            .getAsInt();
    

    leastIdx 应该返回为 4

    您的流实际上是在尝试查找具有最小Math.sinint,而不是该int 的索引。如果要查找索引,则需要流过索引而不是值:

    int leastIdx = IntStream.range(0, brr.length).boxed()
            .min(comparingDouble(i->Math.sin(brr[i])))
            .get();
    

    或者,如果您愿意牺牲清晰度来避免拳击:

    int leastIdx = IntStream.range(0, brr.length)
            .reduce((x,y) -> Math.sin(brr[x]) > Math.sin(brr[y]) ? y : x)
            .getAsInt();
    

    【讨论】:

      【解决方案2】:

      建议的解决方案有一个缺陷:它们几乎对每个元素都计算了两次正弦值。因此,对于 1000 个输入元素,您将不得不计算大约 2000 次正弦。

      有两个解决方案涉及我的 StreamEx 库,每个流元素只计算一次正弦:

      final int leastIdx = IntStreamEx
              .ofIndices(brr).boxed()
              .minByDouble(i -> Math.sin(brr[i])).get();
      

      或者:

      final int leastIdx = (int) IntStreamEx.of(brr)
              .mapToObj(Math::sin)
              .collect(MoreCollectors.minIndex()).getAsLong();
      

      两者都在您的输入中返回 4。不幸的是,目前他们都涉及拳击。目前 StreamEx 不提供消除装箱和二次正弦计算的方法。

      【讨论】:

      • 我不会在意,除非分析器告诉我计算 sin 两次是个问题。它不太可能被优化掉。
      • @Holger,正弦可能不是什么大问题,但在某些情况下,它可能很重要,具体取决于特定的密钥提取器功能。
      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 2020-03-24
      • 2017-10-28
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 2021-09-06
      相关资源
      最近更新 更多