如何检查任何多个“错误”布尔值是不是为真?

Posted

技术标签:

【中文标题】如何检查任何多个“错误”布尔值是不是为真?【英文标题】:How to check if any multiple "wrong" booleans are true?如何检查任何多个“错误”布尔值是否为真? 【发布时间】:2019-04-07 19:24:36 【问题描述】:

我有一些*电话项目,在 ArrayList:thePhones 下,数据类型为 PhoneX1

.moved() 在手机移动时返回true

for (PhoneX1 aPhone : thePhones) 
    while (!aPhone.moved()) 
        Thread.sleep(1000);
     
    System.out.println(aPhone + " Moved")
    ...

上面的代码成功运行,等待aPhone被迭代移动,并输出预期的内容。但是,我希望程序能够确定何时移动了不等于aPhone 的错误电话,以便程序可以输出类似以下内容的内容:“移动了错误的电话,程序终止。” ,并终止。例如,如果thePhones 中的第一个电话预计会被移动,但任何其他电话都被移动了,那么程序应该终止。

所指的手机是旧 iPhone。

【问题讨论】:

手机什么时候被归类为错误移动?我们可以看看你的 PhoneX1 课程吗? @Frost .moved() 只是指物理移动手机。它要么被移动,要么没有。 【参考方案1】:

您可以在 while 循环中使用流来执行以下操作:

thePhones.stream().filter(e -> !e.equals(aPhone)).anyMatch(PhoneX1::moved)

如果List 中的任何其他电话已被移动,则返回 true:

while (!aPhone.moved()) 
    if(thePhones.stream().filter(e -> !e.equals(aPhone)).anyMatch(PhoneX1::moved)) 
       //Do something
    
    Thread.sleep(1000);
  

【讨论】:

修复了我自己的代码的问题,现在可以完美运行。太感谢了!还教我有关流的知识! :)【参考方案2】:

如果我正确理解了任务,那么您基本上是想“监控”手机的移动,并在它们没有按正确顺序移动时将其视为错误。这意味着您必须单独监控每部手机的状态,假设moved() 方法返回的状态可能随时更改。

如果这是正确的,那么一种方法是:

定义要移动的电话的预期序列(这是它们在列表中的序列) 为每部手机安排一个监控手机状态的任务 如果任务检测到手机被移动,则将其放入(阻塞)队列 等待每部手机进入队列,并验证它们是否按预期顺序出现

这里实现,展示基本思想。可能会有一些警告,具体取决于轮询频率等,但我认为这可能是一种合理的方法。不过,替代实现(例如使用ExecutorCompletionService)可能是可能的:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

