【问题标题】:How to use a lambda to filter a boolean array in Java如何使用 lambda 在 Java 中过滤布尔数组
【发布时间】:2019-08-29 06:26:45
【问题描述】:

我想用"||" 分割一个字符串,并计算结果数组中有多少元素返回true 用于函数boolean isValid(String[] r)

我正在尝试使用Arrays.stream 来评估和过滤数组,最后过滤结果数组以仅保留真实值。

boolean[] truthSet = Arrays.stream(range.split("\\s+))
                           .map(r -> isValid(r))
                           .filter(b -> _whatGoesHere_)
                           .toArray(boolean[]::new);

代替_whatGoesHere,我尝试使用bb == true,但无济于事。实现这一目标的正确方法是什么?

【问题讨论】:

  • “无济于事” - 为什么?结果如何?
  • @SharonBenAsher 好吧,我可能会过早地假设,但我的 IDE 认为它是“lambda 表达式中的错误返回类型。对象无法转换为布尔值”
  • 错误不是由b -> b引起的。你应该阅读它。并张贴。它与尝试从Stream<java.lang.Boolean>(objects) 创建一个boolean (primitive types) 数组有关。无论如何,创建一个只有真值的数组有什么意义?流的大小不会传达相同的信息吗? (即有 N 个有效字符串)?
  • 不需要map元素;你可以直接使用filterArrays.stream(...).filter(str -> isValid(str)).count()

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


【解决方案1】:

您可以简单地传递自己,lambda 看起来像 b -> b(因为它已经是一个布尔值:

 Boolean[] truthSet = Arrays.stream(range.split("\\s+"))
                       .map(r -> isValid(r))
                       .filter(b -> b)
                       .toArray(Boolean[]::new);

但是你得到的只是值,即true 并将它们打包到数组中——这将产生一个布尔数组,除了true 值之外什么都没有。也许你的意思是:

 String[] validStrings = Arrays.stream(range.split("\\s+"))
                       .filter(r -> isValid(r))
                       .toArray(String[]::new);

P.S.:要计算值,您可以使用Stream#count

【讨论】:

  • 第一部分根本没有回答这个问题。
  • .toArray(boolean[]::new); 不起作用,因为此时的类型是 Stream<Boolean>。您可以使用 Boolean 代替原始类型...
  • 这将返回一个全为“真”的数组 - 那么有什么区别呢?
  • 是的,我打算将其转换为布尔数组,但这也有效。我最终想计算为 isValid 返回true 的项目数,所以这也有效。虽然,我很好奇,如果我确实想要一个布尔数组,我会怎么做?
  • @GothamCityRises,要计算不需要收集到数组的项目数,可以使用Stream.count()Collectors.counting() 方法。您需要编辑问题并说明确切的要求是什么
【解决方案2】:

如果您只想计数,则可以使用简单的Stream#count

long count = Arrays.stream(range.split("\\s+"))
                       .map(r -> isValid(r))
                       .filter(b -> b)
                       .count();

而且由于没有像IntStream, DoubleStream 这样的BooleanSteram,所以你不能转换Stream<Boolean> to boolean[],在这种情况下,你必须使用Boolean[]

Boolean[] truthSet = Arrays.stream(range.split("\\s+"))
                           .map(r -> isValid(r))
                           .filter(b -> b)
                           .toArray(Boolean[]::new); 

【讨论】:

  • filter(b -> b) 会编译吗?
  • 是的,它会编译并正常工作。我相信你的 isValid(r) 方法返回一个 boolean
【解决方案3】:

我希望这是你想要的

   Boolean[] truthSet = Arrays.stream(range.split("\\s+"))
            .filter(r -> isValid(r))
            .map(s -> Boolean.TRUE)
            .toArray(Boolean[]::new);

【讨论】:

    【解决方案4】:

    如果我正确阅读了问题,OP 会要求用 '||' 分割并且正在寻找计数,因此(最小)可行的解决方案如下所示:

    import java.util.regex.Pattern;
    
    class Scratch {
        public static void main(String[] args) {
            String test = "||a||a||b||a||bn";
    
            long count = Pattern.compile("\\|\\|")
                    .splitAsStream(test)
                    .filter(Scratch::isValid)
                    .count();
    
            System.out.println(count);
        }
    
        private static boolean isValid(String r) {
            return "a".equals(r);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-29
      • 2015-08-30
      • 1970-01-01
      • 1970-01-01
      • 2014-05-11
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 2021-05-31
      相关资源
      最近更新 更多