【问题标题】:Java 8 Stream filter using list as condition使用列表作为条件的 Java 8 流过滤器
【发布时间】:2019-01-26 11:18:58
【问题描述】:

您好,我是 Java 8 的初学者,所以请耐心等待 :)

我有一个返回自定义对象列表的方法。我需要做的:我有一个disabledPaymentTypesStrings 的列表——我不知道它有多少元素。我怎样才能改变我的代码,以免写出像!paymentType.getName().equalsIgnoreCase(disabledPaymentTypesStrings.get(1))这样的每一个条件?我想以某种方式将我的整个列表“disabledPaymentTypesStrings”作为条件放在这里,但我不知道该怎么做。请给我一些提示或建议:)

private List<PaymentType> listOfPaymentTypesForChangePayment(OrderPaymentTypeParameters paymentTypeParameters) {

        List<String> disabledPaymentTypesStrings = newArrayList(Splitter.on(COMMA).split(systemUtils.getChangePaymentTypeDisabled()));

        return paymentTypeSelector.availablePaymentTypesForChangePayment(paymentTypeParameters).stream()
            .filter(paymentType ->
                !paymentType.getName().equalsIgnoreCase(disabledPaymentTypesStrings.get(0)) &&
                !paymentType.getName().equalsIgnoreCase(disabledPaymentTypesStrings.get(1)) &&
                !paymentType.getName().equalsIgnoreCase(disabledPaymentTypesStrings.get(2)))
            .collect(toList());
    }

【问题讨论】:

  • 考虑将您的付款类型表示为枚举而不是字符串。使用集合而不是列表。

标签: java filter java-8 java-stream


【解决方案1】:

流式方法可以包括在filter() 中流式传输字符串列表并保留PaymentType 元素,其中paymentType.getName() 与字符串列表的任何元素都不匹配:

return paymentTypeSelector.availablePaymentTypesForChangePayment(paymentTypeParameters)
        .stream()
        .filter(paymentType -> disabledPaymentTypesStrings.stream()
               .allMatch(ref -> !ref.equalsIgnoreCase(paymentType.getName())))
        .collect(toList());

但您也可以使用相同的大小写来比较Strings。例如小写。它将简化过滤。

您可以将引用列表元素转换为小写:

List<String> disabledPaymentTypesStrings = newArrayList(Splitter.on(COMMA).split(systemUtils.getChangePaymentTypeDisabled()))
 .stream()
 .map(String::toLowerCase)
 .collect(toList());

您可以在filter() 中使用List.contains()

return paymentTypeSelector.availablePaymentTypesForChangePayment(paymentTypeParameters)
    .stream()
    .filter(paymentType -> !disabledPaymentTypesStrings.contains(paymentType.getName().toLowerCase()))
    .collect(toList());

请注意,对于大型列表,使用 Set 会更有效。

【讨论】:

  • 为了完整起见,请注意:将disabledPaymentTypesStrings 转换为List 并在其上调用contains 意味着disabledPaymentTypesStrings 确实有3 个元素。关于问题中的代码,可能有超过 3 个元素,但只比较前 3 个元素。第二个注意事项:就像@RealSkeptic 在他的评论中建议的那样,在调用contains 时使用Set 更合适。
【解决方案2】:

使用contains()。但是你必须考虑忽略大小写

private List<PaymentType> listOfPaymentTypesForChangePayment(OrderPaymentTypeParameters paymentTypeParameters) {

            List<String> disabledPaymentTypesStrings = newArrayList(Splitter.on(COMMA).split(systemUtils.getChangePaymentTypeDisabled()));

            return paymentTypeSelector.availablePaymentTypesForChangePayment(paymentTypeParameters).stream()
                .filter(paymentType -> !disabledPaymentTypesStrings.contains(paymentType)
                .collect(toList());
        }

【讨论】:

    【解决方案3】:

    这两个步骤都需要有普通大小写的值(大写或小写,我更喜欢小写)

    List<String> disabledPaymentTypesStringsLowerCase = newArrayList(Splitter.on(COMMA).split(systemUtils.getChangePaymentTypeDisabled()))
     .stream()
     .map(String::toLowerCase)
     .collect(toList());
    
    return paymentTypeSelector.availablePaymentTypesForChangePayment(paymentTypeParameters)
        .stream()
        .map(paymentType -> paymentType.getName())
        .map(String::toLowerCase)
        .filter(disabledPaymentTypesStrings::contains)
        .collect(toList());
    

    如果 paymentType 类已知,则此代码可以进一步重构,假设 paymentType 类为 PaymentType,代码如下所示,

    return paymentTypeSelector.availablePaymentTypesForChangePayment(paymentTypeParameters)
        .stream()
        .map(PaymentType::getName)
        .map(String::toLowerCase)
        .filter(disabledPaymentTypesStrings::contains)
        .collect(toList());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      相关资源
      最近更新 更多