Build a Comparator<Person>实现自然键排序,然后使用基于二分搜索的重复数据删除。TreeSet会给你这种开箱即用的能力。
注意Comparator<T>.compare(a, b)必须满足通常的反对称性、传递性、一致性和自反性要求或二分搜索排序将失败。您还应该使其能够识别空值(例如,如果一个、另一个或两者的名字字段为空)。
Person 类的一个简单的自然键比较器如下(它是一个静态成员类,因为您没有显示每个字段是否有访问器)。
public class Person {
public static class NkComparator implements Comparator<Person>
{
public int compare(Person p1, Person p2)
{
if (p1 == null || p2 == null) throw new NullPointerException();
if (p1 == p2) return 0;
int i = nullSafeCompareTo(p1.firstname, p2.firstname);
if (i != 0) return i;
i = nullSafeCompareTo(p1.lastname, p2.lastname);
if (i != 0) return i;
return p1.age - p2.age;
}
private static int nullSafeCompareTo(String s1, String s2)
{
return (s1 == null)
? (s2 == null) ? 0 : -1
: (s2 == null) ? 1 : s1.compareTo(s2);
}
}
private String firstname, lastname;
private int age;
private long id;
}
然后您可以使用它来生成唯一的列表。使用add返回的方法true
当且仅当该元素尚不存在于集合中时:
List<Person> newList = new ArrayList<Person>();
TreeSet<Person> nkIndex = new TreeSet<Person>(new Person.NkComparator());
for (Person p : originalList)
if (nkIndex.add(p)) newList.add(p); // to generate a unique list
或将最后一行替换为该行以输出重复项
if (nkIndex.add(p)) newList.add(p);
无论你做什么,都不要使用remove
在枚举原始列表时,这就是为什么这些方法将您的独特元素添加到新列表中。
如果您只对唯一列表感兴趣,并且希望使用尽可能少的行:
TreeSet<Person> set = new TreeSet<Person>(new Person.NkComparator());
set.addAll(originalList);
List<Person> newList = new ArrayList<Person>(set);