Последнее появление … Я написал пост, связанный с новыми угощениями, которые JDK8 предлагает для нас. Скорее всего, особенность, которая меня больше всего волнует — это лямбды. Я должен признать, что в течение моего первого года, когда я был блудным человеком (в течение которого я разрабатывал с использованием C #), я любил LINQ и красивые, элегантные вещи, которые вы можете делать с ним. Теперь, даже если стирание все еще находится в том же месте, где мы его оставили в прошлый раз, теперь у нас есть лучший способ фильтровать, изменять, просматривать коллекции и помимо синтаксического сахара, это также может заставить вас правильно использовать четырехъядерный процессор что ты хвастался своим друзьям. И говоря о друзьях, этот пост представляет собой список терминов, связанных с лямбдами и потоковой обработкой, которые вы можете бросить своим друзьям, когда они спросят вас: «Что это за <место термина из JDK 8, связанное с лямбдами>?». Я не намерен иметь полный список или руководство по лямбде, если я сказал что-то не так или я что-то пропустил, пожалуйста, дайте мне знать …
Функциональный интерфейс:
Согласно [jls 8], функциональный интерфейс — это интерфейс, который имеет только один абстрактный метод и, таким образом, представляет один контракт функции (в некоторых случаях этот «единственный» метод может принимать форму нескольких абстрактных методов с переопределенными эквивалентными сигнатурами ( [jls7_8.4.2]) унаследовано от суперинтерфейсов, в этом случае унаследованные методы логически представляют один метод).
@FunctionalInterface
— используется для указания того, что интерфейс должен быть функциональным интерфейсом. Если аннотация размещается на интерфейсе, которого на самом деле нет, возникает ошибка времени компиляции.
Пример:
1
|
interface Runnable { void run(); } |
Интерфейс Runnable
является очень подходящим примером, поскольку единственный присутствующий метод — это метод run . Другим «классическим» примером функционального интерфейса Java является интерфейс Comparator <T> , в следующем примере — ранее упомянутый интерфейс и метод equals, унаследованный от Object , интерфейс по-прежнему функционален, поскольку метод сравнения является единственным абстрактным методом, в то время как Равные унаследованы от суперкласса.
1
2
3
4
5
6
|
interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2); } |
Ручей
поток — согласно [оксфордскому словарю], в вычислениях это непрерывный поток данных или инструкций, обычно с постоянной или предсказуемой скоростью.
Начиная с JDK 8 поток представляет собой механизм, используемый для передачи элементов из источника данных через вычислительный конвейер. Поток может использовать в качестве источников данных массивы, коллекции, функции генератора, каналы ввода / вывода.
Получение потоков:
- Из
Collection
помощью методовstream()
и / илиparallelStream()
; - Из массива через
Arrays.stream(Object[])
- Из статических методов фабрики для потоковых классов, таких как
Stream.of(Object[])
,IntStream.range(int, int)
илиStream.iterate(Object, UnaryOperator)
; - Строки файла могут быть получены из
BufferedReader.lines();
- Потоки путей к файлам могут быть получены из методов в файлах;
- Потоки случайных чисел можно получить из
Random.ints();
- Множество других потоковых методов в JDK,
including BitSet.stream()
,Pattern.splitAsStream(java.lang.CharSequence)
иJarFile.stream()
.
потоковые операции — действия, выполняемые в потоке. С точки зрения управления потоком существует два типа действий: промежуточные и терминальные операции.
Промежуточная операция потока — операции, сужающие содержимое потока. Промежуточные операции по своей природе ленивы — фактически не изменяют содержимое потока, но создают другой более узкий поток. Обход потока начинается только тогда, когда вызывается операция терминала.
- фильтр — фильтрует поток на основе предоставленного предиката
- map — создает новый поток, применяя функцию отображения к каждому элементу из исходного потока (соответствующие методы для каждого числового типа: int, long, double)
- flatMap — операция, которая приводит к применению преобразования «один ко многим» к элементам потока, а затем сглаживает элементы результатов в новый поток. Например, если заказы представляют собой поток заказов на покупку, и каждый заказ на покупку содержит коллекцию отдельных позиций, то следующее создает поток отдельных позиций:
1
|
orderStream.flatMap(order -> order.getLineItems().stream()) |
- Отличный — возвращает поток отдельных операций
- sorted — возвращает поток отсортированных операций
- peek — ориентированный на отладку метод, который возвращает поток, состоящий из элементов этого потока, при этом предусмотренное действие выполняется для каждого элемента
Пример:
01
02
03
04
05
06
07
08
09
10
11
12
|
list.stream() .filter(filteringFunction) .peek(e -> {System.out.println( "Filtered value: " + e); }); .map(mappingFunction) .peek(e -> {System.out.println( "Mapped value: " + e); }); .collect(Collectors.intoList()); |
- limit — возвращает усеченную версию текущего потока (не более, чем предельное количество элементов)
- substream — возвращает поток, состоящий из оставшегося элемента, начиная с начальной позиции или между startPosition и endPosition
операция потокового терминала — прохождение потока для получения результата или побочного эффекта. После выполнения операции терминала поток считается использованным (вызов другой операции для потребленного потока вызовет IllegalStateException
). Операции с терминалами носят нетерпеливый характер, за исключением iterator()
и splititerator()
которые предоставляют механизм расширения для тех, кто не находит нужную функцию в API.
- forEach — применяет предоставленную операцию к каждому элементу потока. Также существует версия forEachOrdered
- toArray — извлекает элементы потока в массив
- уменьшить — метод уменьшения
- собирать — изменчивый метод сокращения
- min — вычисляет минимум потока
- max — вычисляет максимум потока
- count — считает элементы потока
- anyMatch — возвращает true, если есть элемент, соответствующий заданным критериям
- allMatch — возвращает true, если все элементы совпадают
- noneMatch — возвращает true, если ни один из элементов не совпадает
- findFirst — находит первый элемент, который соответствует предоставленному условию
- findAny — возвращает элемент из потока
потоковый конвейер : состоит из источника, за которым следует ноль или более промежуточных операций и операция терминала.
Spliterator — Spliterator для прохождения и разделения элементов источника. Можно использовать его для обхода, оценки количества элементов или разбить его на несколько разделителей
Сокращение — операция сокращения (или сложение) берет последовательность входных элементов и объединяет их в единый итоговый результат путем многократного применения операции объединения. Операцией сокращения может быть вычисление суммы, максимума, минимума, подсчета или сбор элементов в списке. Операция сокращения также распараллеливается, если используемые функции являются ассоциативными и не имеют состояния. Метод, используемый для сокращения, является reduce()
Пример: уменьшение с использованием суммы:
1
|
int sum = numbers.stream().reduce( 0 , (x,y) -> x + y); |
или же
1
|
int sum = numbers.stream().reduce( 0 , Integer::sum); |
Изменяемое сокращение — это операция, которая накапливает входные элементы в изменяемый контейнер результатов (StringBuilder или Collection) при обработке элементов в потоке.
Пример:
1
|
String concatenated = strings.reduce( "" , String::concat) |
Предикат — функциональный интерфейс, который определяет, соответствует ли входной объект некоторым критериям
Я надеюсь, что вы найдете этот сокращенный список полезным и сохраните его в своих закладках в те моменты, когда вам нужны все эти термины на одной странице.
Если вы нашли что-то, чего не хватает, пожалуйста, дайте мне знать, чтобы я мог это исправить.
Итак … я желаю вам хорошего времени пришествия и счастливого / веселого / веселого, но самое главное, я желаю вам мирного Рождества!