Stream
Java 8 의 인터페이스, 특히 Spliterator
and Collector
인터페이스 와 관련된 인터페이스를 이해하는 데 문제 가 있습니다. 내 문제는 내가 간단하게 이해할 수 있다는 것입니다 Spliterator
및 Collector
인터페이스를 아직 그 결과, Stream
인터페이스는 여전히 다소 나에게 모호하게됩니다.
정확히 a Spliterator
와 a 는 무엇 Collector
이며 어떻게 사용합니까? 내가 직접 ( Spliterator
또는 Collector
아마도 Stream
그 과정에서 내 자신 을) 기꺼이 쓰려면 어떻게해야합니까?
나는 웹에 흩어져있는 몇 가지 예를 읽었지만 여기의 모든 것이 여전히 새롭고 변경 될 수 있으므로 예제와 자습서는 여전히 매우 드 r니다.
답변
거의 확실하게 Spliterator
사용자 를 다루지 않아도됩니다 . 당신이있는 거 쓰는 경우에만 필요합니다 Collection
종류의 자신을하고 또한 최적화하려는 그들에 대한 작업을 병렬화.
가치있는 Spliterator
것은 a는 컬렉션의 일부를 쉽게 분리 할 수있는 방법으로 컬렉션의 요소를 조작하는 방법입니다. 하나의 스레드가 다른 부분에서 작동하는 등
본질적으로 유형의 값을 Stream
변수에 저장해서는 안됩니다 . Javadoc 예제에서와 같이 거의 항상 유동 체인에서 사용할 일회용 객체이기 때문에 Stream
일종의입니다 Iterator
.
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
Collector
“축소”연산의 가장 일반적이고 추상적 인 버전은 la map / reduce입니다. 특히, 병렬화 및 마무리 단계를 지원해야합니다. 의 예는 Collector
다음과 같습니다.
- 합산, 예.
Collectors.reducing(0, (x, y) -> x + y)
- StringBuilder 추가, 예 :
Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString)
답변
Spliterator
기본적으로 “분할 가능한 반복자”를 의미합니다.
단일 스레드는 전체 Spliterator 자체를 통과 / 처리 할 수 있지만 Spliterator에는 trySplit()
다른 사람 (일반적으로 다른 스레드)이 처리 할 섹션을 “분할” 하는 방법 이있어 현재의 Spliterator가 적은 작업으로 남겨집니다.
Collector
reduce
함수 (map-reduce 명성) 의 사양 과 초기 값을 결합하고 두 결과를 결합하는 함수 (따라서 분할 된 작업 스트림의 결과를 결합 할 수 있도록 함)를 결합합니다.
예를 들어, 가장 기본적인 수집기는 초기 값이 0이고 기존 결과에 정수를 추가 한 다음 두 결과를 더하여 ‘결합’합니다. 따라서 분할 된 정수 스트림을 합산하십시오.
보다:
답변
다음은 사전 정의 된 콜렉터를 사용하여 일반적인 변경 가능한 축소 작업을 수행하는 예입니다.
// 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
– 스트림 의 핵심 기능입니다 .
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()
이 방법을 사용하면 데이터 세트를 하나 이상의 기준 (파일 크기, 행 수 등)에 따라 여러 개의 작은 세트로 분할 할 수 있습니다.