【问题标题】:Check if all items in a list are set to the same boolean value检查列表中的所有项目是否设置为相同的布尔值
【发布时间】:2019-08-29 23:27:30
【问题描述】:

我有一个 ArrayList,每次运行程序时都会由随机数量的 GameObj 实例填充。

如果一个对象与 ArrayList 中的另一个对象接触,它将设置一个名为 visible 的布尔值,从 true 到 false。

有没有办法通过以下方式检查ArrayList中的所有item实例是否都设置为false:

XXXX.visible = false

一旦我可以检查它们是否都设置为false。

【问题讨论】:

  • list.stream().allMatch
  • bool allBricks = true; for(GameObj brick : yourList) { if(brick.visible) { allBricks = false; break; } } if(allBricks) { System.out.println("Well Done, Game over."); }
  • 在这种情况下,另一种方法是设置一个计数器,例如int bricksHits,当砖块被击中时它会增加。然后你可以使用一个简单的 if 语句,例如if(bricksHit >= totalBricks) { ... },它只检查一次,而不是循环整个列表(在最坏的情况下)。
  • 是的,让我们把函数式编程解决方案交给Boolean 和ArrayList 的新手。

标签: java arraylist


【解决方案1】:

您可以使用Stream.noneMatch() 来执行此操作:

if (bricks.stream().noneMatch(GameObj::isVisible)) {
    doStuffIfAllBricksAreInvisible();
}

如果所有砖块都不可见,则返回 true。

此外,我建议查看Stream.allMatch(),如果列表的所有元素都与给定的谓词匹配,则返回 true。

使用allMatch() 如下所示:

if (bricks.stream().allMatch(b -> !b.isVisible())) {
    doStuffIfAllBricksAreInvisible();
}

要完成此操作,您还可以查看Stream.anyMatch(),如果其中一个元素与给定谓词匹配,则返回 true。

【讨论】:

  • @HBU 您必须调整这部分以适应您对 GameObj 的需求。你能把这个添加到你的问题中吗?我也更新了我的帖子。
  • 不要使用公共字段,最好为它创建一个getter。或者,您可以使用 b -> b.visible 代替方法参考。
  • 那是教条式的 Java,但它没有任何意义。如果您有需要公开的内容,请删除样板代码并将其公开。抽象是值得的论点,因为您可以更改 getIsVisible 的实现实际上从未发生过。我唯一会使用该样板代码的地方是与一个库交互时,该库的行为通过诸如 Hibernate 之类的方法起作用。最糟糕的是 POJO,它是记住解决方案并误用它而不是编写干净代码的缩影。
【解决方案2】:

如果您使用的是 Java

flag 从 true 变为 false 时,将计数减 1。如果 flag 已经为 false,则什么也不做。现在您可以检查计数是否为 0。

如果计数为 0,则打印“干得好,游戏结束”,否则继续游戏。

对于 Java 8 或更高版本,您可以按照其他答案中的建议使用流 API。

【讨论】:

  • 请谨慎对待这样的解决方案,因为每个实例都在更改相同的变量,并且很可能需要线程安全的解决方案。
【解决方案3】:

我建议使用 anyMatch,因为当列表为空时 allMatch 方法返回 true

if (!bricks.stream().anyMatch(GameObj::isVisible)) {
    // TODO when visible balls not found (all are invisible)
}

【讨论】:

  • 虽然您提出了一个很好的观点,但这将归结为他的用例、速度需求和设计是什么。例如,他可能希望一个空的List 返回true 或false,或者可以保证它永远不会为空。至于在游戏设计中经常发挥作用的速度,带有break 的简单 for 循环比函数式解决方案要快得多。众所周知,Java 的函数式接口在处理小型 ArrayList 时比循环替代方案慢得多。
【解决方案4】:

检查List 的boolean 值是否都是true 或至少一个值是false

        List<Boolean> booleans = new ArrayList<>();
            
        booleans.add(false);
        booleans.add(true);
        booleans.add(true);
        booleans.add(true);
            
        boolean areAllTrue = booleans.stream().allMatch(Boolean::booleanValue);
        // equivalent to:
        boolean areAllTrue = booleans.stream().allMatch(b -> b);

重要提示:如果booleans.size() 为零; allMatch() 的结果始终是 true。所以你必须先检查大小,或者根据你的上下文需要。

【讨论】:

    【解决方案5】:

    如果您是 Java 新手,您可能希望使用这样的 for 循环:

    bool allFalse = true;
    for(int index = 0; index < arrayList.size(); ++index)
        if(arrayList[index].visible) {
            allFalse = false;
            break;
        }
    

    break; 在找到第一个真值后立即终止 for 循环,因为您不再需要检查。

    如果您知道arrayList 不为空,这将起作用,但将allFalse 设置为空List 可能是有意义的,因为不存在的东西既不是真也不是假。

    对于检查 ArrayList 中元素不多的内容,带有 break 的 for 循环也将比 Stream 快得多。虽然在可读性和可维护性至关重要的情况下,这可能并不重要,但在游戏中通常很重要,特别是如果他经常进行此检查。但是,这取决于他的用例。速度可能并不重要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 2012-07-01
      • 1970-01-01
      • 2016-02-16
      • 2021-03-12
      相关资源
      最近更新 更多