Выпуск Java 8 в марте 2014 года привел к ряду существенных изменений в мире java, и среди наиболее важных – Потоки
и функциональное программирование.
Новые версии java усилили его использование, добавив довольно полезные новые функции.
Итак, сегодня мы превратим код Java 7 и более ранних версий в Java 8 +, используя программирование в функциональном стиле.
1- Сортировка списка домашних животных в неестественном порядке.
Предыдущая java 8
Listpets = new ArrayList<>(); pets.add(new Pet("Scoby", 10)); pets.add(new Pet("Jahnna", 12)); pets.add(new Pet("Kira", 15)); pets.add(new Pet("Snoopy", 2)); pets.add(new Pet("Jeck" ,7)); Collections.sort(pets, new Comparator<>() { @Override public int compare(Pet pet1, Pet pet2) { return (int) (pet1.getWeight() - pet2.getWeight()); } }); for(Pet pet : pets) { System.out.println(pet.getName()); }
Используя Лямбда- и потоковый подход.
Listpets = new ArrayList<>(); pets.add(new Pet("Scoby", 10)); pets.add(new Pet("Jahnna", 12)); pets.add(new Pet("Kira", 15)); pets.add(new Pet("Snoopy", 2)); pets.add(new Pet("Jeck" ,7)); pets.stream() .sorted((p1, p2) -> (int) (p1.getWeight() - p2.getWeight())) .forEach(Pet::getName);
В первом примере нам пришлось предоставить анонимный класс, который расширяется от Comparator
и переопределяет абстрактное поведение. Затем передайте его в качестве параметра в Коллекции.метод сортировки
, потому что класс Pet не реализует Сопоставимый
интерфейс.
Используя Java 8+, давайте создадим более описательный код, который выражает “что” независимо от того, как.
2- Превратите наших милых питомцев в диких животных.
Java 7 или более ранняя версия.
// pets List Listwild = new ArrayList<>(); for(Pet p : pets) { WildAnimal animal = new WildAnimal(p.getName(), p.getWeight() * 2); wild.add(animal); animal.hunt(); }
Использование функций Java 8.
// pets List pets.stream() .map(e -> new WildAnimal(e.getName(), e.getWeight() * 2)) .forEach(WildAnimal::hunt);
Теперь мы используем метод map()
для преобразования одного типа в другой, в этом случае ваши крошечные питомцы теперь безжалостные дикие животные, и в конце для каждого из них мы вызываем hunt()
.
До сих пор наши 2 первых примера были слишком простыми, давайте рассмотрим еще несколько интересных примеров.
3- Рассчитать статистику по кандидатам на работу
Возможно, вы работаете дома из-за карантина (или раньше работали удаленно), и вас попросили рассчитать некоторые статистические данные и бесчисленный список претендентов на работу. принимаются только те, кто соответствует квалификационным критериям и их возраст составляет от 20 до 35 лет (просто пример, мы не хотим быть такими исключительными). чтобы создать некоторую бизнес-логику.
Давайте посмотрим, как мы можем это сделать, используя старый способ.
// applicants list ... int count = 0; int totalQualification = 0; double avgQualification; for (Applicant applicant : applicants) { if ((applicant.getAge() > 19 && applicant.getAge() < 36) && applicant.getInterviewQualification() > 69) { count++; totalQualification += applicant.getInterviewQualification(); } } avgQualification = count != 0 ? totalQualification / count : 0; System.out.format("Qualification stats {count=%d, total=%d, avg=%f}", count, totalQualification, avgQualification);
Что ж, неплохо, но мы можем добиться большего, используя java 9+
// applicants list ... var stats = applicants.stream() .filter(a -> a.getAge() > 19 && a.getAge() < 36) .filter(a -> a.getInterviewQualification() > 6) .mapToInt(Applicant::getInterviewQualification) .summaryStatistics(); System.out.format("Qualification stats {count=%d, total=%d, avg=%f}", stats.getCount(), stats.getSum(), stats.getAverage());
Примечание: Как мы цепляем операции, как если бы это был конвейер, потому что на самом деле это конвейер.
4 – Группируйте кандидатов по должности, на которую они претендовали.
До
Map> group = new HashMap<>(); for(Applicant ap: applicants) { List list = group.get(ap.getPosition()); if(list == null){ list = new ArrayList<>(); group.put(ap.getPosition(), list); } list.add(ap); } System.out.println(group);
После
Map> group = applicants .stream() .collect(Collectors.groupingBy(Applicant::getPosition)); System.out.println(group);
Код выглядит намного понятнее во втором примере, в этом случае мы используем коллектор groupingBy
, который принимает функцию в качестве параметра в данном случае Функция <Заявитель>
. Ссылка на метод позволяет нам запускать метод GetPosition
от текущего передаваемого кандидата и использовать возвращаемое значение в качестве группы.
В нашем последнем примере мы будем использовать даты.
5 – Группировка статистических данных за последние 7 дней о COVID-19
поскольку вам скучно и вы хотите создать другое приложение для визуализации статистики коронавируса, возможно, этот пример может помочь.
Используя старый способ
ListlastWeek = new ArrayList<>(); Calendar calendar = GregorianCalendar.getInstance(); calendar.setTime(new Date()); for(int i = 0; i < 7; i++) { Date current = calendar.getTime(); lastWeek.add(covid19DataSource.getSummaryByDate(current)); calendar.add(Calendar.DAY_OF_MONTH, -1); } System.out.println(lastWeek);
Использование Java 9+
LocalDate today = LocalDate.now().plusDays(1); ListlastWeek = today.minusDays(7).datesUntil(today, Period.ofDays(1)) .map(covid19DataSource::getSummaryByDate) .collect(Collectors.toList()); System.out.println(lastWeek);
Здесь мы не только используем lambda и Stream, но также используем более новый Java time API. Даты До тех пор, пока метод
не был добавлен в Java 9, позволяют нам получать поток LocalDate
объекты, которые мы сопоставляем, чтобы получить соответствующую сводку covid 19, а затем просто собрать ее в список.
[Summary{confirmed=0, recovered=0, deaths=0, date=2020-04-17}, ...
Оба подхода возвращают один и тот же результат, было бы здорово получить одни и те же показатели в реальной жизни.:D
Спасибо за чтение, берегите себя:).
Оригинал: “https://dev.to/jmorla/5-ways-to-boost-up-your-code-using-functional-programming-style-in-java-f32”