如何在Java中从ArrayList中删除一个对象?

7

我有一个ArrayList,其中包含一些对象,例如User,每个对象都有一个namepassword属性。如何从这个ArrayList中仅删除具有特定“名称”的User对象?


3
你能更准确地描述你的问题吗?写下你正在处理的代码片段... - aleroot
9个回答

24
Iterator<User> it = list.iterator();
while (it.hasNext()) {
  User user = it.next();
  if (user.getName().equals("John Doe")) {
    it.remove();
  }
}

9
看起来提问者没有为这个问题做任何工作,你不应该免费给他们编写代码。 - Hunter McMillen

7
你可以使用类似这样的代码:
           // If you are using java 8
           userList.removeIf(user-> user.getName().equals("yourUserName"));
           // With older version
           User userToRemove = null;
           for(User usr:userList) {
             if(usr.getName().equals("yourUserName")) {
                userToRemove = usr;
                break;
             }
           }
           userList.remove(userToRemove);

s是什么?请尽量具体地回答。 - james.garriss
这里的 s 是谓词,并且只能在支持 Lambda 表达式的 JDK 1.8 中使用。移除满足给定谓词的所有集合元素。 - jprism
这是一个很棒的答案,而且易于理解。 - Onkar Musale
谢谢。你的答案帮助我顺利毕业于计算机科学专业。8年后,我为你的最佳答案颁发了一个徽章xD。 - Mohamed Gamal
@MohamedGamal 很高兴知道。谢谢。 - manikant gautam

7
另一个想法:如果User类可以通过用户名唯一定义,而且您使用类似以下内容覆盖equals方法:
public boolean equals(Object arg0) {
    return this.name.equals(((user) arg0).name);
}

您可以不通过对列表进行迭代来删除User。只需执行以下操作:

 list.remove(new User("John Doe"))

6
您可能会在尝试从List中删除对象时遇到ConcurrentModificationException异常。该异常的解释是ArrayList的迭代器是一种快速失败的迭代器。例如,当它检测到运行时集合已被修改时,它将抛出异常(失败)。解决此问题的方法是使用Iterator。
以下是一个简单的示例,演示了如何在满足特定条件时遍历List并删除元素:
List<User> list = new ...

for (Iterator<User> it = list.iterator(); it.hasNext(); ) {

    User user = it.next();
    if (user.getUserEmail().equals(currentUser.getUserEmail())) {
       it.remove();
    }
}

6

推荐解决此问题的方法是:

ArrayList<User> list = new ArrayList<User>();
list.add(new User("user1","password1"));
list.add(new User("user2","password2"));
list.add(new User("user3","password3"));
list.add(new User("user4","password4"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) 
{
    User user = iter.next();
    if(user.name.equals("user1"))
    {
        //Use iterator to remove this User object.
        iter.remove();
    }
}

使用迭代器删除对象比直接使用ArrayList(Object)更高效,因为它更快速并且节省20%的时间,这是Java集合的标准做法。

3

您可以:

  • 使用迭代器循环遍历列表。
  • 检查列表中的每个项目是否是正确的用户(通过检查名称)。
  • 如果是,则使用迭代器的remove方法将其移除。

1
只需搜索从用户获取的对象ArrayList,并测试名称是否等于要删除的名称。然后从列表中删除该对象。

希望有一些优化可以进行,否则原始问题只能使用O(n)的实现。 - Clockwork-Muse
1
@X-Zero 在什么场景下,如果你不知道列表中一个对象的位置,你能有比O(n)更好的性能? - Hunter McMillen
2
@X-Zero:如果所有的操作者只有一个数组列表,那么O(n)就是他所能期望的最好结果(仅元素删除本身就是O(n))。 - NPE
是的,我知道。但如果我们知道它是按名称排序的,或者可能是哈希映射之类的东西,那就太好了。 - Clockwork-Muse

0

你的代码可能长这样:

List<User> users = new ArrayList<User>();

public void removeUser(String name){
    for(User user:users){
        if(user.name.equals(name)){
            users.remove(user);
        }
    }
}

2
你应该在循环中使用迭代器来进行删除操作,否则可能会出现ConcurrentModificationException异常。 - assylias
@assylias 基本的for循环在Java 5中得到了扩展,以使得对数组和其他集合的迭代更加方便。而for-each循环则隐式地使用了迭代器。 - Matrix Scarlett Johansson
1
尝试运行以下代码(对于格式不当表示抱歉):List<String> list = new ArrayList<String>(); list.add("a"); for (String s : list) { list.remove(s); },你应该会得到一个异常。 - assylias
@assylias 啊哈,没错。我之前只是想到了使用for-each循环遍历迭代器,但忽略了一个事实:除非使用iterator.remove方法,否则list.remove并不能删除元素。除非for-each可以探索迭代器对象来执行删除操作。 - Matrix Scarlett Johansson

-1
ArrayList<User> userList=new ArrayList<>();
//load data

public void removeUser(String userName){
    for (User user: userList){
        if(user.getName()equals(userName)){
            userList.remove(user);
        }
    }
}

2
在 foreach 迭代时无法删除元素。 https://dev59.com/A3VC5IYBdhLWcg3wpi98 - Gangaraju

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接