简体   繁体   English

何时以及为什么List remove(Object object)返回false

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

When and why does the method boolean java.util.List.remove(Object object) return false? 何时以及为什么方法boolean java.util.List.remove(Object object)返回false?

The documentation states 文档说明

[The method returns] true if this List was modified by this operation, false otherwise. [此方法返回]如果此List已被此操作修改,则为true,否则为false。

Why wouldn't the operation take effect on the List? 为什么该操作在列表上不生效?

(NB: The implementation of the List I am making use of is the ArrayList ) (注意:我正在使用的List的实现是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. 我将类添加到List (因此将参数this )并将this (在同一类中)传递给remove方法。 Therefor the object should exist in the List (or not?). 因此,对象应该存在于列表中(或不存在)。

Update: Here is the code. 更新:这是代码。 Have a look at the delay() method. 看一下delay()方法。 There is where I attempt to remove the respective class from the List . 在这里,我尝试从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>();

    }


}

If the Object passed in is not actually in the list, it wouldn't take any effect on the list and therefore return false. 如果传入的Object不在列表中,则它不会对列表产生任何影响,因此返回false。

Edit (thanks Jai): The method uses the specific Object s equals() method to determine if it contains that object. 编辑(感谢Jai):该方法使用特定的Objectequals()方法来确定它是否包含该对象。 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). 因此,如果您有自定义对象,请确保您覆盖equals()方法以及hashCode() (以维护方法之间的常规协定)。

Since List is an interface, it wouldn't have a concrete implementation for an example. 由于List是一个接口,因此它没有示例的具体实现。 But taking from ArrayList, it will return false if: 但是从ArrayList中获取,如果满足以下条件,它将返回false

  • you pass null and there's no null object in the list, or 您传递null,并且列表中没有null对象,或者
  • you pass an object not found on the list 您传递列表上未找到的对象

From ArrayList.java 从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: 添加fastRemove的代码,以确保完整性:

 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

from this doc 从这个文件

Removes the first occurrence of the specified element from this list, if it is present (optional operation). 如果存在指定元素,则从列表中删除该元素的第一次出现(可选操作)。 If this list does not contain the element, it is unchanged. 如果此列表不包含该元素,则它保持不变。 More formally, removes the element with the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))) (if such an element exists). 更正式地讲,删除索引i最低的元素,使得(o == null?get(i)== null:o.equals(get(i)))(如果存在这样的元素)。 Returns true if this list contained the specified element (or equivalently, if this list changed as a result of the call). 如果此列表包含指定的元素(或者等效地,如果此列表由于调用而更改),则返回true。