public class PhoneMoveDetector

    // Dummy phone class that changes its "moved()" state after a certain time
    private static class PhoneX1
    
        private final String name;
        private volatile boolean moved = false;

        PhoneX1(String name, long delayMs)
        
            this.name = name;
            Thread t = new Thread(() -> 
            
                try
                
                    Thread.sleep(delayMs);
                
                catch (InterruptedException e)
                
                    Thread.currentThread().interrupt();
                
                System.out.println("Moving " + this);
                moved = true;
            );
            t.start();
        

        boolean moved()
        
            return moved;
        

        @Override
        public String toString()
        
            return name;
        
    

    public static void main(String[] args)
    
        checkRightMoveOrder();
        detectWrongMoveOrder();
    

    private static void checkRightMoveOrder()
    
        List<PhoneX1> phones = new ArrayList<PhoneX1>();
        phones.add(new PhoneX1("A", 1500));
        phones.add(new PhoneX1("B", 3000));
        phones.add(new PhoneX1("C", 4500));
        phones.add(new PhoneX1("D", 6000));

        MoveDetector moveDetector = new MoveDetector(phones);

        System.out.println("Checking right move order");
        for (PhoneX1 phone : phones)
        
            try
            
                moveDetector.waitForExpectedToMove();
            
            catch (InterruptedException e)
            
                Thread.currentThread().interrupt();
                return;
            
            System.out.println("Moved " + phone);
        
    

    private static void detectWrongMoveOrder()
    
        List<PhoneX1> phones = new ArrayList<PhoneX1>();
        phones.add(new PhoneX1("A", 1500));
        phones.add(new PhoneX1("B", 3000));
        phones.add(new PhoneX1("C", 2000)); // Should be moved later
        phones.add(new PhoneX1("D", 6000));

        MoveDetector moveDetector = new MoveDetector(phones);

        System.out.println("Detecting wrong move order");
        for (PhoneX1 phone : phones)
        
            try
            
                moveDetector.waitForExpectedToMove();
            
            catch (InterruptedException e)
            
                Thread.currentThread().interrupt();
                return;
            
            System.out.println("Moved " + phone);
        
    


    private static class MoveDetector
    
        private final Queue<PhoneX1> expectedPhones;
        private final BlockingQueue<PhoneX1> movedPhones;

        MoveDetector(List<PhoneX1> phones)
        
            expectedPhones = new LinkedList<PhoneX1>(phones);
            movedPhones = new LinkedBlockingDeque<PhoneX1>();
            ExecutorService executor = Executors.newCachedThreadPool();
            List<Callable<Object>> observers = 
                new ArrayList<Callable<Object>>();
            for (PhoneX1 phone : phones)
            
                Runnable r = () ->
                
                    while (!phone.moved())
                    
                        try
                        
                            Thread.sleep(50);
                        
                        catch (InterruptedException e)
                        
                            Thread.currentThread().interrupt();
                            return;
                        
                    
                    movedPhones.offer(phone);
                ;
                observers.add(Executors.callable(r));
            
            Thread t = new Thread(() -> 
            
                try
                
                    executor.invokeAll(observers);
                    executor.shutdownNow();
                
                catch (InterruptedException e1)
                
                    Thread.currentThread().interrupt();
                
            );
            t.start(); 
        

        void waitForExpectedToMove() throws InterruptedException
        
            PhoneX1 moved = movedPhones.take();
            PhoneX1 expected = expectedPhones.peek();
            if (!Objects.equals(expected, moved))
            
                System.out.println("Moved " + moved + ", but expected " 
                    + expected + " - ERROR!");
                // Handle this case as desired, e.g. by doing a
                // throw new IllegalStateException();
            
            else
            
                System.out.println("Moved " + moved + ", as expected");
                expectedPhones.remove();
            
        
    

输出显示在这里:

Checking right move order
Moving A
Moved A, as expected
Moved A
Moving B
Moved B, as expected
Moved B
Moving C
Moved C, as expected
Moved C
Moving D
Moved D, as expected
Moved D

Detecting wrong move order
Moving A
Moved A, as expected
Moved A
Moving C
Moved C, but expected B - ERROR!
Moved B
Moving B
Moved B, as expected
Moved C
Moving D
Moved D, but expected C - ERROR!
Moved D

【讨论】:

【参考方案3】:

我希望程序能够确定何时移动了不等于 aPhone 的错误电话,以便程序可以输出类似以下内容的内容:“移动了错误的电话

您的 aPhone 实际上是一个 PhoneX1 类型的集合,因此不清楚您如何获得与您的集合的通用类型不匹配的东西。

所指的手机是旧 iPhone。

我的建议是在你的 PhoneX1 类中包含一个布尔变量,比如

bool isOldIphone = false;

然后从您的驱动程序中检查手机的类型是旧的还是新的并执行您的逻辑

ArrayList<PhoneX1> oldPhones = thePhones.stream().filter(e -> e.isOldIphone);     //this returns a list of old phones

然后您可以继续执行您的逻辑,例如说

oldPhones.forEach(System.out.println("old phone moved"));

【讨论】:

我正在使用库/包,所以不要相信这是可能的 你使用的是哪个库

以上是关于如何检查任何多个“错误”布尔值是不是为真?的主要内容,如果未能解决你的问题,请参考以下文章

检查数组中的所有布尔值是不是为真?

检查三个布尔值中的两个是不是为真?

检查数组中的所有值是不是为真,然后返回一个真布尔语句(javascript)[重复]

C# 三个布尔值,一次为真 [关闭]

检查是不是设置了 Javascript 布尔值? [复制]

如果数组中的所有值都为真(字符串)并且其中一个值为假(字符串),则如何返回布尔值 true 停止使用 Javascript 进行检查