В данном уроке я бы хоте показать, каким образом можно создать коллеккцию, для хранение объектов в сортированом виде.
Где вам это может пригодится?
Допустим у вас есть надор данных, а точней набор объектов с данными, и вы их помещаете в список, коллекцию, но как известно, то в не все коллекции сохраняют порядок добавления, а также не все имеют возможность сортировать элементы.
Что же делать в том случае, когда вам нужно отсортировать элементы коллекции? Именно это мы сейчас и рассмотрим.
На днях мне пришлось применить данный способ сортировки, вот я решил им поделится с вами. В этом примере мы научимся сортировать по дате рождения, и по возврасту.
Хочу обратить ваше внимание, что данные для тестирование сортировки были придуманы, и не соответствуют реальным.
Шаг 1. Создание проекта и его структура
По традиции всех уроков как всегда создаем проект:
А структура всего проекта будет достаточно проста:
Теперь кратко о структуре. Как вы видите есть два пакета comparator и pojo в первом будут лежать компараторы (будут рассмотрены ниже), а во втором наш объект который мы будем сортировать.
Все это мы будем проверять с помощью JUnit 4.11 вот зависимость для pom.xml:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency>
На этом этап подготовки закончен, давайте теперь напишем POJO.
Шаг 2. Создание POJO
Я создал простой объект с 3-мя полями и назвалд его People, который имеет имя, возвраст и дату рождения:
package com.devcolibri.exam.pojo; import java.util.Date; public class People { private String fullName; private int age; private Date birthday; public People(String fullName, int age, Date birthday) { this.fullName = fullName; this.age = age; this.birthday = birthday; } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return getClass().getSimpleName() + " {" + "\n\tName: " + this.fullName + ";" + "\n\tAge: " + this.age + ";" + "\n\tBirthday: " + birthday + "\n}"; } }
Как видите я переопределил метод toString(), чтобы было удобней выводить его содержимое в тестах.
Шаг 3. Создание компараторов
Что такое компаратор в Java Collection?
Это класс позволяющий сравнивать данные для их разделение, и с его помощью можно сравнивать данные обьекта для того чтобы определить куда его вставить в списке.
А теперь создадим первый компаратор, который будет сортировать по дате рождения. Создаем класс и называем его PeopleBirthdayComparator:
package com.devcolibri.exam.comparator; import com.devcolibri.exam.pojo.People; import java.util.Comparator; public class PeopleBirthdayComparator implements Comparator<People> { @Override public int compare(People people1, People people2) { return people1.getBirthday().compareTo(people2.getBirthday()); } }
Как видите он достаточно простой, мы реализуем интерфейс Comparator указываем ему дженерик наш объект – это тот объект, который будет добавляться в список.
Дальше мы должны реальзовать один метод compare в нем мы должны указать сравнение по дате, что и вернет нам число, которое определит позицию в списке.
Теперь создадим компаратор, который будет сортировать по возврасту человека, назовем его PeopleAgeComparator:
package com.devcolibri.exam.comparator; import com.devcolibri.exam.pojo.People; import java.util.Comparator; public class PeopleAgeComparator implements Comparator<People> { @Override public int compare(People people1, People people2) { return people1.getAge() - people2.getAge(); } }
Тут аналогичным способом мы определяем, между двух обьектов, какой должен быть на какой позиции, и в качестве фильтра используется разница возвраста.
Шаг 4. Тестирование компараторов
Первым будем тестировать PeopleBirthdayComparator для него создаем в тестах класс PeopleBirthdayComparatorTest:
package com.devcolibri.exam.comparator; import com.devcolibri.exam.pojo.People; import org.junit.Before; import org.junit.Test; import java.util.GregorianCalendar; import java.util.Set; import java.util.TreeSet; public class PeopleBirthdayComparatorTest { private Set<People> peoples; @Before public void setUp() throws Exception { // Инициализируем наш список и указываем наш компаратор // который будет выполнять фильтрацию элементов и их положение в списке peoples = new TreeSet<People>(new PeopleBirthdayComparator()); } @Test public void testAddPeople() throws Exception { // Создаем тестовые объекты People people1 = new People("Alex Barchuk", 21, GregorianCalendar.getInstance().getTime()); Thread.sleep(100); People people2 = new People("Jered Gogs", 54, GregorianCalendar.getInstance().getTime()); Thread.sleep(100); People people3 = new People("Mike Devidson", 31, GregorianCalendar.getInstance().getTime()); Thread.sleep(100); People people4 = new People("Steve Jobs", 40, GregorianCalendar.getInstance().getTime()); Thread.sleep(100); // В любом порядке добавляем их в список // В зависимости от фильтра объекты будут в момент добавления // определять свое место с помощью компаратора и мы в итоге получим отсортированый список peoples.add(people1); peoples.add(people4); peoples.add(people3); peoples.add(people2); // Выводим все элементы списка for(People people : peoples){ System.out.println(people); } } }
Как вы возможно заметили я после каждой инициализации вызываю Thread.sleep(100); чтобы поток заснул на 100 миллисекунд, это делается для того чтобы дата у каждого People была разной, потому-что если будет дата рождения одинаковой, то People не добавится в коллеуцию, так как это Set и в элементы одинаковые не повторяются.
А так как они у нас фильтруются нашим компаратором, то одинаковыми они будут считаться если дыты рождение совпадают вплоть до миллисекунд.
В результате мы получим в консоли вывод содержимого нашего списка, которое будет отсортированно по дате рождения:
People { Name: Alex Barchuk; Age: 21; Birthday: Fri Dec 20 15:42:15 EET 2013 } People { Name: Jered Gogs; Age: 54; Birthday: Fri Dec 20 15:42:15 EET 2013 } People { Name: Mike Devidson; Age: 31; Birthday: Fri Dec 20 15:42:16 EET 2013 } People { Name: Steve Jobs; Age: 40; Birthday: Fri Dec 20 15:42:16 EET 2013 }
Как видите элементы вывелись не в том порядке в котором добавлялись, а в отсортированном по дате рождения. Дата рождения в мемент сортировки учитывалась вплоть до миллисекунд.
А теперь давайте протестироуем следующий компаратор, который сортирует по возврасту, для этого создадим класс и назовем его PeopleAgeComparatorTest:
package com.devcolibri.exam.comparator; import com.devcolibri.exam.pojo.People; import org.junit.Before; import org.junit.Test; import java.util.GregorianCalendar; import java.util.Set; import java.util.TreeSet; public class PeopleAgeComparatorTest { private Set<People> peoples; @Before public void setUp() throws Exception { // Инициализируем наш компаратор для сортировки по возврасту peoples = new TreeSet<People>(new PeopleAgeComparator()); } @Test public void testAddPeople() throws Exception { // Инициализируем всех People People people1 = new People("Alex Barchuk", 21, GregorianCalendar.getInstance().getTime()); People people2 = new People("Jered Gogs", 54, GregorianCalendar.getInstance().getTime()); People people3 = new People("Mike Devidson", 31, GregorianCalendar.getInstance().getTime()); People people4 = new People("Steve Jobs", 40, GregorianCalendar.getInstance().getTime()); // Добавялем элементы в коллекцию в любом порядке peoples.add(people1); peoples.add(people4); peoples.add(people3); peoples.add(people2); // Выводим элементы коллеуции for(People people : peoples){ System.out.println(people); } } }
И после выполнения данного теста мы увидим следующий результат:
People { Name: Alex Barchuk; Age: 21; Birthday: Fri Dec 20 15:48:56 EET 2013 } People { Name: Mike Devidson; Age: 31; Birthday: Fri Dec 20 15:48:56 EET 2013 } People { Name: Steve Jobs; Age: 40; Birthday: Fri Dec 20 15:48:56 EET 2013 } People { Name: Jered Gogs; Age: 54; Birthday: Fri Dec 20 15:48:56 EET 2013 }
Как видите сортировка прошла по возврасту от меньшего к большему.
p.s. Спасибо за внимание, надеюсь данный материал вам помог.
ПОХОЖИЕ ПУБЛИКАЦИИ
- None Found
4 комментариев к статье "Collection. Как создать отсортированную коллекцию?"
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.
Как сделать чтобы было отсортировано по возрасту и по каждому возрасту сортировка по дате?
Опечатка в первом предложении. Допустим у вас есть надор данных. Удалите потом коммит
А где тут мейн? Я не понял как это все дело запускается
Он запускал юнит тест, поэтому мейна нет. 4й шаг смотри