【问题标题】:Remove User from list of users in java从java中的用户列表中删除用户
【发布时间】:2021-01-03 21:29:47
【问题描述】:

我是java新手,如果我的解释很差,请见谅,但我有一个清单:

private LinkedList<User> users= new LinkedList<User>();

还有一个方法 removeUser:

private void removeUser() {
        System.out.println("All Users: ");
        viewUsers();
        System.out.print("Please enter the ID of the user to be removed: ");
        int choice = In.nextInt();
        for (User user : users){ 
            if (users.contains(choice)) { 
                users.remove(choice); 
            } 

        }
    }

现在,当我运行代码时,它会成功打印出所有内容。然而,当我检查列表内容时,什么都没有改变,我不确定我在删除部分代码时做错了什么。

【问题讨论】:

  • viewUsers() 打印列表吗?
  • @Aniox 是的,它会正确打印列表
  • 几个问题:(1) if (users.contains(choice)) 正在检查包含 User 类型对象的列表是否还包含一些 int,这些 int 永远不会被评估为真。您可能想要更像if(user.getID == choice) 的东西。 (2) users.remove(choice); 将尝试删除您当前正在迭代的列表中 position choice 的元素,而不是 ID==choice。 (3) 由于它还会修改您当前正在迭代的列表,您可能会遇到ConcurrentModificationException。您所追求的可能类似于users.removeIf(user-&gt;user.getID()==choice)
  • 生活课:你写了for (User user : users),但你没有在循环内的任何地方使用user。通常,当您编写 for-each 循环时,这是因为您想对正在迭代的集合的每个项目做一些事情;那就是你没有对user 做任何事情是一个警告信号,表明事情不太对劲。
  • 这不是您问题的完整答案,但我认为它很有帮助:Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop

标签: java


【解决方案1】:

如果您想从列表中删除某些项目,则不能使用 for-each 循环。参考:What is a difference between traditional loop and for-each loop?

我想你也需要:

 private void removeUser() {
    System.out.println("All Users: ");
    viewUsers();
    System.out.print("Please enter the ID of the user to be removed: ");
    int choice = In.nextInt();
    for (int i = 0; i < users.size(); i++){ 
        User user = users.get(i);
        if (user.contains(choice)) { 
            users.remove(i); // remove at index i
        } 

    }
}

希望能帮到你!

【讨论】:

    【解决方案2】:

    替代解决方案:如果您想使用 lambda 和流来删除具有相应 ID 的第一个用户。

    
    private void removeUser() {
        System.out.println("All Users: ");
        viewUsers();
        System.out.print("Please enter the ID of the user to be removed: ");
        int choice = In.nextInt();
        
        users.stream()
             .filter(user->user.getId() == choice)
             .findFirst()
             .ifPresent(users::remove);
    }
    
    

    【讨论】:

    • 谢谢。不过,我更喜欢 Pshemo 评论中的users.removeIf(user -&gt; user.getID() == choice)。如果您愿意,请随意将其作为选项包含在您的答案中。
    • 经过测试..不会导致ConcurrentModificationException
    • 好的,我犯了一个错误,没有注意到当您调用.findFirst() 时,它是流的终端操作,它结束了流处理并返回Optional&lt;User&gt;。这意味着调用.ifPresent(users::remove) 不会抛出ConcurrentModificationException(流处理结束)。 +1 但 IMO users.removeIf(user-&gt;user.getId() == choice) 在这里更直观。
    • 同意...它简洁明了.. 但是removeIf 将删除所有具有匹配谓词的元素。删除将进行 O(n)。但是,一旦我们找到第一个元素,findFirst 就会退出。所以平均速度更快。
    • 如果我想改变我不正确的投票,必须编辑一些东西:) 无论如何users::remove 将调用 List#remove 它通常还需要遍历整个列表,以防元素存在不止一次,这使得它O(n).
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多