我有一个带有自定义对象的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,但它没有被修改。我需要一些帮助。谢谢!
答案 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个人的名字进行比较,然后从列表中删除所有重复对象的实例。