Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and why does List remove(Object object) return false

Tags:

java

list

When and why does the method boolean java.util.List.remove(Object object) return false?

The documentation states

[The method returns] true if this List was modified by this operation, false otherwise.

Why wouldn't the operation take effect on the List?

(NB: The implementation of the List I am making use of is the ArrayList)

Update: The objects I am trying to remove do exist in the List. I add the class to the List (hence the argument this) and pass this (within the same class) to the remove method. Therefor the object should exist in the List (or not?).

Update: Here is the code. Have a look at the delay() method. There is where I attempt to remove the respective class from the List.

public class Timer extends Object {

    private static List<Timer> allTimers;
    private Long startTime;
    private int delayTime;
    private boolean registered;

    String name;

    public Timer(String name) {
        this.name = name;
        this.registered = true;
        allTimers.add(this);
        Log.d("SpaceDroid", "Foo: Created timer: " + name + " Size: " + this.allTimers.size());

    }

    public Timer(String name, int delayTime) {
        this(name);
        this.delayTime = delayTime;

    }

    public void setDelayTime(int delayTime) {
        this.delayTime = delayTime;

    }

    public boolean delay() {
        if(this.startTime == null) {
            this.startTime = System.currentTimeMillis();
        }

        if(startTime + this.delayTime < System.currentTimeMillis()) {
            if(this.registered) {
                Log.d("SpaceDroid", "Foo: Trying to remove timer: " + name);
                if(this.allTimers.remove(this)) {
                    Log.d("SpaceDroid", "Foo: Successfully removed timer: " + name);
                }
                else {
                    Log.d("SpaceDroid", "Foo: Did not remove timer: " + name);
                }

            }
            return true;

        }
        else {
            return false;

        }

    }

    // The same as resume, just renew the startTime

    public void reset() {
        this.startTime = null;
        this.registered = true;
        this.allTimers.add(this);

    }

    public void resume() {
        this.startTime = System.currentTimeMillis();

    }

    public void pause() {
        // Check if timer is still running
        if(!this.delay()) {
            // Calculate new delayTime
            delayTime = (int) ((startTime + this.delayTime) - System.currentTimeMillis());
            Log.d("SpaceDroid", "Foo: New delay time: " + delayTime + " for timer: " + name);

        }


    }

    public static void resumeAllTimers() {
        List<Timer> timers = new ArrayList<Timer>(Timer.allTimers);
        for (Timer timer : timers) {
            timer.resume();
        }

    }

    public static void pauseAllTimers() {
        List<Timer> timers = new ArrayList<Timer>(Timer.allTimers);
        for (Timer timer : timers) {
            timer.pause();
        }

    }

    public static void disposeAllTimers() {
        Timer.allTimers.clear();
        Timer.allTimers = null;

    }

    public static void initializeAllTimers() {
        allTimers = new ArrayList<Timer>();

    }


}
like image 878
Luke Taylor Avatar asked Dec 12 '22 15:12

Luke Taylor


2 Answers

If the Object passed in is not actually in the list, it wouldn't take any effect on the list and therefore return false.

Edit (thanks Jai): The method uses the specific Objects equals() method to determine if it contains that object. So, if you have custom objects make sure you override the equals() method, and also the hashCode() (to maintain the general contract between the methods).

like image 164
ddmps Avatar answered Dec 14 '22 06:12

ddmps


Since List is an interface, it wouldn't have a concrete implementation for an example. But taking from ArrayList, it will return false if:

  • you pass null and there's no null object in the list, or
  • you pass an object not found on the list

From ArrayList.java

     public boolean remove(Object o) {
         if (o == null) {
             for (int index = 0; index < size; index++)
                 if (elementData[index] == null) {
                     fastRemove(index);
                     return true;
                 }
         } else {
             for (int index = 0; index < size; index++)
                 if (o.equals(elementData[index])) {
                     fastRemove(index);
                     return true;
                 }
         }
         return false;
     }

Adding the code of fastRemove, for completeness:

 private void fastRemove(int index) {
      modCount++;
      int numMoved = size - index - 1;
      if (numMoved > 0)
          System.arraycopy(elementData, index+1, elementData, index,
                           numMoved);
      elementData[--size] = null; // Let gc do its work
  }

Proving it:

public static void main(String[] args) {
        ArrayList l = new ArrayList();
        System.out.println("Removing null on empty list: " + l.remove(null));
        System.out.println("Removing an object that won't be found: " + l.remove(new Object()));
}

Result:

Removing null on empty list: false
Removing an object that won't be found: false
like image 22
Jops Avatar answered Dec 14 '22 04:12

Jops