根据自定义对象属性从arraylist中删除元素

时间:2013-05-22 11:54:12

标签: java arraylist iterator

我有一个带有自定义对象的ArrayList。我想要的是从数组中删除重复项,具体取决于自定义对象的name属性。我试图使用Set person = new TreeSet();但它不起作用。我猜因为该集合比较地址或其他名称属性。所以我现在正在尝试使用一个迭代器,它不会删除重复项。这就是我得到的;

ArrayList<Person> people = new ArrayList<Person>();
Iterator<Person> iterator = people.iterator();
while (iterator.hasNext()) {
   Person person = iterator.next();

   if (person.getName().equals(iterator.next().getName())) {
       iterator.remove();
   }
}
for (Person person : people) {
    System.out.println(person.getName());
}

尽管我看到了重复的ArrayList,但它没有被修改。我需要一些帮助。谢谢!

4 个答案:

答案 0 :(得分:10)

我有同样的情况,我想出了使用SortedSet的解决方案。在这种情况下,那些导致set的比较器返回0的对象只会在Set中插入一次。

以下是一个例子:

SortedSet<Person> persons = new TreeSet<Person>(new Comparator<Person>() {
    @Override
    public int compare(Person arg0, Person arg1) {
        return arg0.getName().compareTo(arg1.getName());
    }
});

现在,如果您在Person中插入persons,则不会插入重复项(基于其name属性)。

因此,您可以对list<Person>进行迭代,并将其中的每个项目插入到persons集中,并确保不会有任何重复项。所以剩下的就像:

Iterator<Person> iterator = people.iterator();
while(iterator.hasNext()) {
    persons.add(iterator.next());
}
people.clear();
people.addAll(persons); //Now, your people does not contain duplicate names

答案 1 :(得分:2)

您的代码目前已损坏,因为您只将对象与列表中的下一个对象进行比较。要纠正当前的方法,您需要使用另一个子循环,将每个对象与列表中的 all 其他对象进行比较。这可能会使嵌套迭代器变得混乱。

一种替代方法是定义一个新列表,并在确认它们不是重复项后用项目填充它。这样可以避免嵌套迭代器。

最后,另一种选择是定义一个基于此属性进行比较的equals方法,并将对象放在Set中。不要忘记hashCode

答案 2 :(得分:2)

它不会被删除,因为您只是将每个元素与下一个元素进行比较。您可以将名称存储在HashSet中,该HashSet只能容纳每个String中的1个,如果其名称已经在该集合中,则删除该项目。

HashSet<String> seen = new HashSet<String>();
while (iterator.hasNext()) {
     Person p = iterator.next();
     if (seen.contains(p.getName())) {
           iterator.remove();
     } else { 
           seen.add(p.getName());
     }
}

答案 3 :(得分:0)

每当你编写.next()时,迭代都会向前迈出一步。所以,假设你的名单中有10个人。你挑选第一个人,并使用iterator.next()检查下一个人。虽然你取第二个人,但是迭代器现在是第二个人。所以在下一次运行中,第三个人被取出并与第四个人进行比较。

你应该做的是,挑选1个人并将他的名字与列表中所有10个人的名字进行比较,然后从列表中删除所有重复对象的实例。