2

I have and ArrayList with two strings and an Integer, but I just need to sort it by the string Name and the string LastName, I tried with the method Collections.sort like this

    Collections.sort(MyArrayList, (Contact v1, Contact v2) -> v1.getName().compareTo(v2.getname()));

But this sorts my ArrayList just by the names, and doesn't include the last name, how can I add to the sort the last names?

Lyubomyr Shaydariv
  • 20,327
  • 12
  • 64
  • 105
  • 1
    Possible duplicate: http://stackoverflow.com/questions/1421322/how-do-i-sort-a-list-with-multiple-sort-parameters . Your comparator must respect the last name too. – Lyubomyr Shaydariv Sep 30 '15 at 06:36

3 Answers3

3

Use Comparator.comparing(Contact::getName).thenComparing(Contact::getLastName) for your Comparator:

Collections.sort(MyArrayList, Comparator.comparing(Contact::getName).thenComparing(Contact::getLastName));
Bohemian
  • 412,405
  • 93
  • 575
  • 722
2

Well you just need to change your comparison function to include other fields like this

    Collections.sort(contacts, (Contact c1, Contact c2) -> {
        int firstNameComparisonResult = c1.getFirstName().compareTo(c2.getFirstName());
        if (firstNameComparisonResult != 0) {
            return firstNameComparisonResult;
        } else {
            return c1.getLastName().compareTo(c2.getLastName());
        }
    });

Warning: this assumes there are no nulls.

Full code I used if you want to take a look:

class Contact{
    final String firstName;
    final String lastName;
    final int age;

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    public Contact(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", age=" + age +
                '}';
    }
}

@Test
public void sortTest(){
    List<Contact> contacts = new ArrayList<>();
    contacts.add(new Contact("A","B",37));
    contacts.add(new Contact("A","C",34));
    contacts.add(new Contact("B","A",35));

    Collections.sort(contacts, (Contact c1, Contact c2) -> {
        int firstNameComparisonResult = c1.getFirstName().compareTo(c2.getFirstName());
        if (firstNameComparisonResult != 0) {
            return firstNameComparisonResult;
        } else {
            return c1.getLastName().compareTo(c2.getLastName());
        }
    });

    System.out.println(contacts);
 //[Contact{firstName='A', lastName='B', age=37}, Contact{firstName='A', lastName='C', age=34}, Contact{firstName='B', lastName='A', age=35}]

}
Paweł Chorążyk
  • 3,584
  • 3
  • 27
  • 33
0

Well ... transform your closure into a full anonymous class, and use that power to increase your sort complexity ...

Something like

 Collections.sort(MyArrayList, new Comparator<Contact>() {
    public int compare(Contact v1, Contact v2) {
        int returned =  v1.getvName().compareTo(v2.getname())
        if(returned==0) {
            // alas, Math.signum returns a float value in this cas
            returned = (int) Math.signum(v1.getYourInt(), v2.getYourInt())
        }
        return returned;
    }
 });

WARNING This code has not been compiled in any way.

Riduidel
  • 22,052
  • 14
  • 85
  • 185