JAVA Stream 연산

강정우·2022년 11월 18일
0

JAVA

목록 보기
27/31
post-thumbnail

1. 스트림 중간 연산

Stream<T> distinct() : 중복을 제거
Stream<T> filter(Predicate<T> predicate) : 조건에 안 맞는 요소 제외
Stream<T> limit(long maxSize) : 스트림의 일부를 잘라낸다.
Stream<T> skip(long n) : 스트림의 일부를 건너뛴다.
Stream<T> peek(Consumer<T> action) : 스트림의 요소에 작업수행 => forEach와 비슷하고 작업 중간에 넣어서 결과를 확인할 때
Stream<T> sorted()
Stream<T> sorted(Comparator<T> comparator) : 스트림의 요소를 이때 comparator기준으로 정렬한다.

Stream<R> map(Function<T, R> mapper)
DoubleStream mapToDouble(ToDoubleFuntion<T> mapper)
IntStream mapToInt(ToIntFunction<T> mapper)
LongStream mapToLong(ToLongFunction<T> mapper)
// 요 위, 아래 4줄은 스트림의 요소를 변환한다.
Stream<R>  flatmap(Function<T, Stream <R>> mapper)
DoubleStream flatmapToDouble(Function<T, DoubleStream> m)
IntStream flatmapToInt(Function<T, IntStream> m)
LongStream flatmapToLong(Function<T, LongStream> m)
  • // 이 중간연산의 핵심은 map & flatMap을 얼마나 잘 쓰냐이다.

1) skip(), limit()

  • skip : 앞에서부터 n개 건너뛰기
  • linig : maxSize 이후의 요소는 잘라냄
Stream<T> skip(long n)  // 앞에서부터 n개 건너뛰기
Stream<T> limit(long maxSize)  // maxSize 이후의 요소는 잘라냄
  • 예시
IntStream intStream = IntStream.rangeClosed(1, 10);  // 12345678910
intStream.skip(3).limit(5).forEach(System.out::print);  // 45678

2) filter(), distinct()

  • filter : 조건에 맞지 않는 요소 제거
  • distinct : 중복제거
Stream<T> filter(Predicate<? super T> predicate)  // 조건에 맞지 않는 요소 제거
Stream<T> distinct()  // 중복제거
  • 예시
IntStream intStream = IntStream.rangeClosed(1, 10); // 12345678910
intStream.filter(i->i%2==0).forEach(System.out::print);  // 246810
intStream.filter(i->i%2!=0 && i%3!=0).forEach(System.out::print);
intStream.filter(i->i%2!=0).filter(i->i%3!=0).forEach(System.out::print);

IntStream intStream = IntStream.of(1,2,2,3,3,3,4,5,5,6)'
intStream.distinct().forEach(System.out::pring);  // 123456

3) sorted()

  • sorted : 스트림요소의 기본정렬하거나 지정된 Comparator로 정렬함
Stream<T> sorted()  // 스트림 요소의 기본 정렬(Comparable)로 정렬
Stream<T> sorted(Comparator<? super T> comparator)  // 지정된 Comparator로 정렬
  • 예시
strStream.sorted()							 // 기본정렬
strStream.sorted(Comparator.naturalOrder())  // 기본정렬
strStream.sorted((s1, s2) -> s1.compareTo(s2));  // 람다식도 가능
strStream.sorted(String::compareTo); 		 // 위의 문장과 동일
// result
CCaaabccdd


strStream.sorted(Comparator.reverseOrder())  // 기본 정렬의 역순
strStream.sorted(Comparator.<String>naturalOrder().reversed())  // 요건 굳이...?
// result
ddccbaaaCC


strStream.sorted(String.CASE_INSENSITIVE_ORDER) // 대소문자 구분 안함 원래는 대문자 먼저 쫚 온다.
// result
aaabCCccdd

strStream.sorted(String.CASE_INSENSITIVE_ORDER.reversed())  // 역순정렬인데 그래도 대문자가 먼저나옴
// result
ddCCccbaaa

strStream.sorted(Comparator.comparing(String::length))     // 길이 순 정렬
strStream.sorted(Comparator.comparingInt(String::length))  // no오토박싱
// result
bddCCccaaa

strStream.sorted(Comparator.comparing(String::length).reversed())
// result
aaaddCCccb

4) Comparator의 comparing(), thenComparing()

  • Comparator의 comparing()으로 정렬기준을 제공
comparing(Function<T, U> keyExtractor)
comparing(Function<T, U> keyExtractor, Comparator<U> keyComparator)
  • 예시
studentStream.sorted(Comparator.comparing(Student::getBan))
			 .forEach(System.out::pringln);
            
studentSteam.sorted(Comparator.comparing((Student s)->s.getBan).reversed()
							  .thenComparing(Comparator.naturalOrder()).reversed())
                              .forEach(System.out::println);
  • 추가정렬 기준을 제공할 때는 thenComparing()을 사용
thenComparing(Comparator<T> other)
thenComparing(Function<T, U> keyExtractor)
thenComparing(Function<T, U> keyExtractor, Comparator<U> keyComp)
  • 예시
studentStream.sorted(Comparator.comparing(Studeng::getBen))
			 .thenComparing(Student::getTotalScore)
             .thenComparing(Student::getName)
			 .forEach(System.out::pringln);

5) map()

  • 스트림의 요소 변환하기
Stream<R> map(Function<? super T,? extends R> mapper)  //Stream<T> return Stream<R>
  • 예시
Stream<File> fileStream = Stream.of(new File("Ex1.java"), new File("Ex1") new File("Ex1.bak"), new File("Ex2.java"), new File("Ex1.txt"));
        
Stream<String> filenameStream = fileStream.map(File::getName);
filenameStream.forEach(System.out::println);  // 스트림의 모든 파일의 이름을 출력 
  • 예시2 파일 스트림에서 파일 확장자(대문자)를 중복없이 뽑아내기
fileStream.map(File::getName)							// Stream<File> => Stream(String)
		  .filter(s->s.indexOf('.') != -1)				// 확장자가 없는 것은 제외
          .map(s->s.substring(s.indexOf('.)+1)) 		// Stream<String> (파일이름 전체) => Stream<String> (파일 확장자만)
          .map(String::toUpperCase)						// Stream<String> => Stream<String>
          .distinct()									// 중복제거
          .forEach(System.out::pring);					// JAVABAKTXT

6) peak()

  • 디버깅용으로 많이 쓰임
Stream<T> peek(Consumer<? super T> action)  // 중간연산(스트림을 소비 X)
void forEach(Consumer<? super T> action)  // 최종연산(스트림을 소비 O)
  • 예시
fileStream.map(File::getName)  // Stream<File> => Stream<String>으로 변환
		  .filter(s -> s.indexOf('.') != -1)  // 확장자가 없는 것은 제외
          .peek(s -> System.out.pringf("filename=%s%n", s))  // 파일명을 출력한다
          .map(s -> s.substring(s.indexOf('.')+1))
          .peek(s -> Systemout.pringf("extension=%s%n", s))  // 확장자를 출력한다
          .forEach(System.out::println);  // 최종연산 스트림을 소비.

7) flatMap()

  • 스트림의 스트림을 스트림으로 변환
Stream<String []> strArrStrm = Stream.of(new String[]{"abc", "def", "ghi"},
										 new String[]{"ABC", "GHI", "JKLMN"});
  • 예시 : 만약 그냥 .map() 을 쓴다면 스트림의 스트림이 되어버린다.
Stream<Stream<String>> strStrStream = strArrStrm.map(Arrays::Stream);  // Arrays.stream(T[])
  • 예시 : 만약 당신이 여러개의 문자열 배열을 하나의 문자열 배열로 바꾸길 원한다면 .flatMap() 을 쓰면 된다.
Stream<String> strStrStream = strArrStrm.flatMap(Arrays::Stream);  // Arrays.stream(T[])

2. 스트림 최종 연산

// 각 요소에 지정된 작업 수행
void forEach(Consumer<? super T> action) 
void forEachOrdered(Consumer<? super T> action) : 병렬스트림으로 처리할 때 스트림 요소의 순서를 유지하는 기능

long count() : 스트림 요소의 개수 반환

Optional<T> max(Comparator<? super T> comparator) : 정렬 기준으로 스트림의 최대값을 반환
Optional<T> min(Comparator<? super T> comparator) : 정렬 기준으로 스트림의 최솟값을 반환

// 스트림 요소 하나를 잔환
Optional<T> findAny() : 병렬처리할 때 아무거나 하나 
Optional<T> finFirst() : 직렬처리할 때 첫 번째 요소

// 주어진 조건을 모든 요소가 만족시키는지, 만족시키지 않는지 확인 return은 true, false로
boolean allMatch(Predicate<T> p) : 모두 만족하는지
boolean anyMatch(Predicate<T> p) : 하나라도 만족하는지
boolean noneMatch(Predicate<T> p) : 모두 만족하지 않는지

// 스트림의 모든 요소를 배열로 반환
Object[] toArray()
A[]      toArray(IntFunction<A[]> generator) : 이걸 사용하면 특정 type의 객체로 변환하여 담을 수 있다.

// 스트림의 요소를 하나씩 줄여가면서 계산한다.
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)
U reduce(U identity, BiFunction<U,T,U> accumulator, BinaryOperator<U> combiner)

// 스트림의 요소를 수집한다.
// 주로 요소를 그룹화하거나 분할한 결과를 컬렉션에 담아 반환하는데 사용된다.
R collect(Collector<T, A, R> collector)
R collect(Supplier<R> supplier. BiConsumer<R,T> accumulator, BiConsumer<R, R> combiner)
  • 요 최종연산의 핵심은 reduce와 collect이다.
profile
智(지)! 德(덕)! 體(체)!

0개의 댓글