일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- JPA값타입
- dockercmd
- 스프링부트
- JPAproxy
- sql
- jpa
- jpqlquery
- 제이피큐엘쿼리
- springbootH2
- JPAmapping
- OSIV
- httppie
- javageneric
- JPA프록시
- springboot기본설정
- spring
- gitinitial
- embededtype
- 에이치투데이터베이스
- 데이터베이트h2
- 스프링부트기본설정
- JPA Hint & Lock
- 이해와 원리
- JDBC connection pool
- MySqlType
- Open EntityManager
- 임베디드타입
- 자바제너릭
- Git
- springbootproxy
- Today
- Total
빡코
[Java] 스트림 API 본문
Stream은 자바 8부터 추가된 기능으로 "컬렉션, 배열등의 저장 요소를 하나씩 참조하며 함수형 인터페이스(람다식)를 적용하며 반복적으로 처리할 수 있도록 해주는 기능"이다
즉, 불필요한 코딩(for, if 문법)을 걷어낼 수 있고 직관적이기 때문에 가독성이 좋아진다.
package coding_test;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test3 {
public static void main(String[] args) {
List<String> names = Arrays.asList("jeong","pro","jdk","java");
long count = 0;
//기존 for문을 이용
for(String name: names){
if(name.contains("o")){
count++;
}
}
System.out.println("count: "+ count);
//스트림 이용한 방식
count = 0;
count = names.stream().filter(x ->x.contains("o")).count();//fitler: 조건엔 맞는것만 거른다
System.out.println("count2: "+count);
//map을 이용
names.parallelStream()
.map((x) ->{return x.concat("s");})
.forEach(x-> System.out.println(x));
//map은 스트림의 각 요소를 연산하는데 쓰인다.
//위의 경우는 각 문자열(요소)akek 뒤에 "s"를 붙인다.
//*concat 함수: 문자열과 문자열을 합친 함수를 리턴한다.
List<Integer> nums = Arrays.asList(1,2,3,4,5);
nums.parallelStream()
.map((x) ->{return x*2;}) //각요소에 연산 적용
.forEach(x -> System.out.println(x));
//Limit
List<Integer> ages = Arrays.asList(1,2,3,4,5,6,7,8,9);
ages.stream().filter(x -> x>3).limit(3) //스트림갯수를 3으로 제한
.forEach(x -> System.out.printf("%d,",x));
List<Integer> nums2= Arrays.asList(4,4,2,3,1,2);
nums2.stream()
.sorted() //정렬
.distinct() //중복제거
.forEach(x -> System.out.println(x));
//skip: .skip(3): 처음 3개의 요소는 제외하고 나머지 요소들로 새로운 트림 만든다
List<Integer> nums3 = Arrays.asList(1,2,3,4,5,6,7,8,9);
nums3.stream().skip(3)
.forEach(x -> System.out.println(x));
//reduce: 아래에서 설명
List<Integer> ages3 = new ArrayList<Integer>();
ages3.add(1); ages3.add(2); ages3.add(3);
System.out.println("값:"+ages3.stream()
.reduce((b,c) -> b+c)
.get());
}
}
Java8의 Stream reduction 사용 방법
System.out.println(Arrays.asList(1,2,3)
.stream().reduce(1,(a,b) -> {return a+b;}));
//결과값 7
reduce()의 param으로 (total, n) -> total + n가 전달되고, reduce는 a1, a2, a3, a4...의 stream을 a1 + a2 + a3 + a4...로 연산을 수행합니다. 첫번째로 total=a1, n=a2가 되고, 두번째로 total=(a1+a2), n=a3가 됩니다.
함수를 정의하지 않고 Integer::sum을 사용해도 위와 동일한 결과를 출력합니다.
Stream<Integer> numbers2 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Optional<Integer> sum2 = numbers2.reduce(Integer::sum);
sum2.ifPresent(s -> System.out.println("sum2: " + s));
//결과값: sum2: 55
초기값 있는 Reduction
위와 동일한 동작을 하지만 초기값을 지정해줄 수 있습니다. 첫번째 param으로 초기값을 넘겨주면 됩니다. 초기값이 없는 위와 유사하게 '10 + 1 + 2 + ... 10'으로 연산됩니다.
Stream<Integer> numbers3 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum3 = numbers3.reduce(10, (total, n) -> total + n);
System.out.println("sum3: " + sum3);
//sum3: 65
병렬처리 & Reduction
parallel()을 사용하면 병렬처리로 연산을 수행할 수 있습니다. 순차적으로 연산을 수행하지 않고 여러개의 작업을 병렬로 처리합니다. (1 + 2) + (3 + 4) + ... + (9 + 10)처럼 병렬적으로 처리됩니다.
Stream<Integer> numbers4 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum4 = numbers4.parallel().reduce(0, (total, n) -> total + n);
System.out.println("sum4: " + sum4);
//sum4: 55
하지만 -(마이너스) 연산인 경우 병렬처리는 순차처리와 결과가 다릅니다. 아래 코드를 보면 결과가 -55가 아니라 -5가 됩니다. (1 - 2) - (3 - 4) - ... - (9 - 10)처럼 연산의 순서가 어떻게 되냐에 따라서 결과가 순차처리와 다르게 됩니다.
Stream<Integer> numbers5 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum5 = numbers5.parallel().reduce(0, (total, n) -> total - n);
System.out.println("sum5: " + sum5);
//sum5: -5
순서 있는 병렬처리 Reduction
병렬처리에서 연산 순서에 따라 발생하는 문제를 해결하기 위해 다음과 같이 다른 규칙을 추가할 수 있습니다. param으로 (total1, total2) -> total1 + total2를 추가하였는데 병렬처리된 결과의 관계를 나타냅니다. 첫번째 연산과 두번째 연산은 합해야 한다는 규칙을 정의하여, 연산결과가 순차처리와 동일하게 됩니다.
Stream<Integer> numbers6 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum6 = numbers6.reduce(0,
(total, n) -> total - n,
(total1, total2) -> total1 + total2);
System.out.println("sum6: " + sum6);
//sum6: -55
참조
https://codechacha.com/ko/java8-stream-reduction/
https://www.baeldung.com/java-stream-reduce //원문
https://wraithkim.wordpress.com/2017/04/13/java-8-%EC%8A%A4%ED%8A%B8%EB%A6%BC-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC/
https://jeong-pro.tistory.com/165
http://iloveulhj.github.io/posts/java/java-stream-api.html