-
3-7 자바의 기초(ch14)카테고리 없음 2022. 11. 12. 21:58
chapter14
#14-1~4
람다식(Lambda Expression)
-람다식이란, 함수(메서드)를 간단한 '식(expression)'으로 표현하는 방법
ex)
ㅋㄷㅂㄹ
int max(int a, int b) {
return a > b ? a : b;
}
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
(a, b) -> a > b ? a : b
ㅋㄷㅂㄹ ㄲ
-익명 함수(이름이 없는 함수, anonymous function)
ㅋㄷㅂㄹ
int max(int a, int b) {
return a > b ? a : b;
}
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
int max(int a, int b) -> {
return a > b ? a : b;
}
ㅋㄷㅂㄹ ㄲ
-함수와 메서드의 차이
=>근본적으로 동일. 함수는 일반적 용어, 메서드는 객체지향개념 용어
=>함수는 클래스에 독립적, 메서드는 클래스에 종속적
!람다식 작성하기
1. 메서드의 이름과 반환타입을 제거하고 '->'를 블록{} 앞에 추가한다.
ㅋㄷㅂㄹ
int max(int a, int b) {
return a > b ? a : b;
}
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
int max(int a, int b) ->{
return a > b ? a : b;
}
ㅋㄷㅂㄹ ㄲ
2. 반환값이 있는 경우, 식이나 값만 적고 return문 생략 가능(끝에 ';' 안 붙임)
ㅋㄷㅂㄹ
(int a, int b) ->{
return a > b ? a : b;
}
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
(int a, int b) -> a > b ? a : b
ㅋㄷㅂㄹ ㄲ
3. 매개변수의 타입이 추론 가능하면 생략가능(대부분의 경우 생략가능)
ㅋㄷㅂㄹ
(int a, int b) -> a > b ? a : b
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
(a, b) -> a > b ? a : b
ㅋㄷㅂㄹ ㄲ
!람다식 작성하기 - 주의사항
1. 매개변수가 하나인 경우, 괄호() 생략가능(타입이 없을 때만)
ㅋㄷㅂㄹ
(a) -> a * a
(int a) -> a * a
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
a -> a * a // OK
int a -> a * a // 에러
ㅋㄷㅂㄹ ㄲ
2. 블록 안의 문장이 하나뿐 일 때, 괄호{}생략가능(끝에 ';' 안 붙임)
ㅋㄷㅂㄹ
(int i) -> {
System.out.println(i)
}
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
(int i) -> System.out.println(i)
ㅋㄷㅂㄹ ㄲ
단, 하나뿐인 문장이 return문이면 괄호{} 생략불가
ㅋㄷㅂㄹ
(int a, int b) -> {return a > b ? a : b; } // OK
(int a, int b) -> return a > b ? a : b // 에러
ㅋㄷㅂㄹ ㄲ
!람다식의 예
(메서드와 람다식은 영상 강의 참조 09:00)
!람다식은 익명 함수? 익명 객체!
-람다식은 익명 함수가 아니라 익명 객체이다.
ㅋㄷㅂㄹ
(a, b) -> a > b ? a : b
ㅋㄷㅂㄹ ㄲ
↑
↓
ㅋㄷㅂㄹ
new Object() {
int max(int a, int b) {
return a > b ? a : b;
}
}
ㅋㄷㅂㄹ ㄲ
-람다식(익명 객체)을 다루기 위한 참조변수가 필요. 참조변수의 타입은?
ㅋㄷㅂㄹ
Object obj = new Object() {
int max(int a, int b) {
return a > b ? a : b;
}
}
ㅋㄷㅂㄹ ㄲ
참조변수는
ㅋㄷㅂㄹ
타입 obj = (a, b) -> a > b ? a : b ; // 어떤 타입?
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
int value = obj.max(3, 5); // 에러. Object클래스에 max()가 없음
ㅋㄷㅂㄹ ㄲ
#14-5,6
!함수형 인터페이스
-함수형 인터페이스 - 단 하나의 추상 메서드만 선언된 인터페이스
ㅋㄷㅂㄹ
interface MyFunction {
public abstract int max(int a, int b)
}
ㅋㄷㅂㄹ ㄲ
위 코드를 구현하면
↓
ㅋㄷㅂㄹ
MyFunction f = new MyFunction() {
public int max(int a, int b) {
return a > b ? a : b;
}
};
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
int value = f.max(3, 5); // OK. MyFunction에 max()가 있음.
ㅋㄷㅂㄹ ㄲ
이전 에러났던 max호출과는 달리,
이 함수형 인터페이스 f에는 맥스가 있음!
-함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있음.
(단, 함수형 인터페이스의 메서드와 람다식의 매개변수 개수와 반환타입이 일치해야 함)
ㅋㄷㅂㄹ
MyFunction f = (a, b) -> a > b ? a : b;
int value = f.max(3, 5); // 실제로는 람다식(익명 함수)이 호출됨
ㅋㄷㅂㄹ ㄲ
!함수형 인터페이스 - example
-익명 객체를 람다식으로 대체
ㅋㄷㅂㄹ
List<String> list = Arrays.asList("abc" , "aaa", "bbb", "ddd", "aaa");
Collections.sort(list, new Comparator<String>() {
public int compare(String s1, Sting s2) {
return s2.compareTo(s1) ;
}
} ) ;
ㅋㄷㅂㄹ ㄲ
이건 너무 길다.
ㅋㄷㅂㄹ
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
Collections.sort(list, (s1, s2) -> s2.compareTo(s1) );
ㅋㄷㅂㄹ ㄲ
!함수형 인터페이스 타입의 매개변수, 반환타입
-함수형 인터페이스 타입의 매개변수
ㅋㄷㅂㄹ
void aMethod(MyFunction f) {
f.myMethod() ; // MyFunction에 정의된 메서드 호출
}
ㅋㄷㅂㄹ ㄲ
여기서, f.myMethod라는 메서드를 호출하기위해
ㅋㄷㅂㄹ
@FunctionalInterface
interface MyFunction {
void myMethod();
}
ㅋㄷㅂㄹ ㄲ
myMethod 라는 메서드가 선언되어 있어야 함.
ㅋㄷㅂㄹ
MyFunction f = () -> System.out.println("myMethod() " );
aMethod(f) ;
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
aMethod( () -> System.out.pritnln("myMethod() ") );
ㅋㄷㅂㄹ ㄲ
-함수형 인터페이스 타입의 반환타입
ㅋㄷㅂㄹ
MyFunction myMethod() {
MyFunction f = () -> { } ;
return f;
}
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
MyFunction myMethod() {
return () -> { };
}
ㅋㄷㅂㄹ ㄲ
#14-7,8
!java.util.function 패키지
-자주 사용되는 다양한 함수형 인터페이스를 제공.
(표는 영상강의 전체 참조)
#14-9~12
!Predicate의 결합
-and(), or(), negate()로 두 Predicate를 하나로 결합(default메서드)
ㅋㄷㅂㄹ
Predicate<Integer> p = i -> i < 100;
Predicate<Integer> q = i -> i < 200;
Predicate<Integer> r = i -> i%2 == 0;
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
Predicate<Integer> notP = p.negate(); // i >= 100
Predicate<Integer> a11 = notP.and(q).or(r); // 100 <= i && i < 200 || i%2 == 0
Predicate<Integer> a112 = notP.and(q.or(r)); // 100 <= i && (i < 200 || i%2 == 0)
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
System.out.pritnln(a11. test(2) ) ; // true
System.out.pritnln(a112. test(2) ) ; // false
ㅋㄷㅂㄹ ㄲ
-등가비교를 위한 Predicate의 작성에는 isEqual()를 사용(static메서드)
ㅋㄷㅂㄹ
Predicate<String> p = Predicate.isEqual(str1) ; // isEquals()은 static메서드
Boolean result = p. test(str2) ; // str1과 str2가 같은지 비교한 결과를 반환
ㅋㄷㅂㄹㄲ
이 두 문장을 간단히 하면
ㅋㄷㅂㄹ
boolean result = Predicate.isEqual(str1) . test(str2);
ㅋㄷㅂㄹ ㄲ
로 쓸 수 있다.
!컬렉션 프레임웍과 함수형 인터페이스
-함수형 인터페이스를 사용하는 컬렉션 프레임웍의 메서드(와일드 카드 생략)
(표는 강의영상 참조 18:40)
#14-13,14
!메서드 참조(method reference)
-하나의 메서드만 호출하는 람다식은 '메서드 참조'로 간단히 할 수 있다.
(종류,람다,메서드 참조 표는 영상강의 참조)
-static메서드 참조
ㅋㄷㅂㄹ
Integer method(String s) { // 그저 Integer.parseInt(String s)만 호출
return Integer.parseInt(s);
}
ㅋㄷㅂㄹ ㄲ
위 코드를 람다식으로 바꾸면
ㅋㄷㅂㄹ
Function<String, Integer> f = (String s) -> Integer.parseInt(s) ;
ㅋㄷㅂㄹ ㄲ
위 코드에서 더 줄이면
ㅋㄷㅂㄹ
Function<String, Integer> f = Integer : : parseInt; // 메서드 참조
ㅋㄷㅂㄹ ㄲ
이렇게 됨.
!생성자의 메서드 참조
-생성자와 메서드 참조
ㅋㄷㅂㄹ
Supplier<MyClass> s = () -> new MyClass();
ㅋㄷㅂㄹ ㄲ
↓
ㅋㄷㅂㄹ
Supplier<MyClass> s = MyClass : : new;
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
Function<Integer, MyClass> s = (i) -> new MyClass(i);
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
Function<Integer, MyClass> s = MyClass : : new;
ㅋㄷㅂㄹ ㄲ
-배열과 메서드 참조
ㅋㄷㅂㄹ
Function<Integer, int[]> f = x -> new int[x]; // 람다식
Function<Integer, int[]> f2 = int[] : : new; // 메서드 참조
ㅋㄷㅂㄹ ㄲ
#14-15,16
!스트림(Stream)
-다양한 데이터 소스(컬렉션,배열 등)를 표준화된 방법으로 다루기 위한 것
ㅋㄷㅂㄹ
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream(); // 컬렉션
Stream<String> strStream = Stream.of(new String[ ] {"a", "b", "c"} ) ; // 배열
Stream<Integer> evenStream = Stream.iterate(0, n->n+2); // 0, 2, 4, 6 . . .
Stream<Double> randomStream = Stream.generate(Math: : random) ; // 람다식
IntStream intStream = new Random().ints(5); // 난수 스트림(크기가 5)
ㅋㄷㅂㄹ ㄲ
-스트림이 제공하는 기능 - 중간 연산과 최종 연산
중간 연산 - 연산결과가 스트림인 연산. 반복적으로 적용가능
최종 연산 - 연산결과가 스트림이 아닌 연산. 단 한번만 적용가능(스트림의 요소를 소모)
ex)
stream . distinct() . limit(5) . sorted() . forEach(System.out : : println)
중간연산 중간연산 중간연산 최종연산
ㅋㄷㅂㄹ
String[ ] strArr = {"dd", "aaa", "CC", "cc", "b" };
Stream<String> stream = Stream.of(strArr); // 문자열 배열이 소스인 스트림
Stream<String> filteredStream = stream.filter(); // 걸러내기(중간 연산)
Stream<String> distinctedStream = stream.distinct(); // 중복제거(중간 연산)
Stream<String> sortedStream = stream.sort(); // 정렬(중간 연산)
Stream<String> limitedStream = stream.limit(5) // 스트림 자르기(중간 연산)
int total = stream.count(); // 요소 개수 세기(최종연산)
ㅋㄷㅂㄹ ㄲ
!스트림(Stream)의 특징(1/3)
-스트림은 데이터 소스로부터 데이터를 읽기만할 뿐 변경하지 않는다.
ㅋㄷㅂㄹ
List<Integer> list = Arrays.asList(3, 1, 5, 4, 2);
List<Integer> sortedList = list.stream().sorted() // list를 정렬해서
.collect(Collectors.toList() ); // 새로운 List에 저장
System.out.println(list); // [3, 1, 5, 4, 2]
System.out.println(sortedList); // [1, 2, 3, 4, 5]
ㅋㄷㅂㄹ ㄲ
-스트림은 Iterator처럼 일회용이다.(필요하면 다시 스트림을 생성해야 함)
ㅋㄷㅂㄹ
strStream.forEach(System.out : : println) ; // 모든 요소를 화면에 출력(최종연산)
int numOfStr = strStream. count() ; // 에러. 스트림이 이미 닫혔음.
ㅋㄷㅂㄹ ㄲ
-최종 연산 전까지 중간연산이 수행되지 않는다. - 지연된 연산
ㅋㄷㅂㄹ
IntStream int Stream = new Random().ints(1,46); // 1~45범위의 무한 스트림
intStream.distinct().limit(6).sorted() // 중간 연산
.forEach(i -> System.out.print(i+",") ); // 최종 연산
ㅋㄷㅂㄹ ㄲ
!스트림(Stream)의 특징(2/3)
-스트림은 작업을 내부 반복으로 처리한다.
(영상강의 참조 17:25)
!스트림(Stream)의 특징(3/3)
-스트림의 작업을 병렬로 처리 - 병렬스트림
ㅋㄷㅂㄹ
Stream<String> strStream - Stream.of("dd", "aaa", "CC", "cc", "b");
int sum = strStream.parallel() // 병렬 스트림으로 전환(속성만 변경)
.mapToInt(s -> s.length() ). sum(); // 모든 문자열의 길이의 합
ㅋㄷㅂㄹ ㄲ
-기본형 스트림 - IntStream, LongStream, DoubleStream
=>오토박싱&언박싱의 비효율이 제거됨(Stream<Integer>대신 IntStream사용)
=>숫자와 관련된 유용한 메서드를 Stream<T>보다 더 많이 제공
#14-17~22
!스트림 만들기 - 컬렉션
-Collection인터페이스의 stream()으로 컬렉션을 스트림으로 변환
ㅋㄷㅂㄹ
Stream<E> stream() // Collection인터페이스의 메서드
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> intStream = list. stream() ; // list를 스트림으로 변환
//스트림의 모든 요소를 출력
intStream.forEach(System.out : : print); // 12345
intStream.forEach(System.out : : print); // 에러. 스트림이 이미 닫혔다.
ㅋㄷㅂㄹ ㄲ
!스트림 만들기 - 배열
-객체 배열로부터 스트림 생성하기
ㅋㄷㅂㄹ
Stream<T> Stream.of(T. . . values) // 가변 인자
Stream<T> Stream.of(T[ ])
Stream<T> Arrays.stream(T[ ])
Stream<T> Arrays.stream(T[ ] array, int startInclusive, int endExclusive)
Stream<String> strStream = Stream.of("a", "b", "c"); //가변 인자
Stream<String> strStream = Stream.of(new String[ ]{"a", "b", "c"} );
Stream<String> strStream = Arrays.stream(new String[ ] {"a", "b", "c" } );
Stream<String> strStream = Arrays.stream(new String[ ] {"a", "b", "c" }, 0, 3);
ㅋㄷㅂㄹ ㄲ
-기본형 배열로부터 스트림 생성하기
ㅋㄷㅂㄹ
IntStream IntStream.of(int. . . values) // Stream이 아니라 IntStream
IntStream IntStream.of(int[ ])
IntStream Arrays.stream(int[ ])
IntStream Arrays.stream(int[ ] array,int startInclusive, int endExclusive)
ㅋㄷㅂㄹ ㄲ
!스트림 만들기 - 임의의 수
-난수를 요소로 갖는 스트림 생성하기
ㅋㄷㅂㄹ
IntStreamintStream = new Random().ints(); // 무한 스트림
intStream.limit(5).forEach(System.out: : println); // 5개의 요소만 출력한다.
IntStream intStream = new Random().ints(5) // 크기가 5인 난수 스트림을 반환
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
Integer.MIN_VALUE <= ints() <= Integer.MAX_VALUE
Long.MIN_VALUE <= longs() <= Long.MAX_VALUE
0.0 <= doubles() < 1.0
ㅋㄷㅂㄹ ㄲ
*지정된 범위의 난수를 요소로 갖는 스트림을 생성하는 메서드(Random클래스)
ㅋㄷㅂㄹ
IntStream ints(int begin, int end) // 무한 스트림
longStream longs(long begin, long end)
DoubleStream doubles(double begin, double end)
IntStream ints(long streamSize, int begin, int end) // 유한 스트림
LongStream longs(long streamSize, long begin, long end)
DoubleStream doubles(long streamSize, double, double end)
ㅋㄷㅂㄹ ㄲ
!스트림 만들기 - 특정 범위의 정수
-특정 범위의 정수를 요소로 갖는 스트림 생성하기(IntStream, LongStream)
ㅋㄷㅂㄹ
IntStream IntStream.range(int begin, int end)
IntStream IntStream.rangeClosed(int begin, int end)
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
IntStream intStream = IntStream.range(1, 5); // 1, 2, 3, 4
IntStream intStream = IntStream.rangeClosed(1, 5); // 1, 2, 3, 4, 5
ㅋㄷㅂㄹ ㄲ
!스트림 만들기 - 람다식 iterate(), generate()
-람다식을 소스로 하는 스트림 생성하기
ㅋㄷㅂㄹ
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f) // 이전 요소에 종속적
static <T> Stream<T> generate(Supplier<T> s) // 이전 요소에 독립적
ㅋㄷㅂㄹ ㄲ
-iterate()는 이전 요소를 seed로 해서 다음 요소를 계산한다.
ㅋㄷㅂㄹ
Stream<Integer> evenStream = Stream.iterate(0, n->n+2); // 0, 2, 4, 6, . . .
ㅋㄷㅂㄹ ㄲ
-generate()는 seed를 사용하지 않는다.
ㅋㄷㅂㄹ
Stream<Double> randomStream = Stream.generate(Math : : random);
Stream<Integer> oneStream = Stream.generate( ()-> 1 );
ㅋㄷㅂㄹ ㄲ
!스트림 만들기 - 파일과 빈 스트림
-파일을 소스로 하는 스트림 생성하기
ㅋㄷㅂㄹ
Stream<Path> Files.list(Path dir) // Path는 파일 또는 디렉토리
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
Stream<String> Files.Lines(Path path)
Stream<String> Files.Lines(Path path, Charset cs)
Stream<String> lines() // BufferedReader클래스의 메서드
ㅋㄷㅂㄹ ㄲ
-비어있는 스트림 생성하기
ㅋㄷㅂㄹ
Stream emptyStream = Stream.empty(); // empty()는 빈 스트림을 생성해서 반환한다.
long count = emptyStream.count(); // count의 값은 0
ㅋㄷㅂㄹ ㄲ
#14-23~25
!스트림의 연산
-스트림이 제공하는 기능 - 중간 연산과 최종 연산
●중간 연산 - 연산결과가 스트림인 연산. 반복적으로 적용가능
●최종 연산 - 연산결과가 스트림이 아닌 연산. 단 한번만 적용가능(스트림의 요소를 소모)
(예시에 대한 설명은 영상강의 참조 00:50)
!스트림의 연산 - 중간 연산
(표는 영상강의 참조 02:50)
!스트림의 연산 - 최종 연산
(표는 영상강의 참조 06:15)
#14-26~29
!스트림의 중간연산(1/7)
-스트림 자르기 - 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/7)
-스트림의 요소 걸러내기 - filter(), distinct()
ㅋㄷㅂㄹ
Stream<T> filter (Predicate<? super T> predicate) // 조건에 맞지 않는 요소 제거
Stream<T> distinct()
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
IntStream.intStream = IntStream.of(1, 2, 2, 3, 3, 3, 4, 5, 5, 6);
intStream.distinct().forEach(System.out : : print); // 123456
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
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);
ㅋㄷㅂㄹ ㄲ
!스트림의 중간연산(3/7)
-스트림 정렬하기 - sorted()
ㅋㄷㅂㄹ
Stream<T> sorted() //스트림 요소의 기본 정렬(Comparable)로 정렬
Stream<T> sorted(Comparator<? super T> comparator) // 지정된 comparator로 정렬
ㅋㄷㅂㄹㄲ
(표는 영상강의 참조 05:40)
!스트림의 중간연산(4/7)
-Comparator의 comparing()으로 정렬 기준을 제공
ㅋㄷㅂㄹ
comparing(Function<T, U> keyExtractor)
comparing(Function<T, U> keyExtractor, Comparator<U> keyComparator)
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
studentStream.sorted(Comparator.comparing(Student : : getBan) ) // 반별로 정렬
.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(Student : : getBan) ) // 반별로 정렬
.thenComparing(Student : : getTotalScore) // 총점별로 정렬
.thenComparing(Student : : getName) // 이름별로 정렬
.forEach(System.out : : println) ;
ㅋㄷㅂㄹ ㄲ
#14-30~34
!스트림의 중간연산(5/7)
-스트림의 요소 반환하기 - map()
ㅋㄷㅂㄹ
Stream<R> map(Function<? super T,? extends R> mapper) //Stream<T> -> 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); // 스트림의 모든 파일의 이름을 출력
ㅋㄷㅂㄹ ㄲ
(예시와 Stream<File> → Stream<String>의 설명은 영상강의 참조 04:50)
!스트림의 중간연산(6/7)
-스트림의 요소를 소비하지 않고 엿보기 - peek()
ㅋㄷㅂㄹ
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.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); // 최종연산 스트림을 소비.
ㅋㄷㅂㄹ ㄲ
!스트림의 중간연산(7/7)
-스트림의 스트림을 스트림으로 변환 - flatMap()
ㅋㄷㅂㄹ
Stream<String[ ]> strArrStrm = Stream.of(new String[ ] { "abc", "def", "ghi" }
new String[ ] {"ABC", "GHI", "JKLMN"} );
ㅋㄷㅂㄹ ㄲ
ㅋㄷㅂㄹ
Stream<Stream<String>> strStrStrm = strArrStrm.map(Arrays : : stream);
ㅋㄷㅂㄹ ㄲ
(그림 설명은 영상강의 참조 14:00)
#14-35~39