Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 알고리즘
- spring boot
- Elasticsearch
- Baekjoon
- Spring
- 코드
- framework
- Java
- 엘라스틱서치
- 백준
- 그리디알고리즘
- API
- 애자일기법
- 클린코드
- 자바
- 개발
- cleancode
- 프레임워크
- 그리디
- 애자일프로그래밍
- database
- 코딩
- 코딩테스트
- 애자일
- ES
- 읽기쉬운코드
- JPA
- 스프링
- 개발자
- 데이터베이스
Archives
- Today
- Total
튼튼발자 개발 성장기🏋️
STREAM 활용 본문
반응형
1. Stream을 활용한 최대값, 최소값, 개수 추출하기
/**
* Returns the minimum element of this stream according to the provided
* {@code Comparator}. This is a special case of a
* <a href="package-summary.html#Reduction">reduction</a>.
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
*
* @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* {@code Comparator} to compare elements of this stream
* @return an {@code Optional} describing the minimum element of this stream,
* or an empty {@code Optional} if the stream is empty
* @throws NullPointerException if the minimum element is null
*/
Optional<T> min(Comparator<? super T> comparator);
/**
* Returns the maximum element of this stream according to the provided
* {@code Comparator}. This is a special case of a
* <a href="package-summary.html#Reduction">reduction</a>.
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
* @param comparator a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* {@code Comparator} to compare elements of this stream
* @return an {@code Optional} describing the maximum element of this stream,
* or an empty {@code Optional} if the stream is empty
* @throws NullPointerException if the maximum element is null
*/
Optional<T> max(Comparator<? super T> comparator);
/**
* Returns the count of elements in this stream. This is a special case of
* a <a href="package-summary.html#Reduction">reduction</a> and is
* equivalent to:
* <pre>{@code
* return mapToLong(e -> 1L).sum();
* }</pre>
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
*
* @return the count of elements in this stream
*/
long count();
- Stream에 담겨있는 데이터 중 최대값을 리턴하는 max (Stream이 empty면 empty인 Optional 리턴)
- Stream에 담겨있는 데이터 중 최소값을 리턴하는 min (Stream이 empty면 empty인 Optional 리턴)
- Stream에 담겨 있는 데이터의 수를 리턴하는 count
예제를 살펴보자.
int max = Stream.of(1, 2, 3, -5, 0).max(Integer::compareTo).get();
System.out.println(max); // 3
User user1 = User.builder()
.id(1)
.name("아이언맨")
.email("ironMan@aaa.co.kr")
.isVerified(true)
.build();
User user2 = User.builder()
.id(2)
.name("캡틴")
.email("captain@aaa.co.kr")
.isVerified(false)
.build();
User user3 = User.builder()
.id(3)
.name("토르")
.email("thor@aaa.co.kr")
.isVerified(false)
.build();
List<User> users = Arrays.asList(user1, user2, user3);
User firstUser = users.stream()
.min((u1, u2) -> u1.getName().compareTo(u2.getName()))
.get();
System.out.println(firstUser); // User(id=1, name=아이언맨, email=ironMan@aaa.co.kr, isVerified=true)
long count = Stream.of(1, 2, -1, 0)
.filter(x -> x >= 0)
.count();
System.out.println(count); // 3
2. Stream을 활용한 조건 만족 check
/**
* Returns whether any elements of this stream match the provided
* predicate. May not evaluate the predicate on all elements if not
* necessary for determining the result. If the stream is empty then
* {@code false} is returned and the predicate is not evaluated.
*
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>.
*
* @apiNote
* This method evaluates the <em>existential quantification</em> of the
* predicate over the elements of the stream (for some x P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if any elements of the stream match the provided
* predicate, otherwise {@code false}
*/
boolean anyMatch(Predicate<? super T> predicate);
/**
* Returns whether all elements of this stream match the provided predicate.
* May not evaluate the predicate on all elements if not necessary for
* determining the result. If the stream is empty then {@code true} is
* returned and the predicate is not evaluated.
*
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>.
*
* @apiNote
* This method evaluates the <em>universal quantification</em> of the
* predicate over the elements of the stream (for all x P(x)). If the
* stream is empty, the quantification is said to be <em>vacuously
* satisfied</em> and is always {@code true} (regardless of P(x)).
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to elements of this stream
* @return {@code true} if either all elements of the stream match the
* provided predicate or the stream is empty, otherwise {@code false}
*/
boolean allMatch(Predicate<? super T> predicate);
- Stream에 담겨있는 데이터가 predicate를 만족하면 true를 리턴하는 allMatch
- Stream에 담겨있는 데이터중 하나라도 predicate를 만족하면 true를 리턴하는 anyMatch
예제를 살펴보자.
List<Integer> numbers = Arrays.asList(1, 2, 3, 0, -5);
boolean allPostive = numbers.stream()
.allMatch(n -> n > 0);
System.out.println(allPostive); // false
boolean anyPostive = numbers.stream()
.anyMatch(n -> n < 0);
System.out.println(anyPostive); // true
anyPostive = numbers.stream()
.anyMatch(n -> n == -5);
System.out.println(anyPostive); // true
3. Stream을 활용한 데이터 리턴
/**
* Returns an {@link Optional} describing the first element of this stream,
* or an empty {@code Optional} if the stream is empty. If the stream has
* no encounter order, then any element may be returned.
*
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>.
*
* @return an {@code Optional} describing the first element of this stream,
* or an empty {@code Optional} if the stream is empty
* @throws NullPointerException if the element selected is null
*/
Optional<T> findFirst();
/**
* Returns an {@link Optional} describing some element of the stream, or an
* empty {@code Optional} if the stream is empty.
*
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
* terminal operation</a>.
*
* <p>The behavior of this operation is explicitly nondeterministic; it is
* free to select any element in the stream. This is to allow for maximal
* performance in parallel operations; the cost is that multiple invocations
* on the same source may not return the same result. (If a stable result
* is desired, use {@link #findFirst()} instead.)
*
* @return an {@code Optional} describing some element of this stream, or an
* empty {@code Optional} if the stream is empty
* @throws NullPointerException if the element selected is null
* @see #findFirst()
*/
Optional<T> findAny();
- Stream에 담겨있는 데이터 중, 첫 번째 데이터 리턴하는 findFirst (Stream이 empty면 empty인 Optional 리턴)
- Stream에 담겨있는 데이터 중, 랜덤으로 데이터 리턴하는 findAny (Stream이 empty면 empty인 Optional 리턴)
예제를 살펴보자.
List<Integer> numbers = Arrays.asList(2, 9, 3, 0, -5);
int first = numbers.stream()
.findFirst()
.get();
System.out.println(first); // 2
int any = numbers.stream()
.findAny()
.get();
System.out.println(any); // ?
4. Stream에 담긴 데이터를 하나의 값으로 계속 함수를 수행
/**
* Performs a <a href="package-summary.html#Reduction">reduction</a> on the
* elements of this stream, using the provided identity value and an
* <a href="package-summary.html#Associativity">associative</a>
* accumulation function, and returns the reduced value. This is equivalent
* to:
* <pre>{@code
* T result = identity;
* for (T element : this stream)
* result = accumulator.apply(result, element)
* return result;
* }</pre>
*
* but is not constrained to execute sequentially.
*
* <p>The {@code identity} value must be an identity for the accumulator
* function. This means that for all {@code t},
* {@code accumulator.apply(identity, t)} is equal to {@code t}.
* The {@code accumulator} function must be an
* <a href="package-summary.html#Associativity">associative</a> function.
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
* @apiNote Sum, min, max, average, and string concatenation are all special
* cases of reduction. Summing a stream of numbers can be expressed as:
*
* <pre>{@code
* Integer sum = integers.reduce(0, (a, b) -> a+b);
* }</pre>
*
* or:
*
* <pre>{@code
* Integer sum = integers.reduce(0, Integer::sum);
* }</pre>
*
* <p>While this may seem a more roundabout way to perform an aggregation
* compared to simply mutating a running total in a loop, reduction
* operations parallelize more gracefully, without needing additional
* synchronization and with greatly reduced risk of data races.
*
* @param identity the identity value for the accumulating function
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return the result of the reduction
*/
T reduce(T identity, BinaryOperator<T> accumulator);
/**
* Performs a <a href="package-summary.html#Reduction">reduction</a> on the
* elements of this stream, using an
* <a href="package-summary.html#Associativity">associative</a> accumulation
* function, and returns an {@code Optional} describing the reduced value,
* if any. This is equivalent to:
* <pre>{@code
* boolean foundAny = false;
* T result = null;
* for (T element : this stream) {
* if (!foundAny) {
* foundAny = true;
* result = element;
* }
* else
* result = accumulator.apply(result, element);
* }
* return foundAny ? Optional.of(result) : Optional.empty();
* }</pre>
*
* but is not constrained to execute sequentially.
*
* <p>The {@code accumulator} function must be an
* <a href="package-summary.html#Associativity">associative</a> function.
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values
* @return an {@link Optional} describing the result of the reduction
* @throws NullPointerException if the result of the reduction is null
* @see #reduce(Object, BinaryOperator)
* @see #min(Comparator)
* @see #max(Comparator)
*/
Optional<T> reduce(BinaryOperator<T> accumulator);
/**
* Performs a <a href="package-summary.html#Reduction">reduction</a> on the
* elements of this stream, using the provided identity, accumulation and
* combining functions. This is equivalent to:
* <pre>{@code
* U result = identity;
* for (T element : this stream)
* result = accumulator.apply(result, element)
* return result;
* }</pre>
*
* but is not constrained to execute sequentially.
*
* <p>The {@code identity} value must be an identity for the combiner
* function. This means that for all {@code u}, {@code combiner(identity, u)}
* is equal to {@code u}. Additionally, the {@code combiner} function
* must be compatible with the {@code accumulator} function; for all
* {@code u} and {@code t}, the following must hold:
* <pre>{@code
* combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
* }</pre>
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
* @apiNote Many reductions using this form can be represented more simply
* by an explicit combination of {@code map} and {@code reduce} operations.
* The {@code accumulator} function acts as a fused mapper and accumulator,
* which can sometimes be more efficient than separate mapping and reduction,
* such as when knowing the previously reduced value allows you to avoid
* some computation.
*
* @param <U> The type of the result
* @param identity the identity value for the combiner function
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function for incorporating an additional element into a result
* @param combiner an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values, which must be
* compatible with the accumulator function
* @return the result of the reduction
* @see #reduce(BinaryOperator)
* @see #reduce(Object, BinaryOperator)
*/
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
reduce는 3가지로 오버로딩되어있다.
- accumulator를 이용해 데이터를 합쳐 Optional을 리턴하는 reduce
- 초기값과 accumulator를 이용하여 함쳐 제너럴 타입을 리턴하는 reduce
- 합치는 과정에서 타입이 바뀔 경우 사용하는 reduce
예제로 살펴보자.
List<Integer> numbers = Arrays.asList(2, 9, 3, -9);
int sum = numbers.stream()
.reduce((x, y) -> x + y)
.get();
System.out.println(sum); // 5
// max, min, count도 reduce의 일종이라는 것을 알 수 있다.
int max = numbers.stream()
.reduce((x, y) -> x > y ? x : y)
.get();
System.out.println(max); // 9
int initialized = numbers.stream()
.reduce(9, (x, y) -> x * y);
System.out.println(initialized); // -4374
4. Stream에 담긴 데이터를 collection으로 리턴
/**
* Performs a <a href="package-summary.html#MutableReduction">mutable
* reduction</a> operation on the elements of this stream using a
* {@code Collector}. A {@code Collector}
* encapsulates the functions used as arguments to
* {@link #collect(Supplier, BiConsumer, BiConsumer)}, allowing for reuse of
* collection strategies and composition of collect operations such as
* multiple-level grouping or partitioning.
*
* <p>If the stream is parallel, and the {@code Collector}
* is {@link Collector.Characteristics#CONCURRENT concurrent}, and
* either the stream is unordered or the collector is
* {@link Collector.Characteristics#UNORDERED unordered},
* then a concurrent reduction will be performed (see {@link Collector} for
* details on concurrent reduction.)
*
* <p>This is a <a href="package-summary.html#StreamOps">terminal
* operation</a>.
*
* <p>When executed in parallel, multiple intermediate results may be
* instantiated, populated, and merged so as to maintain isolation of
* mutable data structures. Therefore, even when executed in parallel
* with non-thread-safe data structures (such as {@code ArrayList}), no
* additional synchronization is needed for a parallel reduction.
*
* @apiNote
* The following will accumulate strings into an ArrayList:
* <pre>{@code
* List<String> asList = stringStream.collect(Collectors.toList());
* }</pre>
*
* <p>The following will classify {@code Person} objects by city:
* <pre>{@code
* Map<String, List<Person>> peopleByCity
* = personStream.collect(Collectors.groupingBy(Person::getCity));
* }</pre>
*
* <p>The following will classify {@code Person} objects by state and city,
* cascading two {@code Collector}s together:
* <pre>{@code
* Map<String, Map<String, List<Person>>> peopleByStateAndCity
* = personStream.collect(Collectors.groupingBy(Person::getState,
* Collectors.groupingBy(Person::getCity)));
* }</pre>
*
* @param <R> the type of the result
* @param <A> the intermediate accumulation type of the {@code Collector}
* @param collector the {@code Collector} describing the reduction
* @return the result of the reduction
* @see #collect(Supplier, BiConsumer, BiConsumer)
* @see Collectors
*/
<R, A> R collect(Collector<? super T, A, R> collector);
- Stream을 원하는 collection으로 바꿔줄 때 주로 사용하는 collector
예제로 살펴보자.
List<Integer> list = Stream.of(1,2,3)
.collect(Collectors.toList());
System.out.println(list); // [1, 2, 3]
Set<Integer> set = Stream.of(1,2,3,3,3,3,3)
.collect(Collectors.toSet());
System.out.println(set); // [1, 2, 3]
list = Stream.of(-1,2,-3)
.collect(Collectors.mapping(x -> Math.abs(x), Collectors.toList()));
System.out.println(list); // [1, 2, 3]
// reduce대신 아래와 같이 사용할 수도 있다.
int sum = Stream.of(-1,2,-3)
.collect(Collectors.reducing(0, (x, y) -> x + y));
System.out.println(sum); // -2
반응형
'프로그래밍 > JAVA' 카테고리의 다른 글
문자열을 생성할 때 어떻게 생성하나요? (0) | 2024.08.28 |
---|---|
Error와 Exception의 차이를 아시나요? (1) | 2024.08.28 |
Optional (0) | 2022.08.12 |
Stream (0) | 2022.07.25 |
Method Reference (0) | 2022.07.14 |