У меня возникают проблемы понимания Stream
интерфейса в Java 8, особенно там , где он должен делать с Spliterator
и Collector
интерфейсов. Моя проблема в том, что я пока просто не могу понять Spliterator
и Collector
интерфейсы, и в результате Stream
интерфейс для меня все еще несколько неясен.
Что такое «а» Spliterator
и «а» Collector
и как их использовать? Если я хочу написать свое собственное Spliterator
или Collector
(и, возможно, свое собственное Stream
в этом процессе), что мне делать и не делать?
Я прочитал несколько примеров, разбросанных по сети, но поскольку здесь все еще новое и может быть изменено, примеров и руководств по-прежнему очень мало.
источник
Collectors.of
старый метод бета - версии , которая была удалена или я-то отсутствует? Для полноты(x,y) -> x+y
картины можно записать какInteger::sum
.Spliterator
в основном означает «разделяемый итератор».Одиночный поток может проходить / обрабатывать весь Spliterator сам, но Spliterator также имеет метод,
trySplit()
который « отделяет » раздел для обработки другим (обычно другим потоком), оставляя текущий разделитель с меньшими затратами.Collector
объединяет спецификациюreduce
функции (известности, уменьшающей карту), с начальным значением и функцией для объединения двух результатов (что позволяет объединить результаты из разделенных потоков работы).Например, самый простой Collector будет иметь начальное значение 0, добавлять целое число к существующему результату и «объединять» два результата, добавляя их. Таким образом суммируется разделенный поток целых чисел.
Увидеть:
Spliterator.trySplit()
Collector<T,A,R>
источник
Ниже приведены примеры использования предопределенных коллекторов для выполнения общих задач изменяемого сокращения:
// Accumulate names into a List List<String> list = people.stream().map(Person::getName).collect(Collectors.toList()); // Accumulate names into a TreeSet Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new)); // Convert elements to strings and concatenate them, separated by commas String joined = things.stream() .map(Object::toString) .collect(Collectors.joining(", ")); // Compute sum of salaries of employee int total = employees.stream() .collect(Collectors.summingInt(Employee::getSalary))); // Group employees by department Map<Department, List<Employee>> byDept = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment)); // Compute sum of salaries by department Map<Department, Integer> totalByDept = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.summingInt(Employee::getSalary))); // Partition students into passing and failing Map<Boolean, List<Student>> passingFailing = students.stream() .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
источник
Интерфейс
Spliterator
- это ключевая особенность Streams .В интерфейсе представлены методы
stream()
и поparallelStream()
умолчаниюCollection
. Эти методы используют Spliterator через вызовspliterator()
:... default Stream<E> stream() { return StreamSupport.stream(spliterator(), false); } default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true); } ...
Spliterator - это внутренний итератор, который разбивает поток на более мелкие части. Эти более мелкие детали можно обрабатывать параллельно.
Среди других методов есть два наиболее важных для понимания Spliterator:
boolean tryAdvance(Consumer<? super T> action)
В отличие отIterator
, он пытается выполнить операцию со следующим элементом. Если операция выполнена успешно, метод возвращаетсяtrue
. В противном случае возвращаетсяfalse
- это означает отсутствие элемента или конца потока.Spliterator<T> trySplit()
Этот метод позволяет разбить набор данных на множество меньших наборов по тем или иным критериям (размер файла, количество строк и т. Д.).источник