|
||||||||||||||||||
groupingBy
Время создания: 14.11.2020 18:16
Раздел: INFO - Development - JAVA - Collection - Stream
Запись: wwwlir/Tetra/master/base/1605348975btue9a2pzy/text.html на raw.githubusercontent.com
|
||||||||||||||||||
|
||||||||||||||||||
Java 8 Stream reduce Сентябрь 2, 2017 Vertex Academy filter ,Java ,java 8 stream reduce ,Java8 ,mapreduce ,method reference ,reduce ,Stream ,stream reduce Данная статья написана командой Vertex Academy . Это одна из статей из нашего Учебника по Java 8. Надеемся, что данная статья Вам будет полезна. Приятного прочтения! В этой статье мы рассмотрим сбор данных с помощью Stream-ов в Java. 1. Введение Stream API - новый способ взаимодействия с данными, представляя их в виде конечного потока данных. С помощью Stream API в Java 8 стало возможно использование стратегии mapReduce С ней мы сегодня и научимся работать. 2. Sum reduce Посчитаем сумму чисел в списке Java public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 5); Optional<Integer> sum = numbers.stream() .reduce((left, right) -> left + right); sum.ifPresent(System.out::println); //output 11 }
Метод reduce принимает лямбда-выражение известное как аккумулятор (Accumulator), которое служит для сворачивания данных в одну "кучу". А тепер посчитаем сумму начиная с 10 Java public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 5); Integer sum = numbers.stream() .reduce(10, (left, right) -> left + right); System.out.println(sum); //output 11 }
Перегруженный метод reduce принимает начальное значение (identity) и аккумулятор. В первом случае результат метода reduce вернул Optional<Integer> т.к. мы не указывали начальное значение. Во втором случае мы указали начальное значение, и метод reduce уже возвращает обычный Integer. Попоробуем более сложное выражение Java public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3); // 1*10 + 2*10 + 3*10 Integer sum = numbers.stream() .reduce(10, (identity, val) -> identity * val, (left, right) -> left + right); System.out.println(sum); //output 60 } В данном случае метод reduce принимает три параметра - identity, accumulator, combiner. Где accumulator умножает каждое значение из Stream-a на начальное значение (identity) а combiner собирает результат работы accumulator. Выходит что наш Stream преобразовывается из 1, 2, 3 в 10, 20, 30 а послее просто суммируется. 3. Search reduce 3.1 Search min value С помощью map reduce можно так же производить поиск Найдем наименьшее число в массиве Java public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 7); Integer min = numbers.stream() .reduce(Integer.MAX_VALUE, (left, right) -> left < right ? left : right); System.out.println(min); //output 1 } В данном примере мы указали начальное значение и аккумулятор который и оставляет меньшее значение. Так же пример можно улучшить с помощью ссылки на метод min в Integer Java public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 5, 7); Integer min = numbers.stream() .reduce(Integer.MAX_VALUE, Integer::min); System.out.println(min); //output }
3.2 Search longest string Попробуем найти самую длинную строку Java public static void main(String[] args) { List<String> strings = Arrays.asList("aaa", "bbb", "ccc", "ddd", "ffff"); String s = strings.stream() .reduce("", (left, right) -> left.length() > right.length() ? left : right); System.out.println(s); //output ffff } 3.3 Complex search Создадим класс Connection class Connection { private String from; private String to; // constructors, getters }
а так же список всех связей, создав таким образом сеть Java List<Connection> network = Arrays.asList(new Connection("A", "B"), new Connection("A", "C"), new Connection("A", "D"), new Connection("B", "C") );
А теперь попробуем найти все связи, которые знает узел "A" с помощью mapReduce + filter Для этого нам понадобится создать наш identity Java List<String> identity = new ArrayList<>();
а так же accumulator Java BiFunction<List<String>, Connection, List<String>> accumulator = (strings, connection) -> { strings.add(connection.getTo()); return strings; };
где мы просто добавляем наши входящие узлы в список (identity) и возвращаем его. И combiner Java BinaryOperator<List<String>> combiner = (strings, strings2) -> { strings.addAll(strings2); return strings; };
который соединяет два списка узлов в один. А теперь используем все компоненты Java List<String> list = network.stream() .filter(p -> "A".equals(p.getFrom())) .reduce(identity, accumulator, combiner); System.out.println(list); //output [B, C, D]
Таким образом мы получили список узлов, которые знает узел "А" Полный код примера Java public static void main(String[] args) { List<Connection> network = Arrays.asList(new Connection("A", "B"), new Connection("A", "C"), new Connection("A", "D"), new Connection("B", "C") ); List<String> identity = new ArrayList<>(); BiFunction<List<String>, Connection, List<String>> accumulator = (strings, connection) -> { strings.add(connection.getTo()); return strings; }; BinaryOperator<List<String>> combiner = (strings, strings2) -> { strings.addAll(strings2); return strings; }; List<String> list = network.stream() .filter(p -> "A".equals(p.getFrom())) .reduce(identity, accumulator, combiner); System.out.println(list); //output [B, C, D] } |
||||||||||||||||||
Так же в этом разделе:
|
||||||||||||||||||
|
||||||||||||||||||
|