【问题标题】:How to avoid defining single element array in java lambda expression如何避免在 java lambda 表达式中定义单元素数组
【发布时间】:2018-08-09 12:10:58
【问题描述】:

我已经编写了从列表中获取匹配某个条件的单个元素的代码段。有什么办法可以用相同类型的对象替换单个元素数组?

final PromoSlotSize[] slot = new PromoSlotSize[1];
promoSlotSizeList.stream()
    .filter(promoSlotSize -> promoSlotSize.getOfferSet().equals(Constants.HVT_RATE_OFFER_SET))
    .findFirst()
    .ifPresent(p-> slot[0] =p);

【问题讨论】:

  • 什么是PromoSlotSizepromoSlotSizeList!!
  • 为什么是 1 个元素的数组?而不仅仅是一个元素?
  • @azro 试试看...可能会抱怨final ;)

标签: java arrays java-8 java-stream optional


【解决方案1】:

您的方法似乎太过分了。请注意,使用

初始化数组
final PromoSlotSize[] slot = new PromoSlotSize[1];

将第一个也是唯一的元素 slot[0] = null 设为默认值。因此,您可以使用 Optional::orElse 再次使 Stream-API 返回第一个找到的对象 PromoSlotSizenull

slot[0] = promoSlotSizeList.stream()
              .filter(i-> i.getOfferSet().equals(Constants.HVT_RATE_OFFER_SET))
              .findFirst()
              .orElse(null);

正如 @YCF_L 所说:您是否认识到 Stream 返回一个可以直接使用的对象,而不是创建一个元素的数组?如果您不需要将数组作为另一个方法/类的输入,请执行以下操作:

PromoSlotSize slot = promoSlotSizeList.stream()
          .filter(i-> i.getOfferSet().equals(Constants.HVT_RATE_OFFER_SET))
          .findFirst()
          .orElse(null);

【讨论】:

  • 请注意,如果您不在乎获得哪个实例(在有多个匹配 filter() lambda 的情况下),.findAny()findFirst() 更有效。 findFirst() 处理整个流,然后返回找到的第一个,而 findAny() 将退出并在找到匹配元素后立即返回,丢弃流的其余部分。
  • @KevinSwan 有什么文件可以备份吗?
  • blog.codefx.org/java/stream-findfirst-findany-reduce "这两种方法都从流中返回任意元素——除非流有遇到顺序,在这种情况下 findFirst() 返回第一个元素。"
  • @KevinSwan 再次阅读了该博客并向我们展示了findFirst 将处理整个流的位置?
  • 如果指定了遇到顺序,那么它必须处理整个流。如果它没有检查整个列表,它如何在排序后返回“第一个”?如何确定列表中后面不存在其他元素会在当前“第一个”候选者之前? findAny() 允许实现执行短路评估并在找到匹配元素后立即终止,使其具有不确定性。这里没有实际意义,因为 OP 的示例没有指定遭遇顺序,但这是一个需要注意的重要区别。
【解决方案2】:

代码使用了一个技巧,因为只有(有效地)最终变量可以从外部在 lambda 中使用。因此,可以设置第一个元素的最终数组。 实际上,它使用命令式编码,带有循环和结果。

但是下面的要好得多。

Optional<PromoSlotSize> slot = promoSlotSizeList.stream()
                        .filter(i -> i.getOfferSet().equals(Constants.HVT_RATE_OFFER_SET))
                        .findAny();

slot.ifPresent(sl -> System.out.println("Slot present: " + sl));

因为可以并行化,所以boolean found + Slot result这两个属性合二为一。

【讨论】:

    【解决方案3】:

    一种方法是从PromoSlotSize 类的方法创建一个copy。该方法应采用 PromoSlotSize 对象的参数并使用给定的 PromoSlotSize 数据自行填充

    final PromoSlotSize slot = new PromoSlotSize();
    promoSlotSizeList.stream()
                .filter(promoSlotSize -> promoSlotSize.getOfferSet().equals(Constants.HVT_RATE_OFFER_SET))
                .findFirst().ifPresent(p-> slot.copy(p));
    

    假设 PromoSlotSize 是您编写的一个类,这应该可以让您摆脱单元素数组。

    【讨论】:

      猜你喜欢
      • 2018-09-30
      • 1970-01-01
      • 2020-07-26
      • 2014-09-16
      • 2014-06-30
      • 2017-04-16
      • 1970-01-01
      • 2021-01-12
      • 2021-10-19
      相关资源
      最近更新 更多