Java 如何检查是否有任何多个“;“错误”;布尔人是真的吗?
我在Java 如何检查是否有任何多个“;“错误”;布尔人是真的吗?,java,multithreading,for-loop,while-loop,boolean,Java,Multithreading,For Loop,While Loop,Boolean,我在ArrayList下有许多*电话项目:电话,数据类型为PhoneX1 .moved()移动手机时返回true for (PhoneX1 aPhone : thePhones) { while (!aPhone.moved()) { Thread.sleep(1000); } System.out.println(aPhone + " Moved") ... 通过等待aPhone被迭代移动,并输出预期的内容,上述代码成功运行。但是,我希望程序
ArrayList
下有许多*电话项目:电话
,数据类型为PhoneX1
.moved()
移动手机时返回true
for (PhoneX1 aPhone : thePhones) {
while (!aPhone.moved()) {
Thread.sleep(1000);
}
System.out.println(aPhone + " Moved")
...
通过等待aPhone
被迭代移动,并输出预期的内容,上述代码成功运行。但是,我希望程序能够计算出何时移动了一个错误的电话(其中不等于aPhone
),这样程序就可以输出类似于“错误的电话移动,程序终止”和“终止”的内容。例如,如果希望移动手机中的第一部手机,但移动了任何其他手机,则程序应终止
所指的手机是旧iPhone 您可以在while循环中使用流执行以下操作:
thePhones.stream().filter(e -> !e.equals(aPhone)).anyMatch(PhoneX1::moved)
如果移动了列表中的任何其他手机,则返回true:
while (!aPhone.moved()) {
if(thePhones.stream().filter(e -> !e.equals(aPhone)).anyMatch(PhoneX1::moved)) {
//Do something
}
Thread.sleep(1000);
}
我希望该程序能够计算出何时移动了一个错误的电话,其中一个电话不等于一个电话,这样该程序就可以输出这样的内容:“移动了错误的电话。”
这里的aPhone实际上是PhoneX1类型的集合,因此不清楚如何获得与集合的泛型类型不匹配的内容
所指的手机是旧iPhone
我的建议是在类PhoneX1中包含一个布尔变量,比如
bool isOldIphone = false;
然后从您的驱动程序中检查手机的类型,无论是旧的还是新的,并执行您的逻辑
ArrayList<PhoneX1> oldPhones = thePhones.stream().filter(e -> e.isOldIphone); //this returns a list of old phones
如果我正确地理解了任务,那么你基本上想要“监视”电话的移动,当它们没有按正确的顺序移动时,把它看作是一个错误。这意味着你必须单独监视每个电话的状态,假设由<代码> MODE()返回的状态。
方法可能在任何时间点更改
如果这是正确的,那么一种方法是:
- 定义要移动的手机的预期顺序(这是它们在列表中的顺序)
- 对于每部手机,安排一项监视手机状态的任务
- 如果任务检测到手机已移动,请将其放入(阻止)队列
- 等待每部手机进入队列,并验证它们是否按预期顺序出现在队列中
这是在这里实现的,以展示基本思想。根据轮询频率等,可能会有一些警告,但我认为这可能是一种合理的方法。可能会有其他实现(例如使用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();
}
}
}
}
什么时候手机会被归类为移动错误?我们能看到你的PhoneX1类吗?@Frost.moved()
仅指实际移动手机。手机可能已移动,也可能未移动。我正在使用一个库/软件包,因此不相信这是可能的。您正在使用哪个库修复了我自己的代码中的一个问题,该功能现在可以完美运行。非常感谢!还教了我有关流的知识!:)
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