我有一个方法需要实现,它要求我根据一些条件返回队列中的船
/** Returns the next ship waiting to enter the port. The queue should not change.
*
* The rules for determining which ship in the queue should be returned next are as
* follows:
* <ul>
* <li>If a ship is carrying dangerous cargo, it should be returned. If more than one
* ship is carrying dangerous cargo return the one added to the queue first.</li>
*
* <li>If a ship requires medical assistance, it should be returned. If more than one
* ship requires medical assistance, return the one added to the queue first.</li>
*
* <li>If a ship is ready to be docked, it should be returned. If more than one ship is
* ready to be docked, return the one added to the queue first.</li>
*
* <li>If there is a container ship in the queue, return the one added to the queue first.</li>
*
* <li>If this point is reached and no ship has been returned, return the ship that was
* added to the queue first.</li>
*
* <li>If there are no ships in the queue, return null.</li>
* </ul>
* @return next ship in queue
* */
public Ship peek() {
Queue<Ship> newShips = new LinkedList<>(ships); // Make a copy of the queue and change here
for (Ship s : newShips) {
if (s.getFlag() == NauticalFlag.BRAVO) { //ship carrying dangerous cargo
return s;
} else if (s.getFlag() == NauticalFlag.WHISKEY) { // ship requires medical assistance
return s;
} else if (s.getFlag() == NauticalFlag.HOTEL) { // ship is ready to be docked
return s;
} else if (s.getName() == "ContainerShip") { // Container Ship
return s;
} else {
return poll(); // ship that was added to the queue first
}
}
if (newShips.isEmpty()) {
return null;
}
}
我被困在返回船在if else语句在for循环。还有,我如何知道条件(例如carrying dangerous cargo
=NauticalFlag.BRAVO
)是否在队列中有不止一艘船,并返回首先添加到队列中的船。
您必须每次遍历队列并按优先级查找标志,这是一种干净的方式:
public Ship peek() {
Queue<Ship> newShips = new LinkedList<>(ships); // Make a copy of the queue and change here
return findFirstShip(newShips, NauticalFlag.BRAVO)
.orElse(findFirstShip(newShips, NauticalFlag.WHISKEY)
.orElse(findFirstShip(newShips, NauticalFlag.HOTEL)
.orElse(findFirstShip(newShips, NauticalFlag.CONTAINER)
.orElseGet(newShips::poll))));
}
private Optional<Ship> findFirstShip(Queue<Ship> newShips, NauticalFlag flag) {
return newShips.stream().filter(ship -> ship.getFlag() == flag).findFirst();
}
我会将其作为最小化算法的线性搜索,如下所示:
public class Ship
{
/** The known ships. This needs to be populated for the example to work. */
static List<Ship> ships = new ArrayList<> ();
/** Type/status of this ship. */
private NauticalFlag flag;
/** Ship name or type name */
private String name;
public NauticalFlag getFlag ()
{
return flag;
}
public String getName ()
{
return name;
}
/** This is the original version from the question */
public Ship peek1 ()
{
// Make a copy of the queue and change here
final Queue<Ship> newShips = new LinkedList<> (ships);
for (final Ship s : newShips)
{
if (s.getFlag () == NauticalFlag.BRAVO)
{ // ship carrying dangerous cargo
return s;
}
else if (s.getFlag () == NauticalFlag.WHISKEY)
{ // ship requires medical assistance
return s;
}
else if (s.getFlag () == NauticalFlag.HOTEL)
{ // ship is ready to be docked
return s;
}
else if (s.getName () == "ContainerShip")
{ // Container Ship
return s;
}
else
{
return newShips.poll (); // ship that was added to the queue first
}
}
if (newShips.isEmpty ())
{
return null;
}
return newShips.poll ();
}
/** This is how I would do it as a linear search (or minimization). */
public Ship peek2 ()
{
Ship result = null;
for (final Ship s : ships)
{
if (priority (s) > priority (result))
{
result = s;
}
}
return result;
}
/**
* Define the preference function here. Note how null is handled first to prevent
* nullPointerException problems.
*/
public int priority (Ship s)
{
if (s == null)
{
return 0;
}
if (s.getFlag () == NauticalFlag.BRAVO)
{ // ship carrying dangerous cargo
return 5;
}
else if (s.getFlag () == NauticalFlag.WHISKEY)
{ // ship requires medical assistance
return 4;
}
else if (s.getFlag () == NauticalFlag.HOTEL)
{ // ship is ready to be docked
return 3;
}
else if (s.getName () == "ContainerShip")
{ // Container Ship
return 2;
}
return 1;
}
}