【问题标题】:How to convert type of stream?如何转换流的类型?
【发布时间】:2017-05-03 23:24:32
【问题描述】:

除了我之前提出的问题,可以在这里找到, How to combine list elements and find the price of largest combination

我没有使用Integer price,而是使用String price

List<Long> highest = details
                .stream()
                .map(d -> Stream.concat(Stream.of(d.getDetailId()), d.getStackableDetails().stream()).collect(Collectors.toList()))
                .collect(Collectors.toMap(s -> s.stream().map(Double.class::cast).reduce(0D,
                        (left, right) -> left + Double.parseDouble(map.get(right).getPrice())),
                        s -> s.stream().collect(Collectors.toList()),
                        (left, right) -> right,
                        TreeMap::new))
                .lastEntry().getValue();

但我在运行时不断收到类转换异常。有人可以告诉我为什么我无法转换 Stream 类型以及如何纠正它。谢谢!

【问题讨论】:

  • 发布实际失败消息/堆栈跟踪
  • java.lang.ClassCastException: 无法将 java.lang.Long 转换为 java.lang.Double
  • 是的,例如String price ="30.0"
  • 为什么你的类型还是混淆了? Detail.class 在你的控制之下吗?如果是,请相应地进行调整。如果不是:为什么不先将它们包装成自己的类型?这样你就不需要经常转换和解析......
  • 我添加了一个answer to your other question,您可以将价格转换功能添加到...

标签: collections java-8 java-stream


【解决方案1】:

我不太清楚您要做什么,但是填充 TreeMap 只是为了获取最后一个元素是没有意义的。获取最大元素是作为固有的Stream 操作提供的。

所以你在问题代码中所做的可以简化为

List<Long> highest = details
    .stream()
    .map(d -> Stream.concat(Stream.of(d.getDetailId()), d.getStackableDetails().stream())
                    .collect(Collectors.toList()))
    .max(Comparator.comparingDouble(s -> s.stream()
                       .mapToDouble(l -> Double.parseDouble(map.get((double)l).getPrice()))
                       .sum()))
    .get();

这也解决了您的问题,只需将Long 转换为double。这会将Long 对象拆箱为long 值,执行扩大转换为double 并将其装箱为Double 以进行Map 查找。但是,不建议使用 Double 对象作为映射键。

【讨论】:

  • 我错过了什么吗? map 来自哪里(map.get((double)l)?
  • @Holger TreeMap 的建议是我很白痴,匆忙写作和回答......应该受到责备,而不是 OP
  • @Roland:我不知道它来自哪里,但它在 OP 的代码中,我只是以完全相同的方式使用它......从上下文中,我们可以得出结论,它必须是一个 @ 987654335@。请记住,OP 的代码自上一个问题以来已经发展。
  • @Eugene:没关系;我们都在匆忙或疲倦时做这些事情。这就是为什么稍后修改代码如此重要的原因……
  • Eugene、Holger、Roland - 感谢所有帮助人员,所有这些解决方案都非常有效。再次感谢!
【解决方案2】:

你的问题很可能在这里:

 s -> s.stream().map(Double.class::cast)

您的detailIdLong 类型;但您正试图将其转换为Double

【讨论】:

  • 但不是从 long 转换为 double 有效。请让我知道我缺少什么,还有其他方法可以做到这一点。
  • 从基本类型long 转换为基本类型double 是有效的,但从Long 转换为Double 是无效的,因为Long 不是@987654330 的子类@。您可以改用.map(Long::doubleValue)
  • @liksar 这些是Objects,您不能简单地从一个转换到另一个(不解释原因 - 关于此的信息很多)。此外,您可能在谈论wideningnarrowing,它们适用于简单类型,而不适用于对象。
  • @Holger 这是合法的 - 但可能很可能会丢失精度,但数字必须非常大。
  • @Eugene:无论如何,当您将它们总结为double 值时,这并不重要。无论如何,使用 sum 作为映射键几乎没有意义……
【解决方案3】:

几乎是my answer to your other question的副本:

double maxPrice = details.stream()
  .mapToDouble(detail -> Stream.concat(Stream.of(detail.getDetailsId()),
                                       detail.getStackableDetails().stream())
    .flatMap(detailId -> details.stream()
      .filter(candidateDetail -> detailId.equals(candidateDetail.getDetailsId())))
    .map(Detail::getPrice)
    // the applied transformation function of your String price to double:
    .mapToDouble(Double::parseDouble) 
    .sum()
  )
  .max()
  .orElse(0.0);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-06
    相关资源
    最近更新 更多