更新Java ArrayList中特定对象项

5

我该如何从我的 Arraylist 对象中更新记录呢?

例如:

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

User user = new User();
user.setUserId(1);
user.setUsername("user1");
userList.add(user);

User user = new User();
user.setUserId(2);
user.setUsername("user2");
userList.add(user);

User user = new User();
user.setUserId(3);
user.setUsername("user3");
userList.add(user);

现在我想要更新我的ArrayList中的特定记录。比如说,我想要更新id为2的用户的用户名。

User user = new User();
user.setUserId(2);
user.setUsername("new_username2");

//before i want to remove or update the record on the list which contain user id #2
userList.add(user);

我想从列表中搜索userList.contains(2),然后用新值删除或更新它。


2
为什么不重用现有的用户对象? - wero
我能不使用用户对象吗?如果可能的话,我只想使用.contains()。 - Cris
1
不太清楚你的意思,但是javatutorial中使用Map的答案可能是正确的解决方案。 - wero
5个回答

8
如果您知道元素的位置,请只执行以下操作:
userList.get(index).setUsername("newvalue");

如果没有,您需要循环所有元素以找到要更新的元素。
for (User user : userList) {
    if (user.getUserId().equals(searchedId)) {
        user.setUsername("newvalue");
        break;  
    }
}

那如果我不想使用循环对象,但是又不知道该记录在列表中的位置呢? - Cris
这是第二个代码块。如果您知道要搜索的ID(而不是索引)。 - Davide Lorenzo MARINO
不要忘记添加notifyDataSetChanged()来刷新ListView。 - Daniel Nyamasyo

5
在您的情况下,我认为使用Map比List更好:
Map<Integer, User> userMap = new HashMap<Integer, User>();

User user = new User();
user.setUserId(1);
user.setUsername("user1");
userMap.put(user.getUserId(), user);

user = new User();
user.setUserId(2);
user.setUsername("user2");
userMap.put(user.getUserId(), user);

user = new User();
user.setUserId(3);
user.setUsername("user3");
userMap.put(user.getUserId(), user);

以这种方式,您可以直接搜索所需的userId:
User userToModify = userMap.remove(idToModify);
userToModify.setUsername("new name");
userToModify.setUserId(54);
userMap.put(user.getUserId(), userToModify);

如果您只需要通过一个字段(在这种情况下为userId)查找对象,则使用Map更高效、易于使用(和维护)。


谢谢,我认为这比列表更有效率。 - Cris
是的,如果您的列表仅在此上下文中使用,则更有效率。如果您还需要一个列表(用于代码的其他部分),则需要检查是否最好拥有两个不同的数据结构或仅一个。 - Davide Lorenzo MARINO
除非你需要特定的List功能,否则你不必使用另一个不同的数据结构,因为Map提供了一个很好的values()方法,它返回Map中存储的所有值(在这种情况下是User对象)的集合。通常这就足够了。此外,由于返回的集合是由Map支持的(即其对象与之紧密链接),对集合的每个操作也会对Map产生影响(元素删除、对象更新等),从而避免了代码和数据结构的重复。 :) - javatutorial
@javatutorial 你说得对。但是列表是有序集合,而映射不是。如果代码需要知道插入顺序的信息,则需要维护一个列表。我不知道代码,所以我说“如果您还需要列表(用于代码的其他部分)”。values() 不等同于列表,因为它不遵守插入顺序。 - Davide Lorenzo MARINO
@DavideLorenzoMARINO:有LinkedHashMap,它保留插入顺序,因此使用values()可以获得有序的集合(也可以参见这里)。 通常复制数据结构是一个不好的主意,因为你总是需要对Map和List进行两次操作。但当然,如果你需要一些特定的功能(比如LinkedList的队列-双端队列方法),那么这可能是一个解决方案。 - javatutorial
@javatutorial 不错的想法! - Davide Lorenzo MARINO

2

如果只需要更新名称,则无需创建新对象并将其插入列表中。如@Davide所指出的那样,您可以遍历列表并设置用户名。

我建议在此基础上,为了效率起见,使用Hashtable<Integer,User> userTable而不是列表,以防止遍历整个列表以查找正确的用户。

这样,您可以通过其ID高效地获取用户并设置用户名,如下所示:userTable.get(id).setUsername("新用户名")


2
 for(User user : userList) {
    if(user.getId == 2) {
        user.setUsername("newUsername")
    }
}

这只是一个清晰的例子,供您理解如何实现它 - 不是为了复制粘贴,先生... - i23

0
如果您想要更改列表中位置K的对象的某些属性,如上所述,请使用以下代码:

userList.get(k).setAttribute(someValue);

然而,如果您想要用一个新的对象替换整个对象,请使用List的set()方法:

userList.set(k,U); //其中,U是一个新的User

另一种选择是删除该项目并在其位置添加一个新项目:

userList.remove(k);
userList.add(k, U);

然而,如果k项是在其移除之前列表的最后一个元素,则需要执行以下操作: userList.remove(k); userList.add(U); // 添加到列表末尾

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