Java:如何从列表中删除元素,同时迭代/添加它 [英] Java: How to remove elements from a list while iterating over/adding to it

查看:121
本文介绍了Java:如何从列表中删除元素,同时迭代/添加它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题是在这个问题



我有两种方法,stopAndRemove(ServerObject服务器)和close()方法。后者应关闭所有服务器并将其从服务器列表中删除。该列表被定义为

  List< ServerObject>服务器。 

我不想在closeCurrentlyOpen中使用stopAndRemove几乎相同的代码,所以我想做一些事情例如:

  public void closeCurrentlyOpen(){
for(ServerObject server:this.servers){
stopAndRemove(server)
}
}

这将导致ConcurrentModificationException。我尝试复制列表

  List< ServerObject> copyList = new ArrayList< ServerObject>(this.servers); 

并使用它作为foreach循环的列表。但是,然后它可能是另一个线程附加一个服务器到服务器列表,而我迭代copyList但closeCurrentlyOpen应该导致一个emtpy列表。
由于addServerToList方法被同步到servers-list,这样做

  public void closeCurrentlyOpen(){
synchronized(this.servers){
for(ServerObject server:this.servers){
stopAndRemove(server)
}
}
}

将解决修改问题。但是我不能同步stopAndRemove方法中的代码,如果直接调用它是必要的。



我觉得这三个方法的设计可能需要一个研究。
任何人的想法?

解决方案

从stopAndRemove()分离一个方法stop然后使用显式迭代器编写循环,执行stop和iterator.remove()。



和在方法名称中是一个代码气味。 >

This question is a more special case of the problem described (and solved) in this question.

I have two methods, stopAndRemove(ServerObject server) and a close() method. The later should close all servers and remove them from the server list. The list is defined as

List<ServerObject> server. 

I do not want to have almost the same code from stopAndRemove in closeCurrentlyOpen, so I want to do something like:

public void closeCurrentlyOpen() {
   for(ServerObject server : this.servers) {
       stopAndRemove(server)
   }
}

This won't work, as this will cause a ConcurrentModificationException. I tried to make a copy of the list

List<ServerObject> copyList = new ArrayList<ServerObject>(this.servers);

and use that as the list for the foreach-loop. But then it might be possible that an other thread appends a Server to the servers list while I am iterating over copyList but closeCurrentlyOpen is supposed to result in an emtpy list. As the addServerToList method is synchronized to the servers-list, doing this

public void closeCurrentlyOpen() {
   synchronized(this.servers) {
     for(ServerObject server : this.servers) {
        stopAndRemove(server)
     }
    }
}

will solve the problem with modifications. But then I can not synchronize the code in the stopAndRemove method which is necessary if it is directly called.

I seems to me that the design of this three methods probably needs a workover. Ideas anybody?

解决方案

Split off a method stop() from stopAndRemove(). Then write the loop with an explicit iterator, do the stop and then iterator.remove().

"and" in a method name is a code smell.

这篇关于Java:如何从列表中删除元素,同时迭代/添加它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