当前位置: 首页 > 知识库问答 >
问题:

检查是否全部为真,并使用Java8的单行lambda表达式重置布尔[]数组

牛智志
2023-03-14

假设我有一个巨大的Booleanarrayflags

Boolean[] flags = { true, false, true };    // 3 means "many"

我想在标志上做两件事:

  • 检查所有元素是否true并返回一个指示器

使用Java 8的lambda表达式,我可以如下所示:

indicator = Arrays.stream(flags).allMatch(flag -> flag);
Arrays.stream(flags).forEach(flag -> flag = false);
return indicator;

然而,此实现扫描标志两次。因为标志是巨大的,我不想要这个。此外,我更喜欢lambda方式。有没有办法实现这个check IfAllTrueAndReset语义学与(一行)lambda表达式扫描标志只有一次?

相关但不相同:检查布尔数组中的所有值是否为真的最优雅的方法是什么?

注:我从评论和回答中学到了很多。谢谢大家!!

  1. Stream很酷,但不是为了这个

共有3个答案

戚研
2023-03-14

对于streams和lambdas来说,这是一个糟糕的匹配,并且没有真正好的方法来做到这一点。

问题是蒸汽处理集合的元素,但您需要修改实际集合。

我认为你最好用一个旧的循环学校来做这件事。

一个不太好的解决方案是在数组的索引上获得一个流,并使用其中的foreach在数组上循环。如果所有元素都是true,则可以使用原子布尔值来存储。这可以并行运行,但我认为普通的for循环更好。

例子:

Boolean[] flags = { true, true, true };  

AtomicBoolean allTrue = new AtomicBoolean(true);
IntStream.range(0, flags.length)
    .forEach(ix -> {
        if (!flags[ix]) allTrue.set(false);
        flags[ix] = false;
    });

在问题的评论中提到,它可能是有趣的原子布尔的解决方案。在这种情况下,使用流的解决方案是可能的,因为可以重置元素而无需修改原始集合。

然而,这个解决方案确实值得怀疑,所以最好不要使用它。问题是map用于副作用(重置值)和映射操作(提取旧值)。我认为并行运行它是可能的,但是它可能比普通的for循环慢,因为每个元素上的操作都很小。

还要注意的是,不能使用allMatch,因为该操作是短路操作,如果发现false将终止,后续元素将不会重置。

AtomicBoolean[] flags = { new AtomicBoolean(true), new AtomicBoolean(false), new AtomicBoolean(true) };  

boolean allTrue = Stream.of(flags)
    .map(b -> b.getAndSet(false))
    .reduce(true, (a, b) -> a && b);
薛文斌
2023-03-14
匿名用户

如果你真的想在一行中使用流,那么你可以这样做

boolean allTrue = IntStream.range(0, flags.length).reduce(0,
    (result, i) -> flags[i] ^ (flags[i] = false) ? result : 1) == 0;

然而,这看起来不是一个好主意,我倾向于使用@MarounMaroun建议的BitSet

窦国源
2023-03-14

使用位集类的经典示例:

此类实现了一个根据需要增长的位向量。位集的每个组件都有一个布尔值。

就复杂性而言,BitSet为每个boolean值使用~1位,这比使用大型boolean对象数组要好得多。

关于检查是否设置了所有位(true或false),API提供了许多有用的方法——它们非常有效。

 类似资料:
  • 我最近接触了Java8,我正在尝试学习Lambda表达式。我想做一些图形计算,我的代码到目前为止: 所有这些代码都是用于图形的,除了和使用的操作之外,所有内容都是基本的数学(加、减、乘、模),并且可以单独针对每个像素执行。 现在的问题是:有可能在GPU上运行这个吗?或者这甚至是自动基于GPU的?(我记得在什么地方读到过这个,但我不确定)

  • 我是Java8的新手,正在学习lambda表达式。 我有接口。 检查配置是否为空,返回空字符串。 检查集合是否为空,返回空字符串。 如果collection不为null,并且key存在,则返回值else return“”; 在Java8中如何做到这一点? 试过这个: 也发布了Java7代码,我试图用lambda表达式解决Java7的if-else部分。

  • 1 Java8 Lambda表达式的介绍 Lambda表达式是Java8中包含的一项新的重要功能。它提供了一种简洁明了的方式来使用表达式表示一个方法接口。在Collection集合中非常有用。它有助于集合元素的迭代,过滤和从集合中提取数据。 Lambda表达式用于提供具有功能接口的接口的实现。它节省了大量代码。在使用Lambda表达式的情况下,我们无需再次定义用于提供实现的方法。我们只编写实现代码

  • 问题内容: 具体来说,我有TabPane,我想知道其中是否包含具有特定ID的元素。 因此,我想使用Java中的lambda表达式来做到这一点: 问题答案: 尝试使用Lambda表达式。这是更好的方法。

  • 具体来说,我有TabPane,我想知道其中是否有具有特定ID的元素。 所以,我想用Java中的lambda表达式来实现这一点:

  • 问题内容: 一位访问员最近问我这个问题:给定三个布尔变量a,b和c,如果三个变量中至少有两个是true,则返回true。 我的解决方案如下: 他说,这可以进一步改善,但是如何呢? 问题答案: 而不是写: 写: 至于表达式本身,是这样的: 或此(无论您觉得更容易掌握): 它测试和准确一次,最多一次。 参考文献 JLS 15.25条件运算符?: