views:

384

answers:

5

I need help to write a comparator :-

I want this output :-

Martin Joseph Male 4/2/1979 Green 
Ramya  Patil  Female 5/4/2009 Red
Don    kelly  Male   5/6/1986 Yellow
Van    Shinde female 3/4/1984 Green

But i am getting the following output :-

Output 1:
 Van    Shinde female 3/4/1984 Green
 Don    kelly  Male   5/6/1986 Yellow
 Ramya  Patil  Female 5/4/2009 Red
 Martin Joseph Male 4/2/1979 Green

how do i sort on last name keeping the order of the list intact .. i mean i want to output female first sorting on last name and then male sorted on last name ... please help me guys ..

this is the comparator i am using after i use the gender comparator :-

public class LastNameComparator implements Comparator<Person> {


public int compare(Person name_one, Person name_two) {
     // TODO Auto-generated method stub
     if(name_one.getGender().equals(name_two.getGender())){
      return name_one.getLast_name().compareTo(name_two.getLast_name());

     }else{
     return name_one.getLast_name().compareTo(name_two.getLast_name());
     }
    }

}
+4  A: 
public int compare(Person a, Person b) {
  int ret = a.getGender().compareTo(b.getGender());
  if (ret == 0) {
    ret = a.getLastName().compareTo(b.getLastName());
  }
  return ret;
}
cletus
A: 

As a complement to cletus's answer, here's a version using a CompareToBuilder (from Apache Commons Lang):

public int compare(Person lhs, Person rhs) {
    return new CompareToBuilder()
            .append(lhs.getGender(), rhs.getGender())
            .append(lhs.getLastName(), rhs.getLastName())
            .toComparison();
}
Chris Jester-Young
+1  A: 

When I read the code in your OP I see that you're always returning the result of comparing by the last name:

If genders are equal
  then compare last names
  else compare last names

However that doesn't much the experimental results which you say you're getting; so as well as modifying your code to match Cletus' suggestion, maybe something else is wrong with your code as well.

ChrisW
+1  A: 

Cletus' solution is probably the most appropriate here, but if you want to take it a little further...

LastNameComparator is rather misleadingly named, since it actually compares on gender as well as last name. It might be less ambiguous to split this functionality into two separate Comparators:

class GenderComparator implements Comparator<Person> {
    public int compare(Person a, Person b) {
        return a.getGender().compareTo(b.getGender());
    }
}

class LastNameComparator implements Comparator<Person> {
    public int compare(Person a, Person b) {
        return a.getLastName().compareTo(b.getLastName());
    }
}

Then, combine the functionality in a 'custom' Comparator:

Comparator<Person> genderThenLastNameComparator = new Comparator<Person>() {
    public int compare(Person a, Person b) {
        int result = new GenderComparator().compare(a, b);
        return result == 0 ? new LastNameComparator().compare(a, b) : result;
    }
}

It's more complicated, but more flexible and reusable. (Which may or may not be justified for such a simple case.)

harto
i like it harto .. thanks a lot
if you like that, the apache commons has built-in comparator chaining: http://commons.apache.org/sandbox/cli2/apidocs/org/apache/commons/cli2/util/Comparators.html
Carl
So does Google collections: http://code.google.com/p/google-collections/
parkr
So the relevant code for the commons `Comparators` class would be `Comparator<Person> c = Comparators.chain(new GenderComparator(), new LastNameComparator());`. Looks pretty neat.
harto
A: 

This should be relatively simple:

here are the rules you specified:

  • females before males
  • names sorted in last name ascending

you do something like this:

// if the genders are not equal, return <0 if this object's gender is female
// else 
//    return lastName.compareTo( obj.lastName );

that's all you need to implement this comparator...

then when you want to sort it, use the collections framework sort!

public static <T> void sort(List<T> list,
                            Comparator<? super T> c)

This is a stable sort too...which is awesome. If you answer it this way I'm sure you'll get the job.

vinnybad