-
스트림의 연산 - 중간 연산JAVA/스트림 2023. 8. 8. 22:47
1. 스트림 자르기 - skip(), limit()
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()
Stream<T> filter(Predicate<? super T> predicate // 조건에 맞지 않는 요소 제거
Stream<T> distinct() // 중복 제거
distinct() 예시 코드
IntStream intStream = IntStream.of(1,2,2,3,3,3,4,5,5,6); intStream.distinct().forEach(System.out::print); // 1 2 3 4 5 6 출력
filter() 예시 코드
IntStream intStream = IntStream.rangeClosed(1, 10); // 1 2 3 4 5 6 7 8 9 10 intStream.filter(i->i%2==0).forEach(System.out::print); // 2 4 6 8 10만 출력
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);
filter()는 중간 연산자이니 여러번 사용 가능하다. &&를 통해 두 번 사용해도 되고 filter()를 두 번 붙여줘도 된다.
3. 스트림 정렬하기 - sorted()
Stream<T> sorted() // 스트림 요소의 기본 정렬(Comparable)로 정렬
Stream<T> sorted(Comparator<? super T> comparator) // 지정된 Comparator로 정렬
strStream.sorted(Comparator.reverseOrder()) // 기본 정렬의 역순으로 정렬
Comparator의 comparing() 정렬
studentStream.sorted(Comparator.comparing(Student::getName)) .forEach(System.out::println);
studentStream에서 Student 객체 하나씩을 Name으로 정렬하는 것이다.
studentStream.sorted(Comparator.comparing(Student::getName) .thenComparing(Student:getScore)) .forEach(System.out::println);
thenComparing을 통해서 정렬 기준을 여러개로 정할 수도 있다. 이름 순으로 정렬하고, 성적순으로 정렬하는 것이다.
4. 스트림의 요소 변환하기 - map()
Stream<R> map(Function<? super T, ? extend R> mapper
Stream<File> fileStream = Stream.of(new File("one.java"), new File("two"), new File("three.java"), new File("four.txt")); Stream<String> filenameStream = fileStream.map(File::getName); filenameStream.forEach(System.out::println); // 스트림의 모든 파일의 이름을 출력
fileStream이라는 스트림에서 파일들을 받아온 다음 fileStream.map()을 통해 file의 이름들을 map을 변환해서 그 요소들을 filenameStream이라는 String 타입의 스트림으로받아온 것이다.
파일 스트림에서 파일 확장자를 중복없이 뽑아내는 예제
fileStream.map(File::getName) .filter(s -> s.indexOf('.') != -1) // 확장자가 없는 것은 제외 .map(s -> s.substring(s.indexOf('.')+1)) // 확장자만 뽑아낸 것 (one.java면 java만) .map(String::toUpperCase) // 대문자로 변환 .distinct() .forEach(System.out::print); // JAVAJAVATXT 출력
map이 총 3번 쓰였는데 맨 위는 Stream<File> -> Stream<String>으로 변환한 것이고 나머지 둘은 타입의 변환은 이루어지지 않는 것이다.
5. 스트림의 요소를 소비하지 않고 조회하기 - peak()
스트림을 소비하는 최종 연산인 forEach()와 달리 peak()는 중간 연산이며 스트림을 소비하지 않는다.
Stream<T> peek(Consumer<? super T> action)
fileStream.map(File::getName) .filter(s -> s.indexOf('.') != -1) // 확장자가 없는 것은 제외 .peak(s -> System.out.printf("filename = %s%n", s)) // 파일명 출력 .map(s -> s.substring(s.indexOf('.')+1)) // 확장자만 뽑아낸 것 (one.java면 java만) .peak(s -> System.out.printf("extension = %s%n", s)) // 확장자를 출력 .forEach(System.out::print); // JAVAJAVATXT 출력
위의 예제에서 peak()을 추가했는데 중간 중간 결과를 보기 위해서 사용된다.
6. 스트림의 스트림을 스트림으로 변환 - flatMap()
Stream<String[]> strArrStrm = Stream.of(new String[]{"abc", "def", "ghi" }, new String[]{"ABC", "DEF", "JKLMN"}); // 스트림 요소 하나 하나가 배열로 되어있음 Stream<Stream<String>> strStrStrm = strArrStrm.map(Arrays::stream);
위와 같은 상황은 스트림의 스트림이 된다.
| "aaa", "bbb" | | "abc", "ABC" | | "ccc", "ddd" |
위의 3개가 모두 스트림이고 3개의 모임이 스트림으로 되어있기 때문이다.
배열이 있을 때 map을 사용하면 이렇게 된다.
이거를 하나의 스트림 -> "abc", "bbb", "abc", "ABC", "ccc", "ddd"로 바꾸기 위해 사용되는 것이 flatMap()이다.
Stream<String> strstrStrms = strArrStrm.flatMap(Arrays::stream);
map이 아니라 flatMap을 사용하면 하나의 스트림이 된다.
'JAVA > 스트림' 카테고리의 다른 글
collect()와 Collectors (0) 2023.08.09 Optinal (0) 2023.08.09 스트림의 연산 - 최종 연산 (0) 2023.08.08 스트림 만들기 (0) 2023.08.08 스트림 (0) 2023.08.08