0

I implemented a queue using array. Now I want to remove a element by searching, if the element were there it must be removed from the queue.

public static void deleteFromQueue(PassengerQueue passengerQueue){

    //passengerQueue.dequeue();
    Scanner scan = new Scanner(System.in);
    System.out.print("please Enter the Passenger name: ");
    String name = scan.nextLine();
    for (int i=0; i<passengerQueue.getPassenger().length; i++){
        if (passengerQueue.getPassenger()[i].getName().equals(name)){
            //
        }
    }
}

here my method of removing

Abra
  • 19,142
  • 7
  • 29
  • 41
  • https://stackoverflow.com/questions/112503/how-do-i-remove-objects-from-an-array-in-java – Jaybird Apr 11 '20 at 05:55
  • 2
    What is `PassengerQueue`? Is it your class or it's extending something? – Omri Attiya Apr 11 '20 at 05:55
  • Does this help? [Removing an element from an Array (Java)](https://stackoverflow.com/questions/642897/removing-an-element-from-an-array-java) – Abra Apr 11 '20 at 05:57

2 Answers2

1

Why do you specifically want to use an array. Please find an example attached using an ArrayList:

    package stackoverflow;

    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;

    import java.util.ArrayList;
    import java.util.Iterator;

    public class QuickTest {

        @Test
        public void test() throws Exception {
            PassengerQueue passengerQueue = new PassengerQueue();
            passengerQueue.add(new Passenger("testName1"));
            passengerQueue.add(new Passenger("testName2"));
            Assertions.assertEquals(2, passengerQueue.size());

            PassengerUtil.removeByName(passengerQueue, "testName1");
            Assertions.assertEquals(passengerQueue.size(), 1);

            System.out.println("All done");
        }

        private static class PassengerUtil {

            /** @param passengerQueue    Modified by reference. **/
            private static void removeByName(PassengerQueue passengerQueue, String specifiedName) {
                // Using an Iterator so that I don't trigger ConcurrentModificationException.
                for (Iterator<Passenger> it = passengerQueue.iterator() ; it.hasNext() ; ) {
                    Passenger currPassenger = it.next();
                    if (currPassenger.getName().equals(specifiedName)) {
                        it.remove();
                    }
                }
            }
        }

        private class PassengerQueue extends ArrayList<Passenger> {
        }

        private class Passenger {

            private String name;

            public Passenger(String name) {
                if (name == null) {
                    throw new NullPointerException("The " + Passenger.class.getSimpleName() + " cannot have a Name equal to NULL!");
                }
                this.name = name;
            }

            public String getName() {
                return this.name;
            }
        }
    }

Please note the following:

  • My PassengerQueue object extends ArrayList. So I have a type-safe list of Passengers just by extending ArrayList - I don't need to do anything else.

  • I use an Iterator to iterate over the list. Its a bit more verbose than your normal for-each loop, but its necessary to not trigger a ConcurrentModificationException. Java doesn't always like when you iterate over a list and then for example delete things from that list while you're iterating over it. (Maybe simple examples won't trigger the ConcurrentModificationException)

  • You called your list PassengerQueue. Please note that Java does have Queue(https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html) collections. Similar to me extending ArrayList you can look at Queue subclasses and extend that instead if you really need your Collection to function like a queue.

  • Your code, and mine, can currently delete multiple elements from the list if the list contains Passengers with the same name.

  • Your question title asked about deleting from an array using an index position. You can consider adding the Apache Commons Lang project to your classpath and using methods from their ArrayUtils

Actually, my answer can be improved to not even use an Iterator:

    private static class PassengerUtil {

        /** @param passengerQueue    Modified by reference. **/
        private static void removeByName(PassengerQueue passengerQueue, String specifiedName) {
            passengerQueue.removeIf(currPassenger -> currPassenger.getName().equals(specifiedName));
        }
    }

Some reading on the latter code example here.

dutoitns
  • 1,949
  • 1
  • 26
  • 32
1

A 'Queue' is defined as a data structure that holds a sequence of items where you can only add something to the end (the 'tail') and where you can take something from the beginning, the 'head'. And sometimes it is said that you can get the current size of the sequence, ask whether the sequence is empty, and that you can look ('peek') at the first item without taking it.

That's the basics. And you can implement that in various ways.

There is an interface in Java (java.util.Queue) that provides the basic features described above. So when you declare

java.util.Queue myQueue = …

then you cannot search your queue for an item and remove it (ok, you can take all elements from your queue, one by one, and add again those you want to keep, but that's tedious).

But the implementation for java.util.Queue is java.util.LinkedList, and a list can be searched.

So you write

java.util.Queue myQueue = new java.util.LinkedList();

and as you now know that the implementation of your queue is in fact a list, you can write

…
for( var i = ((java.util.List) myQueue).iterator(); i.hasNext(); )
{
    if( matchesCriteriaForRemoval( i.next() ) i.remove();
}
…

But this works only because you know some implementation details of myQueue – but that was what you want to hide when you chose to define it as java.util.Queue.

So when you have to be able to remove entries from your PassengerQueue, that data structure should provide a method to do so instead of revealing its internal implementation.

This means your code have to look like this:

public static void deleteFromQueue( PassengerQueue passengerQueue )
{
    Scanner scan = new Scanner( System.in );
    System.out.print( "please Enter the Passenger name: " );
    String name = scan.nextLine();
    passengerQueue.removeByName( name );
}

How this method PassengerQueue.removeByName() is implemented depends from the internal implementation of PassengerQueue; if it uses the java.util.List with the name passengers to store the passengers, it may look like this:

public final void removeByName( final String name )
{
    for( var i = passengers.iterator(); i.hasNext(); )
    {
        if( passengerNameMatches( name, i.next() ) ) i.remove();
    }
}

If you use another container for your passengers, that removal method has to be implemented differently …

Obviously I omitted all error handling, and the collections are generic types, but I used them as raw because of brevity.

tquadrat
  • 3,033
  • 1
  • 16
  • 29