Home > Back-end >  How to return value using for each loop Java
How to return value using for each loop Java

Time:10-11

I have a method need to implement which ask me to return the ship in a queue according to some conditions

/** 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;
        }
    }

I am stuck on returning the ship in the if else statement in the for loop. And also how can I know if the condition for example carrying dangerous cargo = NauticalFlag.BRAVO have more than one ship in the queue and return the one added to queue first.

CodePudding user response:

You must iterate through the queue everytime and look for the flags by priority, this is the way to do it in a clean way:

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();
}

CodePudding user response:

I would do this as a linear search of minimization algorithm, like this:

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;
    }
}
  • Related