arrayList的remove方法不起作用

时间:2010-11-21 13:53:09

标签: java arraylist

您好 我已经编写了这段代码,通过输出你可以得到.remove()方法不起作用。 abcdPoints个拥有xy成员的对象。

以下是a and b and c and d值,必须在upper中删除if语句,但不会删除。

X :59  Y: 143
X :165  Y: 140
X :59  Y: 143
X :165  Y: 140


   System.out.println(upper.toString());
        for(int i =0;i<upper.size();i++)

            if(upper.get(i)==a||upper.get(i)==b||upper.get(i)==c||upper.get(i)==d){
                upper.remove(i);

            }
        for(int i =0;i<lower.size();i++)

            if(lower.get(i)==a||lower.get(i)==b||lower.get(i)==c||lower.get(i)==d){
                upper.remove(i);
            }



        System.out.println(upper.toString());
        System.out.println(lower.toString());


   first println : [X :108  Y: 89, X :165  Y: 140]

   second println: [X :108  Y: 89, X :165  Y: 140]

   third println :  [X :105  Y: 191]

3 个答案:

答案 0 :(得分:7)

如果我正确地阅读你的问题,你假设==将比较两个对象的属性。它没有,这就是equals所做的。 ==告诉您两个引用是否属于相同对象实例,而不是等效对象实例。

例如:

public class Foo {
    public Foo(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @override
    public boolean equals(Object other) {
        Foo otherFoo;

        if (other == null || !(other instanceof Foo)) { // or you might be more restrictive
            return false;
        }

        otherFoo = (Foo)other);
        return otherFoo.x == this.x && otherFoo.y == this.y;
    }

    @override
    public int hashCode() {
        // ...appropriate implementation of hashCode...
    }
}

Foo a = new Foo(0, 0);
Foo b = new Foo(0, 0);
System.out.println(a == b);      // "false"
System.out.println(a.equals(b)); // "true"

另外:考虑当你必须删除ArrayList中的两个连续匹配对象时会发生什么。假设他们在列表中的索引8和9处。因此,当i == 8时,您会删除索引8处的项目,而曾经位于9的项目现在位于8。但是,然后在for循环中递增i并继续索引9处的新项目,而保持第二个不变。如果要在循环中修改列表,请考虑向后循环以避免这种情况,或使用Iterator

答案 1 :(得分:4)

这里有两个问题。首先,您在迭代时从列表中删除对象。这不是一个好主意。

其次,我认为你误解了@T.J. Crowder中提到的Java中的==运算符。

这是一种更好的方式来做你想做的事情(修复equals问题后):

List<Point> mypoints = new ArrayList();
mypoints.add(a);
mypoints.add(b);
mypoints.add(c);
mypoints.add(d);

List<Point> otherPoints = new ArrayList();

for(Point p: upper)
    for(Point myPoint: mypoints)
    {
        if(p.equals(myPoint))
            break;

        otherPoints.add(p);
    }

upper = otherPoints;

另一种实现(仅当upperSet时才有效,因为它不会捕获重复项):

List<Point> mypoints = new ArrayList();
mypoints.add(a);
mypoints.add(b);
mypoints.add(c);
mypoints.add(d);

for(Point myPoint: mypoints)
{
    upper.remove(myPoint);
}

答案 2 :(得分:0)

正如Eric所暗示的那样,列表的长度随着项目的删除而改变,刚刚删除的元素之后的所有值的索引也是如此。

我不确定“较低”的含义是什么。我注意到循环遍历“较低”的循环尝试从“上部”删除元素。这是故意的吗?

这是我的解决方案,基于应从“上方”删除的“删除”点列表。也可以使用原始测试的样式,除了每个==检查必须用等号()检查替换。

如果从Point类中删除了equals(...)实现,则不会从“upper”中删除任何内容,因为测试用例故意使用原始a,b,c和d值的克隆。

import java.util.ArrayList;
import java.util.List;

import junit.framework.Assert;

import org.junit.Test;


public class TestArrayList
{
    @Test
    public void testRemove()
    {
        // Test fixture:
        Point a = new Point(115, 70);
        Point b = new Point(139, 66);
        Point c = new Point(195, 111);
        Point d = new Point(144, 165);

        List<Point> upper = new ArrayList<Point>();
        upper.add(a.clone());
        upper.add(b.clone());
        upper.add(c.clone());
        upper.add(d.clone());

        List<Point> remove = new ArrayList<Point>();
        remove.add(a.clone());
        remove.add(b.clone());
        remove.add(c.clone());
        remove.add(d.clone());

        // Assertions:
        Assert.assertTrue(upper.size() == 4);
        Assert.assertTrue(remove.size() == 4);


        // Modified code:
        System.out.println(upper.toString());
        System.out.println(remove.toString());

        for (Point p : remove)
        {
            upper.remove(p);
        }

        System.out.println(upper.toString());
        System.out.println(remove.toString());

        // Assertions:
        Assert.assertTrue(upper.isEmpty());
        Assert.assertTrue(remove.size() == 4);
    }
}

class Point implements Cloneable
{
    public int x;
    public int y;

    public Point(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    @Override
    public Point clone()
    {
        return new Point(x, y);
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o)
        {
            return true;
        }
        else if (o instanceof Point)
        {
            Point p = (Point) o;

            return x == p.x && y == p.y;
        }
        else
        {
            return false;
        }
    }

    @Override public String toString()
    {
        return "X: " + x + "  Y: " + y;
    }
}