在ArrayList
:thePhones
下,我有许多* phone项,数据类型为PhoneX1
。
.moved()
返回true
。
for (PhoneX1 aPhone : thePhones) {
while (!aPhone.moved()) {
Thread.sleep(1000);
}
System.out.println(aPhone + " Moved")
...
上面的代码通过等待aPhone
被迭代移动并输出期望的内容而成功工作。但是,我希望该程序找出何时移动了不等于aPhone
的错误电话,以便该程序可以输出以下内容:“移动了错误的电话,程序已终止”,然后终止。例如,如果thePhones
中的第一个电话被移动了 expected ,但其他任何电话被移动了,则程序应终止。
所引用的电话是旧的iPhone。
答案 0 :(得分:2)
您可以在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);
}
答案 1 :(得分: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
答案 2 :(得分:0)
我希望程序找出移动不正确的电话(不等于aPhone)的时间,以便程序可以输出以下内容:“移动了错误的电话
这里的aPhone实际上是PhoneX1类型的集合,因此尚不清楚如何获得与集合的通用类型不匹配的东西。
所引用的电话是旧的iPhone。
我的建议是,您的类PhoneX1包含一个布尔变量say
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"));