- PVSM.RU - https://www.pvsm.ru -
Часто Stream API в Java8 используется для работы с коллекциями, позволяя писать код в функциональном стиле.
Удобство и простота методов способствуют интересу к данному функционалу у разработчиков с момента его выхода.
Закончим с теоретической частью и перейдем к несложным примерам.
Пример показывает нахождение максимального и минимального значения из коллекции.
/**
* Пример № 1
* Нахождение максимального и минимального значений
*/
ArrayList<Integer> testValues = new ArrayList();
testValues.add(0,15);
testValues.add(1,1);
testValues.add(2,2);
testValues.add(3,100);
testValues.add(4,50);
Optional<Integer> maxValue = testValues.stream().max(Integer::compareTo);
System.out.println("MaxValue="+maxValue);
Optional<Integer> minValue = testValues.stream().min(Integer::compareTo);
System.out.println("MinValue="+minValue);
Немного усложним пример и добавим исключения (в виде null) при максимального значения в пример №2.
/**
* Пример № 2
* Нахождение максимального значения исключая null значения
*/
ArrayList<Integer> testValuesNull = new ArrayList();
testValuesNull.add(0,null);
testValuesNull.add(1,1);
testValuesNull.add(2,2);
testValuesNull.add(3,70);
testValuesNull.add(4,50);
Optional<Integer> maxValueNotNull = testValuesNull.stream().filter((p) -> p != null).max(Integer::compareTo);
System.out.println("maxValueNotNull="+maxValueNotNull);
Усложним примеры. Создадим коллекцию «спортивный лагерь», состоящую из полей «Имя» и «Количество дней в спортивном лагере». Сам пример создания класса ниже.
public class SportsCamp {
private String name; //Имя спортсмена
private Integer day; //Количество дней в спортивном лагере
public SportsCamp(String name, int day) {
this.name = name;
this.day = day;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDay() {
return day;
}
public void setDay(Integer day) {
this.day = day;
}
}
А теперь примеры работы с новыми данными:
import java.util.Arrays;
import java.util.Collection;
public class Start {
public static void main(String[] args) {
Collection<SportsCamp> sport = Arrays.asList(
new SportsCamp("Ivan", 5),
new SportsCamp("Petr", 7),
new SportsCamp("Ira", 10)
);
/**
* Пример 3
* Поиск имени самого большого по продолжительности нахождения в лагере
*/
String name = sport.stream().max((p1,p2) -> p1.getDay().compareTo(p2.getDay())).get().getName();
System.out.println("Name="+name);
}
}
В примере было найдено имя, Ирина, которая будет находиться в лагере всех дольше.
Преобразуем пример и создадим ситуацию, когда у нас вкралась ошибка, и одна из записей null в имени.
Collection<SportsCamp> sport = Arrays.asList(
new SportsCamp("Ivan", 5),
new SportsCamp( null, 15),
new SportsCamp("Petr", 7),
new SportsCamp("Ira", 10)
);
В этом случае вы получите результат, равный «Name=null».Согласитесь, что мы хотели не этого.Немного изменим поиск по коллекции на новый вариант.
/**
* Пример № 4
*/
String nameTest = sport.stream().filter((p) -> p.getName() != null).max((p1, p2) -> p1.getDay().compareTo(p2.getDay())).get().getName();
Полученный результат, «Ira» — верен.
В примерах показано нам нахождение минимальных и максимальных значений по коллекциям с небольшими дополнениями в виде исключения null значений.
Как мы говорили доступные методы можно разделить на две большие группы промежуточные операции и конечные. Авторы могут называть их различно, например, вариант названия конвейерные и терминальные методы употребляется в литературе и статьях. При работе с методами существует одна конструктивная особенность, вы можете «накидывать» множество промежуточных операций, в конце производя вызов одного терминального метода.
В новом примере добавим сортировку и вывод определенного элемента, например, добавим фильтр по именам с встречающимся «Ivan» и произведем подсчет таких элементов (исключим null значения).
/**
* Пример № 5
*/
long countName = sport.stream().filter((p) -> p.getName() != null && p.getName().equals("Ivan")).count();
System.out.println("countName="+countName);
Добавив в коллекцию new SportsCamp(«Ivan», 17), получим результат равный «countName=2». Нашли две записи.
В данных примерах использовалось создание стрима из коллекции, доступны и другие варианты, например, создание стрима из требуемых значений, например, Stream streamFromValues = Stream.of(«test1», «test2», «test3»), возможны и другие варианты.
Как говорилось выше, у пользователей есть возможность использовать «обработку» используя parallelStream().
Немного изменив пример, получим новый вариант реализации:
long countNameParallel = sport.parallelStream().filter((p) -> p.getName() != null && p.getName().equals("Ivan")).count();
System.out.println("countNameParallel=" + countNameParallel);
Особенность этого варианта состоит в реализации параллельного стрима. Хочется обратить внимание, что parallelStream() оправданно использовать на мощных серверах(многоядерных) для больших коллекций. Я не даю четкого определения и точного размера коллекций, т.к. очень много параметров необходимо выявить и просчитать. Часто только тестирование может показать вам увеличение производительность.
List<SportsCamp> onlyI = sport.stream().filter(p -> p.getName() != null && p.getName().startsWith("I")).collect(Collectors.toList());
System.out.println("SIZE="+onlyI.size());
Результат будет равен трём. Тут нужно обратить внимание, что порядок указания исключения null элементов значим.
Обратите внимание, что Collectors обладает массой возможностей, включая вывод среднего значения или информации со статистикой. Как пример, попробуем соединить данные, вот так:
String campPeople = sport.stream().filter(p -> p.getName() != null).map(SportsCamp::getName).collect(Collectors.joining(" and ","In camp "," rest all days."));
System.out.println(campPeople);
Integer daySum = sport.stream().reduce(0, (sum, p) -> sum += p.getDay(), (sum1, sum2) -> sum1 + sum2);
System.out.println("DaySize=" + daySum);
Автор: Terran37
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/java/128384
Ссылки в тексте:
[1] описание с сайта: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#package.description
[2] «Java 8 в параллель. Учимся создавать подзадачи и контролировать их выполнение».: https://habrahabr.ru/post/272479/
[3] документацию: http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
[4] Источник: https://habrahabr.ru/post/302628/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.