从ArrayList中删除特定值的项目

17

我已经创建了一个对象列表,并添加了人员:

ArrayList<Person> peeps = new ArrayList<Person>(); 

peeps.add(new Person("112", "John", "Smith"));
peeps.add(new Person("516", "Jane", "Smith"));
peeps.add(new Person("114", "John", "Doe"));
我正在尝试弄清楚如何通过ID号码从列表中删除一个人。所以,如果我想删除ID号为114的人,但不知道它在列表中的位置,我该怎么做?
我正试图找出如何按ID号码从列表中删除人员。那么,如果我想删除ID号为114的人,但不知道它在列表中的位置,我应该怎么做?

5
你必须使用ArrayList吗?使用HashMap<Integer(ID),Person>会更好。 - lacraig2
2
你没有为你的问题选择正确的数据结构。使用Map而不是List - Asaph
你能扩展你的Person类吗? - ddagsan
@lacraig2 Map<String, Person> - m0skit0
@m0skit0 是真的。它将是一个字符串。像这样存储整数有点奇怪,但它是一个字符串。 - lacraig2
@lacraig2 我一开始也是这么想的,但如果你仔细想想,这并不奇怪。这些是ID,你不会对它们执行数值操作,所以没有理由将它们视为数字。通过将它们声明为字符串,你可以清楚地表明这一点。你可能还想拥有一个“001”ID,这是无法使用数字存储的。 - m0skit0
7个回答

49

使用Java8:

peeps.removeIf(p -> p.getId().equals("112"));

请注意,这相当于线性搜索,需要O(n)的时间。如果此操作将频繁重复,则建议使用HashMap以加快速度至O(1)
另外,使用排序列表也可以达到同样的效果,但需要O(log n)的时间。

1
不错,使用了Java 8的lambda表达式和新功能。 - m0skit0
1
很好,它很直接易用。 - jitendra varshney
太棒了!很好地使用了SE 8!让我省去了大量的麻烦,不用迭代来删除那个对象。 - Zhi Kai

13

如果您将使用ArrayList,则唯一的方法是遍历整个列表,查看每个人,并查看其ID号是否为114。对于较大的数据集,这样做将是低效的,应该避免。

如果您可以更改数据结构,则某种类型的Map会更好(HashMap通常是一个不错的选择)。您可以将ID号作为“键”,然后将其与每个人相关联。稍后,您可以通过关键字查询Map。缺点是您只能将一个值作为键,因此无法同时拥有名称和ID号键。

编辑:
使用ArrayList更有效的一种方法是按ID号进行排序。然后,您可以使用类似Collections.binarySearch()这样的内容快速访问元素by ID号。缺点是从/插入到排序数组中很昂贵,因为所有大于该元素的元素都必须移动。因此,如果相对于读取数量而言要进行相对较少的更改,则可能是可行的。


1
好答案,但这不是唯一的方法。有关 Map 的建议很好。 - m0skit0

7

有很多方法可以解决这个问题。

  1. 我正在使用来自apache.common.collection4的CollectionUtils或其谷歌等效物。然后使用谓词或在java 8中使用lambda表达式选择您希望的内容。
CollectionUtils.select(peeps, new Predicate<Person>() {
    @Override
    public boolean evaluate(Person object) {
        return object.getId().equals("114");
    }
});

使用好老的迭代器并循环遍历它。
Iterator<Person> iterator = peeps.iterator();
while(iterator.hasNext()) {
   Person next = iterator.next();
   if(next.getId().equals("114")) {
       iterator.remove();
   }
}

3

迭代 ArrayList 的元素并移除与所需移除的字符串匹配的元素:使用 Iterator remove 操作是安全的,不会产生 ConcurrentModificationException

for (Iterator<String> iterator = peeps.iterator(); elementToCheck = iterator.next();) {
    if (elementToCheck.getId().equals("112")) {
        // Remove the current element from the iterator and the list.
        iterator.remove();
    }
}

真的。我已经修改了它。迭代器删除是安全的,并不会引起异常。 - adrCoder
你可以在 for 循环中直接写入 elementToCheck = iterator.next() ;) - m0skit0
真的 :D 改了它 ;-) - adrCoder

3

首先,在Person类中需要有一个有效的equals方法(这是应该有的)。然后,您可以直接使用List#indexOfList#remove。例如:

final Person toRemove = new Person("112");
peeps.remove(peeps.indexOf(toRemove));

(假设Person ID是唯一的)。或者,如果您的列表是ArrayList,则可以使用ArrayList#remove(Object):
final Person toRemove = new Person("112");
peeps.remove(toRemove);

如果您使用的是Java 8,您可以使用Paul的解决方案

0

如果你想搜索字符串,那么应该使用 .equals 方法。

String query;
ArrayList<String> list;

   for(int i=0; i < list.size();i++)
       if (list.get(i).equals(query)){
           list.remove(i);
           break;
       }

ArrayList<Person> 在问题中已经很清楚了。 - m0skit0

-1
class Processor{

ArrayList<Person> peeps = new ArrayList<Person>(); 

void setPeeps(){
    peeps.add(new Person(112, "John", "Smith"));
    peeps.add(new Person(516, "Jane", "Smith"));
    peeps.add(new Person(114, "John", "Doe"));
}

void removePerson(int id){
    for(int i=0; i <= peeps.size(); i++){
        Person person = peeps.get(i);
        if(person.id == id)
            peeps.remove(peeps.get(i));
    }
}

void displayPersonsList(){
    for(Person person : peeps){
        System.out.println(person.id + ":" + person.fName + ":" + person.lName);
    }
}

public static void main(String args[]){
    Processor objProcessor = new Processor();
    objProcessor.setPeeps();
    objProcessor.removePerson(114);
    objProcessor.displayPersonsList();
}
}

class Person{
int id;
String fName;
String lName;

public Person(int id, String fName, String lName){
    this.id = id;
    this.fName = fName;
    this.lName = lName;
}
}

我不只是在这里输入代码。我在STS上尝试运行了它,然后复制了它。你能把你的错误发在这里吗?我再试了一次,它可以正常工作! - Jobin Thomas
@JobinThomas,尝试删除除最后一个条目以外的任何条目!(假设您仍在阅读该网站) - user85421

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