【问题标题】:arraylist remove eliminates following objectsarraylist remove 消除了以下对象
【发布时间】:2013-12-10 17:11:05
【问题描述】:

我的代码中有一个非常奇怪的动作。我有一个以下班级的ArrayList

class mySocket 
{
    public String name;
    public Socket sck;
    public mySocket(String n,Socket s)
    {
        this.name=n;
        this.sck=s;
    }
}

我这样声明对象

ArrayList<mySocket> handler = new ArrayList<>();

现在的问题是,当我尝试使用此方法删除项目时:

public void removeByName(String name)
{
    synchronized(this)
    {
        mySocket t;
        int i;
        for(i=0;i<handler.size();i++)
        {
            t=handler.get(i);
            if((t.name.equals(name)))
            {
               handler.remove(i);
               break;
            }
        }
    }
}

remove 函数会清除索引后面的所有内容。
例如:
如果这个 ArrayList 有 3 个元素并且我调用 handler.remove(1) 它不仅会删除 1,还会删除第 2 行的对象。

【问题讨论】:

  • 这个方法怎么称呼?方法中是否还有其他代码可以移除元素?
  • 第一,你应该使用t.name.equals(name)而不是compareTo(),第二,你能提供整个函数体包含这个for循环吗?
  • 你不需要在处理程序声明的两边都使用 mySocket 吗?例如 ArrayList handler = new ArrayList();这可能不是问题,但它仍然很有趣。
  • 附注。按照约定,Java 中的类名以大写字母开头。阅读:Code Conventions for the Java Programming Language
  • @johnsoe 在 Java 7 中,您可以使用菱形运算符。将推断 RHS 上的泛型类型。

标签: java arraylist


【解决方案1】:

我认为您的问题是您正在使用索引 for 循环并按索引删除。在您的示例中,如果您的列表有 3 个元素并且您删除了索引 1,那么在索引 2 处 的对象仍然存在。它现在只是在索引 1 处。

更好的方法是使用迭代器或 for-each 循环。

//code outside for loop the same
for( mySocket socket : handler ) {

    if((socket.name.equals(name)))
    {
       handler.remove(socket);
       break;
    }
}

mySocket 对象的顺序重要吗?如果没有,将它们存储在按名称键入的Map 中将为您省去一些麻烦。然后你就打电话给handler.remove(name)。即使地图中不存在name,此操作也是安全的。此外,对于不关心名称的集合handler 的当前用途,您可以通过调用map.values() 来检索mySockets 的无序Set。然后,您就可以使用上述的迭代器或 for-each 来迭代该 Set

【讨论】:

    【解决方案2】:

    您不能在循环遍历集合时删除集合中的项目,如您所见,结果是未定义的。

    您要么必须构建要删除和使用的项目列表

    originalList.removeAll(itemsToBeRemoved);
    

    或者您使用迭代器构建循环。

    Iterator<mySocket> handlerIterator = handler.iterator();
    
    while (handlerIterator.hasNext()) {
      mySocket t = handlerIterator.next();
      if (t.name.equals(name)) {
        handlerIterator.remove();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-23
      • 2018-05-15
      • 1970-01-01
      • 2018-03-07
      • 2015-06-15
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      相关资源
      最近更新 更多