我有以下逻辑删除系统中的非活动用户,因为我们在迭代列表时无法删除行。有没有更好的方法来解决这个问题?
List<User> users = new ArrayList<User>();
List<User> removeUsers = new ArrayList<User>();
for (User user : users) {
if (!user.isActive()) {
removeUsers.add(user);
}
}
users.removeAll(removeUsers);
答案 0 :(得分:13)
如果使用ArrayList,最好的方法是Jeff M的变体。您也可以使用您的变体,但您应该考虑使用Set(HashSet或IdentityHashSet)而不是ArrayList for removeUser。对于大量数据,它将具有更好的性能。
但对于LinkedList,最好的方法是使用Iterator.remove方法:
for (Iterator<User> it = users.iterator(); it.hasNext();)
if (it.next().isActive())
it.remove();
答案 1 :(得分:8)
这是一个非常好的方式来做它恕我直言。
我可能采用的其他方式,使用索引并在反向循环时删除。
for (int i = users.size()-1; i >= 0; i--)
{
if (!users.get(i).isActive())
{
users.remove(i);
}
}
或者创建要保留的项目的新列表,并将其替换为旧列表。
List<User> newUsers = new ArrayList<User>();
for (User user : users)
{
if (user.isActive())
{
newUsers.add(user);
}
}
users = newUsers;
目前无法想到任何其他人。
答案 2 :(得分:4)
如何使用Guava魔法?
List<User> users = new ArrayList<User>();
Iterables.removeIf(users, new Predicate<User>() {
@Override
public boolean apply(User user) {
return !user.isActive();
}
});
如果你在几个地方使用Predicate,你甚至可以为它创建一个命名类,让你的代码更好:
private static final class IsNotActiveUserPredicate implements Predicate<User> {
@Override
public boolean apply(User user) {
return !user.isActive();
}
}
List<User> users = new ArrayList<User>();
Iterables.removeIf(users, new IsNotActiveUserPredicate());
答案 3 :(得分:3)
Gosling希望我们这样做的方法是使用Iterator.remove
:
Iterator<User> it = users.iterator();
while (it.hasNext()) {
if (! it.next().isActive()) {
it.remove();
}
}
如果您使用ArrayList
,从性能角度来看这可能不是最好的,但是再次看来,您似乎可以考虑更改为LinkedList
。
无论如何,这是在迭代时从集合中删除元素的方法。
答案 4 :(得分:1)
你可以这样做:
for (int i = users.size()-1; i >= 0; i--) {
if (!users.get(i).isActive()) {
users.remove(i);
}
}
答案 5 :(得分:0)
这是使用Collections2.filter的另一个番石榴版本:
final List<User> activeUsers =
Lists.newArrayList(Collections2.filter(userList, new Predicate<User>(){
@Override
public boolean apply(final User input){
return input.isActive();
}
}));
答案 6 :(得分:0)
这是另一种基于数组的列表相当有效的方法。这是因为每次删除都不需要复制整个尾部。它使用两个步骤:首先将所有需要保留的元素复制到列表开头的最终位置,然后删除列表末尾的所有剩余元素。
public static void removeInactiveUsers( ArrayList<User> users )
{
int j = 0, len = users.size();
for( int i = 0; i < len; ++i )
{
User user = user.get( i );
if( user.isActive() )
{
if( i != j )
users.set( j, user );
++j;
}
}
users.removeRange( j, len );
}
答案 7 :(得分:0)
如果要删除任何一个对象,如当前对象或所选对象,您可以按照以下步骤进行操作。
Object currentObject = null;
for (User user : users)
{
if (user.isActive())
{
currentObject = user ;
}
}
if(currentObject != null) {
users.remove(currentObject);
}
答案 8 :(得分:0)
我意识到这是一个古老的问题,但它是我在进行搜索时提出的,因此其他人可能仍会来到这里。使用Java 8,最简单的方法是在Collection类上使用新的“ removeIf”方法,如下所示:
users.removeIf(user -> !user.isActive());
轻松自如! 应该注意的是,在幕后,Java代码使用的是Iterator.remove()。