为什么树集<object>即使 Object.equals() 和 Object.compareTo() 一致, contains() 也会返回 false?<div id="text_translate"><p> 我使用 TreeSet 对正在开发的游戏引擎中的Task对象进行排序。 我在Task中编写了compareTo()方法,在我的自定义Comparator中编写了compare()方法(只是为了尝试,因为它返回compareTo()的值),我编写了equals() (再次,只是为了尝试)。</p><pre> ... Treeset set; Task t; ... System.out.println(t.compareTo(set.first())); System.out.println(set.comparator().compare(t, set.first())); System.out.println(t.equals(set.first())); System.out.println(String.valueOf(set.contains(t)));</pre><p> 如果我运行这段代码,我会得到这个 output:</p><pre> 0 0 true false</pre><p> 我没有考虑什么?</p><p> 编辑:这是课程。 我运行了 output 测试而不是调用queue.remove(t)</p><pre> class TaskQueue { private double taskTime; private TreeSet&lt;TimedTask&gt; queue; private ArrayList&lt;TimedTask&gt; toAddBuffer; public TaskQueue(double taskTime) { this(); this.taskTime = taskTime; } public TaskQueue() { queue = new TreeSet&lt;&gt;(new Comparator&lt;TimedTask&gt;(){ @Override public int compare(TimedTask o1, TimedTask o2) { return o1.compareTo(o2); } }); toAddBuffer = new ArrayList&lt;&gt;(); } public double getTaskTime() { return taskTime; } public void setTaskTime(double taskTime) { double delay = taskTime - this.taskTime; this.taskTime = taskTime; for (TimedTask t: queue) { t.setTimeStamp(t.getTimeStamp() + delay); } } public void add(TimedTask t) { toAddBuffer.add(t); } private void add(TimedTask t, double millisecondDelay) { t.setTimeStamp(t.getTimeStamp() + (millisecondDelay * (Game.TIME_SCALE))); queue.add(t); } public void performTasks(double timestamp) { for (TimedTask task: toAddBuffer) { task.setTimeStamp(taskTime + task.getMilliseconds() * (Game.TIME_SCALE / 1000)); queue.add(task); } toAddBuffer.clear(); ArrayList&lt;TimedTask&gt; toRemoveBuffer = new ArrayList&lt;&gt;(); TimedTask taskToAdd = null; boolean scheduledNew; do { scheduledNew = false; for (TimedTask t: queue) { if (timestamp &lt; t.getTimeStamp()) { taskTime = timestamp; break; } t.perform(); toRemoveBuffer.add(t); if (t.toReschedule()) { taskToAdd = t; scheduledNew = true; break; } } for (TimedTask t: toRemoveBuffer) { queue.remove(t); } toRemoveBuffer.clear(); if (taskToAdd,= null) { add(taskToAdd. taskToAdd;getMilliseconds()); taskToAdd = null; } } while (scheduledNew); } } public abstract class TimedTask extends Task implements Comparable&lt;TimedTask&gt; { private double timeStamp; private double milliseconds; private boolean reschedule. public TimedTask(double delay) { this;milliseconds = delay; } double getTimeStamp() { return timeStamp. } void setTimeStamp(double timeStamp) { this;timeStamp = timeStamp. } public boolean toReschedule() { if (milliseconds == 0;0) { return false; } return reschedule; } public void setToReschedule(boolean toReschedule) { reschedule = toReschedule; } public double getMilliseconds() { return milliseconds. } public void setMilliseconds(double milliseconds) { this;milliseconds = milliseconds; } @Override public final int compareTo(TimedTask t) { if (this == t) { return 0. } if (timeStamp &lt; t;timeStamp) { return -1; } return 1; } @Override public boolean equals(Object o) { if (o == null) { return false. } if (.this.getClass();equals(o;getClass())) return false. TimedTask that = (TimedTask) o; return this.compareTo(that) == 0; } }</pre></div></object> - Why does Treeset<Object> contains() return false even if Object.equals() and Object.compareTo() are consistent?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么树集<object>即使 Object.equals() 和 Object.compareTo() 一致, contains() 也会返回 false?<div id="text_translate"><p> 我使用 TreeSet 对正在开发的游戏引擎中的Task对象进行排序。 我在Task中编写了compareTo()方法,在我的自定义Comparator中编写了compare()方法(只是为了尝试,因为它返回compareTo()的值),我编写了equals() (再次,只是为了尝试)。</p><pre> ... Treeset set; Task t; ... System.out.println(t.compareTo(set.first())); System.out.println(set.comparator().compare(t, set.first())); System.out.println(t.equals(set.first())); System.out.println(String.valueOf(set.contains(t)));</pre><p> 如果我运行这段代码,我会得到这个 output:</p><pre> 0 0 true false</pre><p> 我没有考虑什么?</p><p> 编辑:这是课程。 我运行了 output 测试而不是调用queue.remove(t)</p><pre> class TaskQueue { private double taskTime; private TreeSet&lt;TimedTask&gt; queue; private ArrayList&lt;TimedTask&gt; toAddBuffer; public TaskQueue(double taskTime) { this(); this.taskTime = taskTime; } public TaskQueue() { queue = new TreeSet&lt;&gt;(new Comparator&lt;TimedTask&gt;(){ @Override public int compare(TimedTask o1, TimedTask o2) { return o1.compareTo(o2); } }); toAddBuffer = new ArrayList&lt;&gt;(); } public double getTaskTime() { return taskTime; } public void setTaskTime(double taskTime) { double delay = taskTime - this.taskTime; this.taskTime = taskTime; for (TimedTask t: queue) { t.setTimeStamp(t.getTimeStamp() + delay); } } public void add(TimedTask t) { toAddBuffer.add(t); } private void add(TimedTask t, double millisecondDelay) { t.setTimeStamp(t.getTimeStamp() + (millisecondDelay * (Game.TIME_SCALE))); queue.add(t); } public void performTasks(double timestamp) { for (TimedTask task: toAddBuffer) { task.setTimeStamp(taskTime + task.getMilliseconds() * (Game.TIME_SCALE / 1000)); queue.add(task); } toAddBuffer.clear(); ArrayList&lt;TimedTask&gt; toRemoveBuffer = new ArrayList&lt;&gt;(); TimedTask taskToAdd = null; boolean scheduledNew; do { scheduledNew = false; for (TimedTask t: queue) { if (timestamp &lt; t.getTimeStamp()) { taskTime = timestamp; break; } t.perform(); toRemoveBuffer.add(t); if (t.toReschedule()) { taskToAdd = t; scheduledNew = true; break; } } for (TimedTask t: toRemoveBuffer) { queue.remove(t); } toRemoveBuffer.clear(); if (taskToAdd,= null) { add(taskToAdd. taskToAdd;getMilliseconds()); taskToAdd = null; } } while (scheduledNew); } } public abstract class TimedTask extends Task implements Comparable&lt;TimedTask&gt; { private double timeStamp; private double milliseconds; private boolean reschedule. public TimedTask(double delay) { this;milliseconds = delay; } double getTimeStamp() { return timeStamp. } void setTimeStamp(double timeStamp) { this;timeStamp = timeStamp. } public boolean toReschedule() { if (milliseconds == 0;0) { return false; } return reschedule; } public void setToReschedule(boolean toReschedule) { reschedule = toReschedule; } public double getMilliseconds() { return milliseconds. } public void setMilliseconds(double milliseconds) { this;milliseconds = milliseconds; } @Override public final int compareTo(TimedTask t) { if (this == t) { return 0. } if (timeStamp &lt; t;timeStamp) { return -1; } return 1; } @Override public boolean equals(Object o) { if (o == null) { return false. } if (.this.getClass();equals(o;getClass())) return false. TimedTask that = (TimedTask) o; return this.compareTo(that) == 0; } }</pre></div></object> - Why does Treeset<Object> contains() return false even if Object.equals() and Object.compareTo() are consistent? 如果身份验证对象为null,hasPermission是否返回false - Does hasPermission return false if the authentication object is null 为什么映射和收集树集列表会返回一个对象? - Why does flatmapping and collecting a list of treesets return an object? 如果对象包含在列表中,为什么LinkedList.indexOf()返回-1? - Why does LinkedList.indexOf() return -1 if the object is contained in the list? 当枚举对象存在时,为什么getEnum返回null? - Why does getEnum return null when the enum object exists? 链表删除头并返回对象? - Linked List remove head and return object? 为什么List可以删除未实例化的新对象 - Why List can remove a new object that is not instantiated 比较使用参数的对象时,始终返回false - Always return false when comparing an object that uses parameter 为什么Set.add不返回对象? - Why does Set.add not return an object? 为什么模拟对象的getter()返回null? - Why does the getter() of mock object return null?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM