스트림은 내부 반복자가 있어서 병렬처리가 가능하며, 이를 통해 간결하게 Java를 표현하고자 하여 사용됨을 배웠다.
스트림은 1회용으로만 사용할 수 있다. 최종 연산(ex. forEach) 등이 수행된 스트림은 재사용할 수 없다. 재사용하면 java.lang.IllegalStateException 이 발생한다.
Unmobidiable List : 수정 불가 전용 리스트-불변성 보장/*Unmodifiable List*/
List<String> unmodifiableList = Collections.unmodifiableList(flatList);
System.out.println("unmodifiableList = " + unmodifiableList);
List<String> unmodifiableList2 = List.of("A", "B", "C");
List<String> unmodifiableList3 = Stream.of("A", "B", "C");
//전부 .add() 가 불가능하다.
Thread , currentThread()
Thread: 카카오톡의 기능은 채팅. 이는 하나의 기능, 곧 Thread다. Single Thread라고할 때 한 번에 하나 밖에 동작을 못한다. 누군가 채팅을 하는 중 다른 작업을 덮어쓰면 채팅을 못할 것. → 별도로 작업을 할 수 있게끔 Multi Thread 로 여러 작업을 할 수 있게 하였다.
CurrentThread : 현재 어떤 Thread인지 출력해주는 것
void print(s)
private static void print(String str) {
System.out.println(str + " : " + Thread.currentThread().getName());
}
결과 -> 모든 작업은 기본적으로 main Thread에서 사용된다.
java : main
mariadb : main
html : main
css : main
mybatis : main
main() : 노멀 쓰레드로→ Stream()으로 돌리면 얘도 전부 메인에서 돌아간다.
System.out.println("Normal Stream ================"
list.stream().forEach(Application2::print);//메소드참조
결과
Normal Stream ================
java : main
mariadb : main
html : main
css : main
mybatis : main
maain()에서 parallelStream() 병렬 처리로 사용하면
System.out.println("parallel stream ==============");
list.parallelStream().forEach(Application2::print);
list.parallelStream().forEach(Application2::print);
아래와 같이 나온다.
parallel stream ==============
html : main
mybatis : main
css : main
mariadb : ForkJoinPool.commonPool-worker-1
java : main
html : main
java : ForkJoinPool.commonPool-worker-1
mariadb : ForkJoinPool.commonPool-worker-3
mybatis : ForkJoinPool.commonPool-worker-2
css : main
중계 연산은 최종 연산 수행 전까지 여러 번 수행할 수 있으며 먼저 일어난 중계 연산의 결과가 파이프라인을 통해 다음 연산으로 전달된다.
IntStream intStream = IntStream.range(1,5);
intStream.filter(i -> (i%2)==0).forEach(i->System.out.print(i+ " "));
```java
0 2 4 6 8
```
| 상세 역할 | 메소드 |
|---|---|
| 필터링 | filter(), distinct() |
| 변환 | map(), flatMap() |
| 제한 | limit(), skip() |
| 정렬 | sorted() |
| 결과 확인 | peek() |
MAP 예제
IntStream intStream = IntStream.range(0,10);
intStream
.filter(i -> (i%2)==0) //짝수 .filter() : 0 2 4 6 8
//forEach로 넘겨받은 값들이 여기에서 걸려서 Map()에서 하나하나씩 연산을 수행한다.파이썬의 map과 가장 유사하네
.map(i -> i*5) // 0 20 40 60 80
.forEach( i -> System.out.print(i + " "));
0 10 20 30 40 List<List<String>> 이중 중첩 List
List<List<String>> list = Arrays.asList(
Arrays.asList("JAVA", "SPRING", "SPRINGBOOT"),
Arrays.asList("java", "spring", "springboot")
);
System.out.println("list = " + list);
flatMap으로 위 두 개의 배열을 합쳐주기
List<String> flatList = list.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
System.out.println("flatList = " + flatList);
list = [[JAVA, SPRING, SPRINGBOOT], [java, spring, springboot]]
flatMap->
flatList = [JAVA, SPRING, SPRINGBOOT, java, spring, springboot].asList()로 하는 법
List<String> sentence = Arrays.asList(
"Hello world",
"Java Stream API",
"flatMap Example"
);
System.out.println("sentence = " + sentence);
/*잘랐다가 다시 붙이기*/
List<String> words = sentence.stream()
.flatMap(sentence2 -> Arrays.stream(sentence2.split(" "))) // 자르기
.toList(); //얘가 다시 list로 바뀐다.
System.out.println("words = " + words);
words = [Hello, world, Java, Stream, API, flatMap, Example]List<Integer> intList = IntStream.of(5,1,3,4,2,6)
.boxed() //wrapper Class
.sorted() //기본(오름차순)정렬 -> .sorted((a , b) -> b - a)
.collect(Collectors.toList()); // list로 변경
System.out.println("intList = " + intList);
intList = [1, 2, 3, 4, 5, 6]public static void main(String[] args) {
long count = IntStream.range(1, 10).count(); // 9
long sum = IntStream.range(1, 10).sum(); // sum : 45
OptionalInt max = IntStream.range(1, 10).max(); // max = OptionalInt[9]
OptionalInt min = IntStream.range(1, 10).min(); // min = O[1]
int OddSum = IntStream.range(1, 10)
.filter(i -> i % 2 == 1)
.sum(); // 홀수 합계 25
}
OptionalInt : 결과 없음을 나타내는 명확한 요구가 있는 메소드의 반환 형식으로 사용reduce()return의 생략
OptionalInt reduceOneParam =
IntStream.range(1, 10)
.reduce((a, b)-> {
return Integer.sum(a,b);
});
OptionalInt reduceOneParam =
IntStream.range(1, 10)
.reduce((a, b)-> Integer.sum(a,b));
Stream 내의 요소들은 [1,2,3,4,5,6,7,8,9]의 내용들을 들고 들어오는 것을 의미함.
인자가 2개인 경우
int reduceTwoParam = IntStream.range(1,10).reduce(100, Integer::sum);
reduce : 100의 내용과 Integer::sum(45) 의 내용을 모두 더한 것.
System.out.println("reduceTwoparam : " + reduceTwoParam);
결과 : return을 하지 않도록 줄여줌.?
145 -> 100을 이전 값 45에 더해줌.
인자가 3개인 경우
Integer reduceThreeParam = Stream.of(1,2,3,4,5,6,7,8,9,10)
.parallel().reduce(
100, Integer::sum, (x,y)->x + y
);
System.out.println("reduceThreeParam = " + reduceThreeParam);
결과
reduceThreeParam = 1055
.parallel() : 병렬 처리이다. 세 가지의 인자부터는 병렬처리 과정이 필요하게 된다.1. anyMatch(Predicate<? super T> predicate); : 하나의 조건이라도 만족하는 값이 있는지
List<String> stringList = Arrays.asList("Java", "Spring", "SpringBoot");
boolean anyMatch = stringList.stream().anyMatch(str -> str.contains("z"));
System.out.println("anyMatch = " + anyMatch);
하나라도 매치되는 값이 있는지 찾고, 있으면 true, 없으면 false반환
2. allMatch(...); : 모든게 조건에 부합한가?
boolean allMatch = stringList.stream().allMatch(str -> str.length() > 4);
System.out.println("allMatch = " + allMatch); // stringList에 있는 문자열의 길이가 4보다 큰가? X
3. noneMatch(..); : 모든 조건을 만족하지 않는가?
boolean noneMatch = stringList.stream().noneMatch(str -> str.contains("a"));
System.out.println("noneMatch = " + noneMatch);