I have been trying to find an elegant solution to the following problem.
Let's say we have two Lists (java.util.List) that both solely contain objects of type Person. Person, in turn, has a property 'name' which can be retrieved by Person.getName().
I am interested in any Person from List A that matches the same name as any of the Persons in List B.
My first thought is to create some sort of iteration like
Iterator i = listA.iterator();
while(i.hasNext()) {
Person p = (Person) i.next();
String name = p.getName();
// ...and then do an inner iteration through listB, to compare
// each and every Person.getName() in listB to this name.
}
I don�t like this and I hope you agree. This is especially performance consuming when having large Lists. There must be some kind of comparison possible using some standard library?
Anyway, I made up an alternative which I am about to implement in a professional assignment. I�d like to know if this can be called a more elegant solution.
First, I create a Comparator called SearchComparator which has the mandatory method compare(Object o1, Object o2). Instead of using both attributes, I only use o1, cast it to Person and compare its name to the name I specify through the Comparator�s constructor. If the names are equal, the result of compare is -1, meaning the object will be moved forward in the Collection, otherwise it�s 1, meaning it will be moved backwards.
public class SearchComparator implements Comparator {
private String name;
public SearchComparator (String name) {
this.name = name;
}
public int compare(Object o1, Object o2) {
Person p1 = (Person) o1;
return p1.getName().equals(name) ? -1 : 1;
}
}
Just like in the first example, I�ll be iterating through listA using Iterator, and I retrieve the name of the Person provided by the next iteration. Nothing different.
But now, I pass this name to a new instance of my SearchComparator, and use it to sort listB using Collections.sort(). The effect is, that it the name occurs in listB, it is now at position 0 of listB. So, I
test the name to the name of to person at listB.get(0) and if they�re equal, I have found a match. Then comes the next iteration.
Iterator i = listA.iterator();
while(i.hasNext()) {
Person p = (Person) i.next();
Collections.sort(listB, new SearchComparator( p.getName() ));
if ((Person)listB.get(0)).getName().equals( p.getName() ) {
// found a match�
}
}
It�s more code, and might be hard to comprehend at first glance, but I think it�s less performance expensive than using iterations within iterations.
I�d like to know if there are other solutions, perhaps standard framework API�s that solve this with one line of code, like Framework.match(listA, listB, �name�); :-)
Please let me know what you think. Thanks.