我有以下代码来实现Elevator:
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){
}
}
我读到一个实现电梯的好方法是实现一个优先级队列来获得电梯,但我不确定如何。
队列将包含目标楼层。
你会如何推荐实施它?
答案 0 :(得分:6)
一种可能性是使用两个单独的TreeSet来排序楼层up
和down
。如果您要在currentFloor
之上添加一个楼层,请将其添加到up
,如果您在currentFloor
下面添加一个楼层,则将其添加到down
;如果您添加等于currentFloor
的楼层,则将其丢弃。 TreeSet会自动丢弃重复项。在确定要访问的下一个楼层时,如果direction == UP,则访问up
中的下一个最低楼层,如果direction == DOWN,则访问down
中的下一个楼层。
或者你可以使用一个TreeSet并试图想出一个聪明的比较器,它将电梯方向考虑在内,但这似乎比它的价值更麻烦。
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
}
}
答案 1 :(得分:2)
我尝试使用单个TreeSet
实现Elevator。
这是一个完整的解决方案:
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
}