// iterate와 generate
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
static <T> Stream<T> generate(Supplier<T> s)
// 0부터 시작해서 값이 2씩 계속 증가하는 예제코드
Stream<Integer> evenStream = Stream.iterate(0, n -> n+2); // 0,2,4,6, ...
// generate() 사용 예제 코드
Stream<Double> randomStream = Stream.generate(Math::random);
Stream<Integer> oneStream = Stream.getnerate( () -> 1);
💡 iterate( )와 generate( )에 의해 생성된 스트림을 기본형 스트림 타입의 참조변수로 다룰 수 없다는 것에 주의해야 한다.
// iterate()와 generate()를 기본형 스트림 타입으로 다루는 예제(에러 케이스)
IntStream evenStream = Stream.iterate(0, n -> n+2); // 에러
DoubleStream randomStream = Stream.generate(Math::random); // 에러
기본형 스트림 타입의 참조변수로 꼭 다뤄야 하는 경우라면 mapToInt( )와 같은 메서드로 변환을 해야 한다.
IntStream evenStream = Stream.iterate(0, n -> n+2).mapToInt(Integer::valueOf);
Stream<Integer> stream = evenStream.boxed(); // IntStream -> Stream<Integer>
// 빈 스트림을 반환하는 예제
Stream emptyStream = Stream.empty(); // empty()는 빈 스트림을 생성해서 반환한다.
long count = emptyStream.count(); // count의 값은 0
// Stream 연결 예제
String[] str1 = {"123", "456", "789"};
String[] str2 = {"ABC", "abc", "DEF"};
Stream<String> strs1 = Stream.of(str1);
Stream<String> strs2 = Stream.of(str2);
Stream<String> strs3 = Stream.concat(strs1, strs2); // 두 스트림을 하나로 연결
// skip()
Stream<T> skip(long n)
// limit()
Stream<T> limit(long maxsize)
// 10개의 요소를 가진 스트림에 skip()과 limit()을 적용하는 예제
IntStream intStream = IntStream.rangeClosed(1, 10); // 1~10의 요소를 가진 스트림
intStream.skip(3).limit(5).forEach(System.out::print); // 45678
// filter()
Stream<T> filter(Predicate<? super T> predicate)
// distinct()
Stream<T> distinct()
// distinct() 사용 예제
IntStream intStream = IntStream.of(1, 2, 2, 3, 3, 3, 4, 5, 5, 6);
intStream.distinct().forEach(System.out::print); // 123456
// 조건이 하나인 filter() 예제
IntStream intStream = IntStream.rangeClosed(1,10); // 1~10
intStream.filter(i -> i%2 == 0).forEach(System.out::println); // 246810
// 조건이 두개인 filter() 예제
intStream.filter(i -> i%2 != 0 && i%3 != 0).forEach(System.out::print); // 157
intStream.filter(i -> i%2 != 0).filter(i -> i%3 != 0).forEach(System.out::print);
💡 필요하면 filter( )를 다른 조건으로 여러 번 사용할 수도 있다.
Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> comparator)
comparing(Function<T, U> keyExtractor)
comparing(Function<T, U) ketExractor, Comparator<U> keyComparator)
// 기본형이 비교 대상일 경우 사용하면 좋은 메서드
comparingInt(ToIntFunction<T> keyExractor)
comparingLong(ToLongFunction<T> keyExractor)
comparingDouble(ToDoubleFunction<T> keyExractor)
// 정렬 조건을 추가하는 메서드
thenComparing(Comparator<T> other)
thenComparing(Function<T, U> keyExractor)
thenComparing(Functino<T, U> keyExractor, Comparator<U> keyComp)
// 학생 스트림을 반별, 성적순, 그리고 이름 순으로 정렬하여 출력하는 예제
studentStream.sorted(Comparator.comparing(Student::getBan)
.thenComparing(Student::getTotalScore)
.thenComparing(Student::getName)
.forEach(System.out::println);
// map() 메서드의 선언부
Stream<R> map(Function<? super T, ? extends R> mapper)
// File의 스트림에서 파일의 이름만 뽑아서 출력하는 예제
Stream<File> fileStream = Stream.of(new File("Ex1.java"), new File("Ex1"),
new File("Ex1.bak"), new File("Ex2.java"), new File("Ex1.txt"));
// map()으로 Stream<File>을 Stream<String>으로 변환
Stream<String> filenameStream = fileStream.map(File::getName);
filenameStream.forEach(System.out::println); // 스트림의 모든 파일이름을 출력
// File의 스트림에서 파일의 확장자만을 뽑고, 중복을 제거해서 출력하는 예제
fileStream.map(File::getName) // Stream<File> -> Stream<String>
.filter(s -> s.indexOf('.') != -1) // 확장자가 없는 것은 제외
.map(s -> s.substring(s.indexOf('.') + 1)) // Stream<String> -> Stream<String>
.distinct() // 중복 제거
.forEach(System.out::print); // JAVABAKTXT
// peek() 사용예제
fileStream.map(File::getName) // Stream<File> -> Stream<String>
.filter(s -> s.indexOf('.' != -1) // 확장자가 없는 것은 제외
.peek(s -> System.out.printf("filename = %s%n" , s)) // 파일명을 출력한다.
.map(s -> s.substring(s.indexOf('.') + 1)) // 확장자만 추출
.peek(s -> System.out.printf("extension = %s%n" , s)) // 확장자를 출력한다.
.forEach(System.out::println);