我有以下代码来实现电梯:
public class Elevator{
Direction dir;
int floorNum;
int capacity;
public void moveUp{
dir = Direction.Up;
}
public void moveDown{
dir = Direction.Down
}
public boolean isMoving{
returns dir.equals(Direction.STATIONARY);
}
}
public class ElevatorController{
Elevator[] elevators;
PriorityQueue<Integer> queue = new PriorityQueue<Integer>;
public void buttonPressed{Direction d, int fromFloot, int toFloor){
}
}
我读到一个实现电梯的好方法是实现一个优先队列来获得电梯,但我不确定如何。
队列将包含目标层。
你建议如何实现它?
一种可能性是使用两个单独的TreeSets来订购楼层,up
和down
。如果你要在currentFloor
之上添加一层,那么将其添加到up
中,如果你要在currentFloor
之下添加一层,那么将其添加到down
中;如果你添加了一个等于currentFloor
的地板,那么就丢弃它。TreeSet自动丢弃重复项。当确定要访问的下一层时,如果方向== UP,则访问up
中的下一个最低层,如果方向== DOWN,则访问down
中的下一个最高层。
或者,你可以使用一个单独的TreeSet,并尝试想出一个聪明的Comparator来考虑电梯的方向,但这似乎比它的价值更多的麻烦。
private TreeSet<Integer> up = new TreeSet<>(); // floors above currentFloor
private TreeSet<Integer> down = new TreeSet<>(); // floors below currentFloor
private int currentFloor = 0;
private Enum direction = direction.UP;
public void addFloor(int f) {
if(f < currentFloor) {
down.add(f);
} else if(f > currentFloor) {
up.add(f);
}
// else f == currentFloor, so don't add the floor to either queue
}
public int nextFloor() {
if(direction == direction.DOWN) {
return down.pollLast(); // highest floor in down, or null if empty
} else {
return up.pollFirst(); // lowest floor in up, or null if empty
}
}
我尝试使用单个TreeSet
实现电梯。
这是一个完整的解决方案:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.TreeSet;
public class MyLift {
public static void main(String[] args) {
System.out.println("Welcome to MyLift");
// RequestListenerThread to read requested floor and add to Set
Thread requestListenerThread = new Thread(new RequestListener(),
"RequestListenerThread");
// RequestProcessorThread to read Set and process requested floor
Thread requestProcessorThread = new Thread(new RequestProcessor(),
"RequestProcessorThread");
requestListenerThread.start();
requestProcessorThread.start();
}
}
class Elevator {
private static Elevator elevator = null;
private static TreeSet<Integer> requestSet = new TreeSet<Integer>();
private int currentFloor = 0;
private Direction direction = Direction.UP;
private Elevator() {
};
/**
* @return singleton instance
*/
static Elevator getInstance() {
if (elevator == null) {
elevator = new Elevator();
}
return elevator;
}
/**
* Add request to Set
*
* @param floor
*/
public synchronized void addFloor(int f) {
requestSet.add(f);
// Notify the thread that a new request has come.
notify();
}
/**
* @return next request to process based on elevator current floor and
* direction
*/
public synchronized int nextFloor() {
Integer floor = null;
if (direction == Direction.UP) {
if (requestSet.ceiling(currentFloor) != null) {
floor = requestSet.ceiling(currentFloor);
} else {
floor = requestSet.floor(currentFloor);
}
} else {
if (requestSet.floor(currentFloor) != null) {
floor = requestSet.floor(currentFloor);
} else {
floor = requestSet.ceiling(currentFloor);
}
}
if (floor == null) {
try {
System.out.println("No Request to process. Waiting");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("Processing Request : " + floor);
requestSet.remove(floor);
}
return (floor == null) ? -1 : floor;
}
public int getCurrentFloor() {
return currentFloor;
}
/**
* Set current floor and direction based on requested floor
*
* @param currentFloor
*/
public void setCurrentFloor(int currentFloor) {
if (this.currentFloor > currentFloor) {
setDirection(Direction.DOWN);
} else {
setDirection(Direction.UP);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.currentFloor = currentFloor;
System.out.println("Floor : " + currentFloor);
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
}
class RequestProcessor implements Runnable {
@Override
public void run() {
while (true) {
Elevator elevator = Elevator.getInstance();
int floor = elevator.nextFloor();
int currentFloor = elevator.getCurrentFloor();
if (floor >= 0) {
if (currentFloor > floor) {
while (currentFloor > floor) {
elevator.setCurrentFloor(--currentFloor);
}
} else {
while (currentFloor < floor) {
elevator.setCurrentFloor(++currentFloor);
}
}
}
}
}
}
class RequestListener implements Runnable {
@Override
public void run() {
while (true) {
String floorNumberStr = null;
try {
// Read input from console
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(System.in));
floorNumberStr = bufferedReader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if (isValidFloorNumber(floorNumberStr)) {
System.out.println("User Pressed : " + floorNumberStr);
Elevator elevator = Elevator.getInstance();
elevator.addFloor(Integer.parseInt(floorNumberStr));
} else {
System.out.println("Floor Request Invalid : " + floorNumberStr);
}
}
}
/**
* This method is used to define maximum floors this elevator can process.
* @param s - requested floor
* @return true if requested floor is integer and upto two digits. (max floor = 99)
*/
public boolean isValidFloorNumber(String s) {
return (s != null) && s.matches("\d{1,2}");
}
}
enum Direction {
UP, DOWN
}