item 55 JungHyunLyoo - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
- throw Exception
- null ๋ฐํ
์์ธ๋ ์ง์ง ์์ธ์ ์ธ ์ํฉ์์๋ง ์ฌ์ฉํด์ผ ํ๋ฉฐ(item 69) ์์ธ๋ฅผ ์์ฑํ ๋ ์คํ ์ถ์ ์ ์ฒด๋ฅผ
์บก์ฒํ๊ธฐ ๋๋ฌธ์ ๋น์ฉโ
null์ ๋ฐํํ๋ฉด ํด๋ผ์ด์ธํธ์์ ๋ถ๋ดโ
- Optional ๋ฐํ
String str = "hello";
Optional<String> o = Optional.ofNullable(str); // str์ด null์ด๋ฉด ๋น Optional ๊ฐ์ฒด ๋ฐํ
Optional๋ null์ด ์๋ Tํ์ ์ฐธ์กฐ๋ฅผ ํ๋ ๋ด๊ฑฐ๋, ํน์ ์๋ฌด๊ฒ๋ ๋ด์ง ์์ ์ ์๋ค.
Optional์ ์์๋ฅผ ์ต๋ 1๊ฐ ๊ฐ์ง ์ ์๋ '๋ถ๋ณ' ์ปฌ๋ ์ ์ด๋ค.
item30์ ์๋์ ์ฝ๋๊ฐ ์์๋ค.
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;
}
Optional์ ์ด์ฉํ์ฌ ์ด๋ ๊ฒ ๋ณํํ ์ ์๋ค.
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);//์ ์ ํ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋ ์ฌ์ฉ
}
์ ์ฝ๋๋ฅผ ์คํธ๋ฆผ์ ์ด์ฉํด ๋ ์งง๊ฒ ๋ณํํ ์ ์๋ค.
์คํธ๋ฆผ์ ์ข ๋จ ์ฐ์ฐ ์ค ์๋น์๊ฐ ์ต์ ๋์ ๋ฐํํ๊ธฐ ๋๋ฌธ!
public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) {
return c.stream().max(Comparator.naturalOrder());
}
Optional์ ๋ฐํ๊ฐ์ด ์์ ์๋ ์์์ API ์ฌ์ฉ์์๊ฒ ๋ช ํํ ์๋ ค์ค๋ค.
์ฌ์ฉ์๊ฐ ๋ฐํ๊ฐ์ด ์์ ๊ฒฝ์ฐ๋ฅผ ํ์๋ก ๋๋นํด์ผ ํ ๋ Optional์ ์ฌ์ฉํ๋ฉด ์ข์ ๊ฒ์ด๋ค.
์๋๋ Optional์ ๋ฐํ๋ฐ์ ์ฌ์ฉ์๊ฐ ์ทจํ ์ ์๋ ์์์ด๋ค.
- ๊ธฐ๋ณธ๊ฐ ์ ํ๊ธฐ
String str = max(words).orElse("no words");
- ์์ธ ๋์ง๊ธฐ
Toy myToy = max(toys).orElseThrow(SimpleException::new);
//์์ธ ํฉํฐ๋ฆฌ ์ ๋ฌ. ์ค์ ๋ก ์์ธ๊ฐ ์ผ์ด๋์ง ์์ผ๋ฉด ์์ธ ์์ฑ ๋น์ฉ์ ๋ค์ง ์์
- ๊ฐ์ด ์ฑ์์ ธ ์๋ค๊ณ ๊ฐ์ ํ๊ธฐ
Element lastNobleGas = max(Elements.NOBLE_GASES).get();
๊ทธ๋ฐ๋ฐ ๋๋๋ก ๊ธฐ๋ณธ๊ฐ์ ์ ํด๋๋ ๋น์ฉ์ด ๋ถ๋ด๋ ์๊ฐ ์๋ค.
๊ทธ๋ด ๋ Supplier๋ฅผ ์ธ์๋ก ๋ฐ๋ orElseGet์ ์ฌ์ฉํ๋ฉด ๊ทธ ๋น์ฉ์ ๋ฎ์ถ ์ ์๋ค.
์๋ํ๋ฉด ๊ธฐ๋ณธ๊ฐ์ด ์ฒ์ ํ์ํ ๋, Supplier๋ฅผ ์ฌ์ฉํด ์์ฑํ๊ธฐ ๋๋ฌธ.
Supplier๋ Optional์ด null์ผ ๋๋ง ์คํ๋๋ค!
private static String wontRunThis() {
System.out.println("Won't run this");
return "foo";
}
public void optional1() {
String o = Optional.of("Hello World!").orElse(wontRunThis());
System.out.println("Result : " + o);
}
Won't run this
Result : Hello World!
private static String wontRunThis() {
System.out.println("Won't run this");
return "foo";
}
public void optional2() {
String o = Optional.of("Hello World!").orElseGet(() -> wontRunThis());
System.out.println("Result : " + o);
}
Result : Hello World!
์ถ์ฒ https://itstory.tk/entry/Java-8-OptionalorElse-vs-OptionalorElseGet [๋'s IT Story]
์์์ ๊ธฐ๋ณธ ๋ฉ์๋๋ก ์ฒ๋ฆฌํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ, filter, map, flatMap, ifPresent ๋ฑ์ ๊ณ ๊ธ ๋ฉ์๋๋ค๋ก
์ ์ ํ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ตํ์ ์๋จ์ผ๋ก isPresent๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
ํ์ง๋ง ์ฌ๋งํ๋ฉด ์ด ๋ฉ์๋๋ค ๋ง๊ณ ์๋จ์ ๋์ด๋ ๋ฉ์๋๋ฅผ ํตํด ์ฒ๋ฆฌํ์.
๊ทธ๊ฒ์ด ๋ ์งง๊ณ ๋ช ํํ๊ณ ์ฉ๋ฒ์ ๋ง๋ ์ฝ๋์ด๋ค. ์๋์ ์ฝ๋๋ isPresent๊ฐ ์ฌ์ฉ๋ ์์์ด๋ค.
Optional<ProcessHandle> parentProcess = ph.parent();
System.out.println(
"๋ถ๋ชจ PID: " + (parentProcess.isPresent() ?
String.valueOf(parentProcess.get().pid()) : "N/A")
);
์ด ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ด ๋ค๋ฌ์ ์ ์๋ค.
System.out.println("๋ถ๋ชจ PID: " +
ph.parent().map(h -> String.valueOf(h.pid())).orElse("N/A"));
์คํธ๋ฆผ์ ์ฌ์ฉํ ์ ์๋ java 8์์๋ ์ด๋ ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ๋ ๋ง๋ค.
streamOfOptionals.filter(Optional::isPresent).map(Optional::get)
java 9์์๋ Optional์ stream() ๋ฉ์๋๊ฐ ์ถ๊ฐ๋์๋ค.
streamOfOptionals.flatMap(Optional::stream)
๋ฐ์ฑ๋ ๊ธฐ๋ณธ ํ์ ์ ๋ด๋ ์ต์ ๋์ ๊ธฐ๋ณธ ํ์ ์์ฒด๋ณด๋ค ๋ฌด๊ฒ๋ค. ๋ ๊ฒน์ด๋ ๊ฐ์ธ๊ธฐ ๋๋ฌธ.
๊ทธ๋์ ์๋ฐ API ์ค๊ณ์๋ int, long, double ์ ์ฉ Optional class๋ค์ ์ค๋นํด๋จ๋ค.
- OptionalInt
- OptionalLong
- OptionalDouble
์ด ํด๋์ค๋ค๋ Optional๊ฐ ์ ๊ณตํ๋ ๋ฉ์๋๋ฅผ ๊ฑฐ์ ๋ค ์ ๊ณตํ๋ค.
๋จ '๋ ์ค์ํ ๊ธฐ๋ณธ ํ์ '์ฉ์ธ Boolean, Byte, Character, Short, Float์ ์์ธ๋ผ๊ณ ํ๋ค.
์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด, Map ์์ ํค๊ฐ ์๋ค๋ ์ฌ์ค์ ๋ํ๋ด๋ ๋ฐฉ๋ฒ์ด ๋๊ฐ์ง๊ฐ ๋๋ค.
- key ์์ฒด๊ฐ ์๋ ๊ฒฝ์ฐ
- value๊ฐ ๋น Optional์ธ ๊ฒฝ์ฐ
์ธ๋ฐ์์ด ๋ณต์ก์ฑ๋ง ๋์ฌ์ ํผ๋๊ณผ ์ค๋ฅ ๊ฐ๋ฅ์ฑ์ ํค์ธ ๋ฟ์ด๋ค.
Optional์ ์ปฌ๋ ์ ์ key, value๋ ๋ฐฐ์ด์ ์์๋ก ์ฌ์ฉํ๋ ๊ฒ ์ ์ ํ ์ํฉ์ ๊ฑฐ์ ์๋ค.