List<Persons> теперь сортируется по имени, затем по возрасту.
String.compareTo "Сравнивает две строки лексикографически" - из документов.
Collections.sort это статический метод в библиотеке native Collections. Он выполняет фактическую сортировку, вам просто нужно предоставить компаратор, который определяет, как следует сравнивать два элемента в вашем списке: это достигается путем предоставления вашей собственной реализации compare метода.
Ответ 2
Для тех, кто может использовать потоковый API Java 8, существует более аккуратный подход, который хорошо документирован здесь: лямбды и сортировка
Ознакомьтесь со ссылкой выше, чтобы узнать более аккуратный способ и объяснение того, как вывод типов Java делает его определение немного более неуклюжим по сравнению с LINQ.
// Define chained comparators: // Great article explaining this and how to make it even neater: // http://blog.jooq.org/2014/01/31/java-8-friday-goodies-lambdas-and-sorting/ Comparator<Person> comparator = Comparator.comparing(person -> person.name); comparator = comparator.thenComparing(Comparator.comparing(person -> person.age));
// Sort the stream: Stream<Person> personStream = people.stream().sorted(comparator);
// Make sure that the output is as expected: List<Person> sortedPeople = personStream.collect(Collectors.toList()); Assert.assertEquals("Andi", sortedPeople.get(0).name); Assert.assertEquals(2, sortedPeople.get(0).age); Assert.assertEquals("Barry", sortedPeople.get(1).name); Assert.assertEquals(20, sortedPeople.get(1).age); Assert.assertEquals("Barry", sortedPeople.get(2).name); Assert.assertEquals(50, sortedPeople.get(2).age); Assert.assertEquals("Bob", sortedPeople.get(3).name); Assert.assertEquals(40, sortedPeople.get(3).age); Assert.assertEquals("Bob", sortedPeople.get(4).name); Assert.assertEquals(42, sortedPeople.get(4).age); Assert.assertEquals("Bob", sortedPeople.get(5).name); Assert.assertEquals(72, sortedPeople.get(5).age); Assert.assertEquals("Cathy", sortedPeople.get(6).name); Assert.assertEquals(40, sortedPeople.get(6).age); Assert.assertEquals("Dan", sortedPeople.get(7).name); Assert.assertEquals(4, sortedPeople.get(7).age); Assert.assertEquals("Debby", sortedPeople.get(8).name); Assert.assertEquals(3, sortedPeople.get(8).age); // Andi : 2 // Barry : 20 // Barry : 50 // Bob : 40 // Bob : 42 // Bob : 72 // Cathy : 40 // Dan : 4 // Debby : 3 }
/** * A person in our system. */ publicstaticclassPerson { /** * Creates a new person. * @param name The name of the person. * @param age The age of the person. */ publicPerson(String name, int age) { this.age = age; this.name = name; }
/** * The name of the person. */ public String name;
/** * The age of the person. */ publicint age;
@Override public String toString() { if (name == null) returnsuper.toString(); elsereturn String.format("%s : %d", this.name, this.age); } }
Ответ 3
Используя подход Java 8 Streams, со ссылками на методы в геттерах...
// Create a stream... varsortedList= persons.stream() // sort it (does not sort the original list)... .sorted(Comparator.comparing(Person::getName) .thenComparing(Person::getAge)); // and collect to a new list .collect(Collectors.toList());
//Sorts the original list Lambda style persons.sort((p1, p2) -> { if (p1.getName().compareTo(p2.getName()) == 0) { return p1.getAge().compareTo(p2.getAge()); } else { return p1.getName().compareTo(p2.getName()); } });
Наконец...
// This syntax is similar to the Streams example above, but sorts the original list!!! persons.sort(Comparator.comparing(Person::getName).thenComparing(Person::getAge));
Ответ 4
Вам нужно реализовать свое собственное Comparator, а затем использовать его: например
Компаратор сначала сравнивает имена, если они не равны, он возвращает результат их сравнения, в противном случае он возвращает результат сравнения при сравнении возраста обоих лиц.
Этот код является всего лишь черновиком: поскольку класс неизменяем, вы могли бы подумать о создании из него синглтона, вместо этого создавая новый экземпляр для каждой сортировки.