
package me.whiteship.chapter08.item55;
import java.util.*;
// 반환 타입으로 Optional<T> 사용하기 (327-328쪽)
public class Max {
// 코드 55-1 컬렉션에서 최댓값을 구한다. - 컬렉션이 비었으면 예외를 던진다. (327쪽)
// public static <E extends Comparable<E>> E max(Collection<E> c) {
// if (c.isEmpty())
// throw new IllegalArgumentException("빈 컬렉션");
//
// E result = null;
// for (E e : c)
// if (result == null || e.compareTo(result) > 0)
// result = Objects.requireNonNull(e);
//
// return result;
// }
// 코드 55-2 컬렉션에서 최댓값을 구해 Optional<E>로 반환한다. (327쪽)
public static <E extends Comparable<E>>
Optional<E> max(Collection<E> c) {
if (c.isEmpty())
return Optional.empty();
E result = null;
for (E e : c)
if (result == null || e.compareTo(result) > 0)
result = Objects.requireNonNull(e);
return Optional.of(result);
}
// // 코드 55-3 컬렉션에서 최댓값을 구해 Optional<E>로 반환한다. - 스트림 버전 (328쪽)
// public static <E extends Comparable<E>>
// Optional<E> max(Collection<E> c) {
// return c.stream().max(Comparator.naturalOrder());
// }
public static void main(String[] args) {
List<String> words = Arrays.asList("args", "args2", "args3");
// 코드 55-4 옵셔널 활용 1 - 기본값을 정해둘 수 있다. (328쪽)
String lastWordInLexicon = max(words).orElse("단어 없음...");
System.out.println(lastWordInLexicon);
}
}
없을 경우에는 Optional.empty()를 주고, 잇는 경우에는 Optional.of에다 넣어준다.
null이 들어가는 경우 Optional.ofNullable로 사용가능하다.

에러를 나오게 하려면 orElseThrow를 사용할 수도 있다.
반드시 값이 있을 것이라 믿으면 .get()을 사용 가능하다.

이렇게 stream으로 사용도 가능하다.
null을 return하지는 말자.
핵심 정리 2: Optional<T>

package me.whiteship.chapter08.item55;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.Stream;
// 불필요하게 사용한 Optional의 isPresent 메서드를 제거하자. (329쪽)
public class ParentPid {
public static void main(String[] args) {
ProcessHandle ph = ProcessHandle.current();
// isPresent를 적절치 못하게 사용했다.
Optional<ProcessHandle> parentProcess = ph.parent();
System.out.println("부모 PID: " + (parentProcess.isPresent() ?
String.valueOf(parentProcess.get().pid()) : "N/A"));
// 같은 기능을 Optional의 map를 이용해 개선한 코드
System.out.println("부모 PID: " +
ph.parent().map(h -> String.valueOf(h.pid())).orElse("N/A"));
// p329 Optional의 스트림
Stream<Optional<String>> streamOfOptionals = Stream.of(
Optional.of("Apple"),
Optional.empty(),
Optional.of("Banana"),
Optional.of("Cherry"),
Optional.empty()
);
// isPresent를 적절치 못하게 사용했다.
// streamOfOptionals.filter(Optional::isPresent)
// .map(Optional::get)
// .forEach(System.out::println);
// 같은 기능을 Optional의 스트림을 이용해 개선한 코드
streamOfOptionals.flatMap(Optional::stream)
.forEach(System.out::println);
}
}
isPresnet 값이 있으면, 없으면
map은 해당 값을 맵핑할수도 있다.
flatMap은 optional들을 값이 있으면 그 값을 원소로 담은 스트림으로, 없으면 값이 없는 빈 stream으로 바꿔준다.

OptionalInt 는 int -> Optional로 감쌀 수 있다.