我正在尝试找到一种基于某些规则从列表中过滤掉某些项目的最佳方法。例如我们有
public class Person{
String name;
String sex;
String dob;
String contactNo;
Person(String name, String sex, String dob, String contactNo) {
this.name = name;
this.sex = sex;
this.dob = dob;
this.contactNo = contactNo;
}
}
List<Person> persons = Arrays.asList(new Person("Bob", "male", "19800101", "12345"),
new Person("John", "male", "19810101", "12345"),
new Person("Tom", "male", "19820101", "12345"),
new Person("Helen", "female", "19800101", "12345"),
new Person("Jack", "male", "19830101", "12345"),
new Person("Suan", "female", "19850101", "12345"));
我想删除具有相同 dob 和 contactNo 的一对男性和女性(在上面的示例中删除 Bob 和 Helen)。我使用嵌套循环实现了这一点,该循环有效但看起来很难看。请问有没有更好的方法来实现这一点?我可以实施谓词来做到这一点吗?
public void filterPersons() {
List<Person> filtered = new ArrayList<Person>();
for (Person p: persons) {
boolean pairFound = false;
for (Person t: persons) {
if ((p.sex.equals("male") && t.sex.equals("female")) || (p.sex.equals("female") && t.sex.equals("male"))) {
if (p.dob.equals(t.dob) && p.contactNo.equals(t.contactNo)) {
pairFound = true;
break;
}
}
}
if (!pairFound) {filtered.add(p);}
}
System.out.println("filtered size is: " + filtered.size());
for (Person p: filtered) {
System.out.println(p.name);
}
}
非常感谢。
我已经重写了上面的方法,如下所示,看起来更好恕我直言:
public void testFilter() {
Predicate<Person> isPairFound = new Predicate<Person>() {
@Override public boolean apply(Person p) {
boolean pairFound = false;
for (Person t: persons) {
if ((p.sex.equals("male") && t.sex.equals("female")) ||
(p.sex.equals("female") && t.sex.equals("male"))) {
if (p.dob.equals(t.dob) && p.contactNo.equals(t.contactNo)) {
pairFound = true;
break;
}
}
}
return pairFound;
}
};
Iterable<Person> filtered = Iterables.filter(persons, isPairFound);
for (Person p: filtered) {
System.out.println(p.name);
}
}