ch 14-35~39 Optional< T >
Optional< T >
- T타입 객체의 래퍼클래스 - Optional< T >
public final class Optional<T> {
private final T value; // T타입의 참조변수 (모든 종류의 객체,null을 저장할 수 있다.)
...
}
- Object result = getResult()의 값은 null 혹은 객체
- null을 직접 다루는 것은 위험하다.(NullPointerException 발생 위험이 있다.) 그래서 간접적으로 null을 다루기 위해 Optional을 사용한다.
- null체크를 위해서는 if문이 필수다. 그렇게 되면 코드가 지저분해지므로 Optional을 통해 간접적으로 null을 다룬다.
- String str = "" (null을 빈 문자열로 써서 간접적으로 다룬다.)
Optional< T >객체 생성하기
- Optional< T >객체를 생성하는 다양한 방법
String str = "abc";
Optional<String> optVal = Optional.of(str);
Optional<String> optVal = Optional.of("abc");
Optional<String> optVal = Optional.of(null); // NullPointerException발생
Optional<String> optVal = Optional.ofNullable(null); // OK
- null대신 빈 Optional< T > 객체를 사용하자
Optional<String> optVal = null; // 널로 초기화. 바람직하지 않음
Optional<String> optVal = Optional.<String>empty(); // 빈 객체를 초기화
Optional< T >객체의 값 가져오기
- Optional객체의 값 가져오기 - get(), orElse(), orElseGet(), orElseThrow()
T orElseGet (Supplier<? extends T> other)
T orElseThrow (Supplier<? extends X> exceptionSupplier)
- isPresent() - Optional객체의 값이 null이면 false, 아니면 true를 반환
if(Optional.ofNullabe(str).isPresent()) { // if(str!=null) {
System.out.println(str);
}
// ifPresent(Consumer) - 널이 아닐때만 작업 수행, 널이면 아무 일도 안 함
Optional.ofNullable(str).ifPresent(System.out::println);
OptionalInt, OptionalLong, OptionalDouble
public final class OptionalInt {
...
private final boolean isPresent; // 값이 저장되어 있으면 true
private final it value; // int타입의 변수
- OptionalInt의 값 가져오기 - int getAsInt()
- 빈 Optional객체와의 비교
OptinalInt opt = OptionalInt.of(0); // OptionalInt에 0을 저장
OptianlInt opt2 = OptionalInt.empty(); // OoptionalInt에 0을 저장
System.out.println(opt.isPresent()); // ture
System.out.println(opt2.isPresent()); // false
System.out.println(opt.equals(opt2)); // false
ch 14-40~44 스트림의 최종연산
스트림의 최종연산 - forEach()
- 스트림의 모든 요소에 지정된 작업을 수행 - forEach(), forEachOrdered()
void forEach(Consumer<? super T> action) // 병렬스트림인 경우 순서가 보장되지 않음
void forEachOrdered(Consumer<? super T> action) // 병렬스트림인 경우에도 순서가 보장됨
* 스트림 작업을 직렬로 처리
IntStream.range(1, 10).sequential().forEach(System.out::print); // 123456789
IntStream.range(1, 10).sequential().forEachOrdered(System.ot::print); // 123456789
* 스트림 작업을 병렬로 처리 (여러 쓰레드가 나눠서 작업 처리)
IntStream.range(1, 10).parallel().forEach(System.out::print); // 683295714 (순서보장X)
IntStream.range(1, 10).parallel().forEachOrdered(System.ot::print); // 123456789
스트림의 최종연산 - 조건 검사
- 조건 검사 - allMatch(), anyMatch(), noneMatch()
boolean allMatch (Predicate<? super T> predicate) // 모든 요소가 조건을 만족시키면 true
boolean anyMatch (Predicate<? super T> predicate) // 한 요소라도 조건을 만족시키면 true
boolean noneMatch (Predicate<? super T> predicate) // 모든 요소가 조건을 만족시키지 않으면 true
boolean hasFailedStu - stuStream.anyMtch(s->s.getTotalScore()<=100); // 낙제자가 있는지?
- 조건에 일치하는 요소 찾기 - findFirst(), findAny()
Optional<T> findFirst() // 첫 번째 요소를 반환. 순차 스트림에 사용 (결과가 null일 수 있음)
Optional<T> findAndy() // 아무거나 하나를 반환. 병럴 스트림에 사용
Optional<Student> result = stuStream.filter(s->s.getTotalScore() <= 100).findFirst();
Optional<Student> result = parallelStream.filter(s->s.getTotalScore() <= 100).findAny();
스트림의 최종연산 - reduce()
- 스트림의 요소를 하나씩 줄여가며 누적연산(accumulator) 수행 - reduce()
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator>
U reduce(U identity, BiFunction<U,T,U> accumulator, BinaryOperatoro<U> combiner)
* iendtity - 초기값
* accumulator - 이전 연산결과와 스트림의 요소에 수행할 연산
* combiner - 병렬 처리된 결과를 합치는데 사용할 연산(병렬 스트림)
// int reduce(int identity, IntBinaryOperator op)
int count = intStream.reduce(0, (a,b) -> a + 1); // count()
int sum = intStream.reduce(0, (a,b) -> a + b); // sum()
int max = intStream.reduce(Integer.MIN_VALUE, (a,b) -> a > b ? a : b); // max()
int min = intStream.reduce(Integer.MAX_VALUE, (a,b) -> a < b ? a : b); // min()
int a = identity;
for(int b : stream)
a = a + b; // sum()