【问题标题】:Save a string from a list using streams使用流保存列表中的字符串
【发布时间】:2020-07-01 18:46:44
【问题描述】:

我正在尝试流式传输字符串列表。我知道我们可以这样做:

list.stream().filter(i -> !Stringutils.isempty(service.someMethod(i))).map(i -> service.someMethod(i)).findfirst().get();

问题是我需要调用service.someMethod 两次。

这里有什么建议可以避免service.someMethod 在过滤器中调用它两次并在映射中调用另一个?

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    您应该像这样反转映射和过滤器:

    list.stream() 
        .map(service::someMethod)
        .filter(s -> !Stringutils.isEmpty(s)) // or if it exists, StringUtils::isNotEmpty
        .findFirst()
        .get()
    

    【讨论】:

    • 或者,如果someMethod 永远不会返回null,则只需s -> !s.isEmpty()。事实上,即使该方法可以返回null,我也宁愿使用s -> s !=null && !s.isEmpty(),而不是添加一个第三方库依赖,使其无法识别是否需要null处理。
    • 我对您的评论很好,但我正在回答使用Stringutils 的问题(注意小写u:))。我个人会使用方法引用而不是 lambda,特别是对于常见的 String 相关代码,如果存在,请使用 common-lang3/4。
    【解决方案2】:

    我喜欢使用 java8 流,希望你也喜欢。

    您似乎想用someMethod 映射列表,然后过滤非空值,所以就这样做吧! 您唯一应该做的就是更改地图和过滤器的顺序。 更改顺序后, someMethod 只会被调用一次,因为我们映射它们一次并过滤映射的值。

    新代码将是这样的:

     String answer = list
           .stream()
           .map(a -> service.someMethod(a))
           .filter(a -> !a.isEmpty())
           .findFirst()
           .get();
    
    

    更好的是,您可以将 lambda 替换为方法参考

         .map(service::someMethod)
         // same as .map(a -> service.someMethod(a))
    

    (对不起我的英语)

    【讨论】:

    • 感谢您的详细解释。
    • 只是添加一个旁注,如果你使用JDK 11,请确保使用isBlank()方法stackoverflow.com/questions/51299126/…
    • @parrotjack 使用 isBlank() 仅在实际使用 isBlank() 的不同语义时才有意义。这里没有迹象表明,isBlank() 是有意的。
    • @Holger 是有道理的,但我刚才提到了更安全的一面。没有伤害。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 2016-10-21
    • 2021-06-14
    • 1970-01-01
    • 2014-03-16
    • 2011-01-15
    相关资源
    最近更新 更多