2021. 6. 23. 06:00ใ๊ฐ๋ ์ ๋ฆฌ ์์ ์ค/Java
์๋ ํ์ธ์? ์ฃผ๋ํ๋ ์ ๋๋ค!
์ค๋์ Optional์ด๋ผ๋ ๊ธฐ๋ฅ์ ๋ํด์ ๊ณต๋ถ๋ฅผ ํ๋ฒ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
๊ทธ๋ผ ๋ฐ๋ก ์์ํ๊ฒ ์ต๋๋ค!
๐ Optional์ด๋?
๐ T Type ๊ฐ์ฒด์ ๋ํผํด๋์ค - Optional<T>
๋ํผ ํด๋์ค์ ๋ํด ์ ๋ชจ๋ฅด์ ๋ค๋ฉด ๋ํผ ํด๋์ค ํผ๋์ ๊ด์ฌ์ ์ฃผ์ธ์!
Public final class Optional<T> {
private final T value; // T ์๋ฃํ ํ์
์ ์ฐธ์กฐ ๋ณ์ Value ์ ์ธ
....
}
์ฌ๊ธฐ์ T ํ์ ์ ๋ชจ๋ ํ์ ์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ ์๊ณ , Null ๋ํ ์ ์ฅํ ์ ์๋ ๊ฒ์ด์์.
๐ Optional์ ์ฌ์ฉํ๋ ์ด์
๐ Null์ ์ง์ ๋ค๋ฃจ๋ ๊ฒ์ ์ํํ๊ธฐ ๋๋ฌธ
๐ฌ Null์ ์ ๋ชป ๋ค๋ฃจ๊ฒ ๋๋ฉด Null Point Exception์ด ๋ฐ์ํ๊ฒ ๋๋ ๊ฒ์ด์์! ๊ทธ๋์ ๊ฐ์ฒด์์ ๋ด์์ ๊ฐ์ ์ ์ผ๋ก Null์ ๋ค๋ฃจ๊ธฐ ์ํด ์ฌ์ฉํ๋ต๋๋ค!
๐ Null์ ์ง์ ๋ค๋ฃจ๊ฒ ๋๋ฉด Null Check ์ฌ์ฉ ํ์
๐ฌ Null Check ์ if๋ฌธ์ ํ์๋ก ์ฐ๊ฒ ๋๋๋ฐ, ์ด๋ ๊ฒ ๋๋ฉด ์ฝ๋๊ฐ ๊ธธ์ด์ง๋ ์ํฉ์ด ๋ฐ์ํ๊ฒ ๋๋ ๊ฒ์ด์์.
Object result = getResult();
์์ ์ฝ๋๊ฐ ์๋ค๊ณ ๊ฐ์ ํ ๋, ๋ฐํ๊ฐ์ ๋ ์ค์ ํ๋๊ฐ ๋์ค๊ฒ ๋ ๊ฒ์ด์์.
๐ฌ Null
๐ฌ ๊ฐ์ฒด
Null์ด ๋ฐํ๋๊ฒ ๋๋ค๋ฉด Null Point Exception์ด ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ if๋ฌธ์ ํตํด Null ์ฌ๋ถ๋ฅผ ๊ฒ์ฌํด ์ค์ผ ํ๋ ๊ฒ์ด์์.
if ( result != null ) { // Null Check if๋ฌธ
System.out.println( result.toString)
}
์ ์ฝ๋์ ๊ฐ์ด Null์ด ๋ฐํ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ ์ฝ๋๋ ์กฐ๊ฑด์์ ํตํด ๊ทธ ๊ฐ์ ๊ผญ ํ์ธ ํด ์ค์ผ ํ๋ ๊ฒ์ด์์.
optional์ ์ด์ฉํ๊ฒ ๋๋ฉด result์ Null์ด ๋ด๊ธธ ์ ์๋ ๊ฒ์ result ์์ optional์ ๋ฃ์ ๋ค ๊ทธ ์์ Null์ ๋ฃ์ผ๋ ค๊ณ ํ๋ ๊ฒ์ด์์.
๊ทธ๋ ๊ฒ ๋๋ฉด result๊ฐ ๋ฐ๋ผ๋ณด๋ optional์ ๋ฌด์กฐ๊ฑด ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ๊ฐ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ๊ฐ Null์ด๋๋ผ๋ result๋ ์ธ์ ๋ Null์ ๊ฐ์ ์ ์๊ฒ ๋๋ ๊ฒ์ด์์.
์ด๋ฌํ ์ด์ ๋ก Null Point Exception์ด๋, Null Check ๋จ๊ณ๊ฐ ์์ด์ง๊ฒ ๋๋ฏ๋ก, ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด ์ง๊ณ , Null์ ์ํ์ผ๋ก๋ถํฐ ์์ ๋ก์์ง ์ ์๋ต๋๋ค.
๐ Optional<T> ๊ฐ์ฒด ์์ฑ
String str = "abc";
Optional<String> optVal = Optional.of(str);
Optional<String> optVal = Optional.of("abc");
Optional<String> optVal = Optional.of(null); // Null Point Exception ๋ฐ์
Optional<String> optVal = Optional.ofNullable(null); // ์ ์
์ฒซ๋ฒ์งธ ์ฝ๋๊ฐ ์คํ๋๋ฉด optVal์ Optional ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ๊ฐ๊ฒ ๋ ๊ฒ์ด๊ณ , Optional ๊ฐ์ฒด optVal์๋ "abc"๊ฐ ๋ด๊ธด ์ฃผ์๊ฐ์ ๊ฐ๊ฒ ๋ ๊ฒ์ด์์. ๊ทธ๋์ ์ ์์ ๋๋ค.
๋๋ฒ์งธ ์ฝ๋๋ String str = "abc";์ ์ฒซ๋ฒ์งธ ์ฝ๋๋ฅผ ํฉ์น ์ฝ๋์ด๋ฉฐ, ์ด๊ฒ ์ญ์ ์ ์์ ๋๋ค.
์ธ๋ฒ์งธ ์ฝ๋๋ null์ ์ง์ ์ ์ฅํ๊ฒ ๋๋ฉด Null Point Exception์ด ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด์์.
Null์ผ ์ ์๋ ๊ฐ์ ๋ฃ๊ณ ์ถ๋ค๋ฉด ๋ค๋ฒ์งธ ์ฝ๋์ฒ๋ผ ofNullable์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ต๋๋ค!
๐ Null ๋์ ๋น Optional<T> ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ
Optional<String> optVal = null; // Null๋ก ์ด๊ธฐํ๋ฅผ ํ๋ ๊ฒ์ธ๋ฐ, ๊ฐ๋ฅํ์ง๋ง ๋ฐ๋์งํ์ง ์๋ค.
Optional<String> optVal = Optional.<String>empty(); // ๋น ๊ฐ์ฒด๋ก ์ด๊ธฐํ ๋ฐ๋์งํ๋ค.
// ' <String> '์ ์๋ต ๊ฐ๋ฅ
๐ Optional<T> ๊ฐ์ฒด์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
๐ Optional ๊ฐ์ฒด์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ - get(), orElse(), orElseGet(), orElseThrow()
Optional<String> optVal = Optional.of("abc");
String str1 = optVal.get(); // optVal์ ์ ์ฅ๋ ๊ฐ์ ๋ฐํ. Null์ผ ์ ์์ธ ๋ฐ์
String str2 = optVal.orElse(""); // optVal์ ์ ์ฅ๋ ๊ฐ์ด null์ผ ๋ ๊ทธ ๊ฐ์ ์๊ดํธ ์์ ๊ฐ์ผ๋ก ์นํํ์ฌ ์ฌ๊ธฐ์๋ ๊ณต๋ฐฑ์ ๋ฐํ
String str3 = optVal.orElseGet(String::new); // ๋๋ค์ ์ฌ์ฉ๊ฐ๋ฅ () -> new String()
String str4 = optVal.orElseThrow(NullPointerException::new) // Null์ด๋ฉด ์์ธ ๋ฐ์
orElseThorw() ์์ธ ์ข ๋ฅ๋ฅผ ์ง์ ๊ฐ๋ฅํ๋ต๋๋ค!
T orElseGet ( Supplier < ? extends T > other )
T orElseThrow ( Supplier < ? extends x > exceptionSupplier )
์์ ์ฝ๋๋ orElseGet๊ณผ orElseThrow๊ฐ ์ด๋ป๊ฒ ๊ตฌํ ๋์ด ์๋์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์๋ ๊ฒ์ด์์.
Supplier๋ ๋งค๊ฐ๋ณ์ ์์ด ๋ฐํ๋ง ์๋ ๊ฒ์ด์์.
๊ฒฐ๊ตญ str3 ๋ถ๋ถ์ () -> ( new String() ); ์ด๋ผ๊ณ ํํํ ์ ์๋ ๊ฒ์ด์์.
๐ isPresent() - Optional ๊ฐ์ฒด ๊ฐ์ด Null์ด๋ฉด false, ์๋๋ฉด True๋ฅผ ๋ฐํ
if ( Optional.ofNullable(str).isPresent() ) { // if ( str != null )
System.out.println(str);
}
// ifPresnt( Consumer ) - Null์ด ์๋๋๋ง ์์
์ ์ํ, Null์ด๋ฉด ์๋ฌด ์์
์์
Optional.ofNullable(str).ifPresent(System.out::println);
ifPresnet๋ Null์ด ์๋ ๋๋ง ์๊ดํธ ์์ ์์ ์ ์ํํ๋ ๊ฒ์ด์์.
๐ ์์ ์ฝ๋
class Optinal_ex {
public static void main(String[] args) {
int[] arr = {};
System.out.println("arr.lenth = " + arr.length); // ๊ฒฐ๊ณผ๋ 0
int[] arr = new int[0];
System.out.println("arr.lenth = " + arr.length); // ๊ฒฐ๊ณผ๋ 0
// Optional<String> opt = null; // Error๋ ๋์ง ์์ง๋ง, ๊ถ๊ณ ํ์ง ์์
Optional<String> opt = Optional.empty(); // ์ด๋ ๊ฒ ์ฐ๋ ๊ฒ์ด ์ข๋ค.
System.out.println(" opt = " + opt ); // ๊ฒฐ๊ณผ๋ Optional.empty
// System.out.println(" opt = " + opt.get() ); // NoSuchElementException ๋ฐ์ ๋ค์ด์๋ ๊ฐ์ด null์ด๊ธฐ ๋๋ฌธ์ ๋ฐ์
// ์์ ๊ฐ์ด ํ๊ณ ์ถ์ ๋๋ ์๋ ์ฝ๋๊ฐ ์ ์
String str = "";
// str = opt.get(); // ์์ธ ๋ฐ์
// try {
// str = opt.get();
// } catch (Exception e) {
// str = ""; // ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ๊ณต๋ฐฑ์ผ๋ก ์ด๊ธฐํ
// }
// System.out.println(" str = " + str ); // ๊ฒฐ๊ณผ๋ ์๋ฌด๊ฒ๋ ์ฐํ์ง ์๋๋ค.
// ์์ ๊ฐ์ด try-catch๋ฅผ ๊ฐ๋ตํ๊ฒ ์ธ ์ ์๋ ๋ฐฉ๋ฒ
str = opt.orElse(""); // Optional์ ์ ์ฅ๋ ๊ฐ์ด Null์ด๋ฉด ๊ณต๋ฐฑ ๋ฐํ
str = opt.orElseGet( () -> "EMPTY"); // ์ด๋ ๊ฒ ํ๋ฉด EMPTY๊ฐ ์ฐํ
System.out.println(" str = " + str );
}
}
๐ OptionalInt, OptionalLong, OptionalDouble
๐ ๊ธฐ๋ณธํ ๊ฐ์ ๊ฐ์ธ๋ ๋ํผ ํด๋์ค
public final class OptionalInt {
...
private final boolean isPresent; // ๊ฐ์ด ์ ์ฅ๋์ด ์๋ค๋ฉด? True๊ฐ ๋ฐํ
private final int value; // int ํ์
์ ๋ณ์
์์์ ์ด๊ฑฐํ OptionalInt, OptionLong, OptionalDouble ๋ฑ์ ์ฌ์ค Optional<T>๋ฅผ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํ ๊ฒ์ด์์.
ํ์ง๋ง, ์ ๊ฒ์ ์ฌ์ฉํ๋ ์ด์ ๋ ์ฑ๋ฅ! ๋ฐ๋ก ํผํฌ๋จผ์ค ๋๋ฌธ์ธ ๊ฒ์ด์์!
๐ OptionalInt์ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ - int getAsInt()
Optional Class | ๊ฐ์ ๋ฐํํ๋ Method |
Optional<T> | T get() |
OptionalInt | int getAsInt() |
OptionalLong | long getAsLong() |
OptionalDouble | double getAsDouble() |
๐ ๋น Optional ๊ฐ์ฒด์์ ๋น๊ต
OptionalInt opt = OptionalInt.of(0); // OptionalInt์ 0 ์ ์ฅ
OptionalInt opt2 = OptionalInt.empty(); // OptionalInt์ 0 ์ ์ฅ
์ฌ๊ธฐ์ empty๋ ์๋ฌด๊ฒ๋ ์ ์ฅํ์ง ์์ ๊ฒ์ ์๋ฏธํ๋ ๊ฒ์ด์์. ์ฆ, 0๊ณผ๋ ์ฌ์ค ์๋ฏธ๊ฐ ๋ค๋ฅด๋ค๊ณ ๋ด์ผ ํ๋ ๊ฒ์ด ๋ง๊ฒ ์ง์?
๊ทธ๋ผ ์ด๊ฑธ ์ด๋ป๊ฒ ๊ตฌ๋ณํ ์ ์์๊น์? ์ด๊ฒ์ ๊ตฌ๋ณํ๊ธฐ ์ํด isPresent()๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด์์.
System.out.println( opt.isPresent() ); // True
System.out.println( opt2.isPresent() ); // False
System.out.println( opt.equals( opt2 ); // False
๋๊ฐ์ด 0์ด๋ผ๋ ๊ฐ์ด ์ ์ฅ๋๋๋ผ๋ ์์ opt์๋ 0์ด๋ผ๋ ์ ์๊ฐ ์ ์ฅ๋์ด ์๋ ๊ฒ์ด๊ณ , isPresent()์์ True๋ฅผ ๋ฐํํ๋ ๊ฒ์ด์์.
ํ์ง๋ง, opt2์๋ 0์ด๊ธด 0์ธ๋ฐ, ์ ์ 0์ด๋ผ๊ณ ํ๊ธฐ์ ์ ๋งคํ empty๊ฐ ์ ์ฅ๋์ด ์๋ ๊ฒ์ด๊ณ , isPresent()์์ Flase๋ฅผ ๋ฐํํ๋ ๊ฒ์ด์์. ๊ฒฐ๊ตญ opt2๋ ์๋ฌด๊ฒ๋ ์ ์ฅํ์ง ์์๋ค๋ผ๊ณ ๋ณด๋ ๊ฒ์ด ๋ง์์!
๐ ์์ ์ฝ๋
import java.util.*;
class optional_Ex1 {
// abced๋ผ๋ ๊ฐ์ ๊ฐ๋ Optional ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , abced๊ฐ ๋ฌธ์์ด ์ด๊ธฐ ๋๋ฌธ์ <String>์ผ๋ก ์์ฑ
Optional<String> optStr = Optional.of( "abcde" );
// Optional ๋ํ map์ด๋ผ๋ Method๋ฅผ ๊ฐ๊ณ ์์ด Optional์ map์ผ๋ก ๋ณํํ ๋ค ๊ฐ์ length๋ก ๋ณํํ๋ค.
// length๋ ์ ์์ด๋ฏ๋ก, <Integer>๋ก ๋ฐ๊ฟ์ค๋ค.
Optional<Integer> optInt = optStr.map(String::length);
// ์์ ์ฝ๋๋ฅผ ๋๋ค์์ผ๋ก ๋ฐ๊พธ๋ฉด?
Optional<Integer> optInt = optStr.map( s -> s.length() );
System.out.println( " optStr = " + optstr.get() ); // ๊ฒฐ๊ณผ optStr = abcde
System.out.println( " optInt = " + optstr.get() ); // ๊ฒฐ๊ณผ optInt = 5
int result1 = Optional.of( "123" )
// fileter๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด 133์ ๊ธธ์ด๊ฐ 0๋ณด๋ค ํฐ์ง ํ์ธํ๋ค.
.filter( x -> x.length() > 0 )
// parseInt๋ฅผ ํตํด ๋ฌธ์์ด 123์ ์ ์ 123์ผ๋ก ๋ณํ์์ผ ์ค๋ค.
.map( Integer::parseInt ).get();
int result2 = Optional.of("")
.filter( x -> x.length() > 0 )
.map( Integer::parseInt).orElse(-1);
System.out.println( " result1 = " + result1 ); // ๊ฒฐ๊ณผ result1 = 123
System.out.println( " result2 = " + result2 ); // ๊ฒฐ๊ณผ result2 = -1
Optional.of( "456" ).map( Integer::parseInt)
.ifPresent( x -> System.out.printf( " result3 = %d%n", x ) ); // ๊ฒฐ๊ณผ result3 = 456
OptionalInt optInt1 = OptionalInt.of(0); // 0์ ์ ์ฅ isPresent = True
OptionalInt optInt2 = OptionalInt.empty(); // ๋น ๊ฐ์ฒด ์์ฑ ifPresent = False
System.out.println( " optInt1.ispresent() ); // ๊ฒฐ๊ณผ true
System.out.println( " optInt2.isPresent() ); // ๊ฒฐ๊ณผ false
System.out.println( " optInt1.getAsInt() ); // ๊ฒฐ๊ณผ 0
System.out.println( " optInt2.getAsInt() ); // ๊ฒฐ๊ณผ NoSuchElementException
System.out.println( " optInt1 = " + optInt1 ); // ๊ฒฐ๊ณผ optInt1 = OptionalInt[0]
System.out.println( " optInt2 = " + optInt2 ); // ๊ฒฐ๊ณผ optInt2 = OptionalInt.empty
System.out.println( " optInt1.equals( optInt2) ? " + optInt1.equals( optInt2 ) ); // ๊ฒฐ๊ณผ optInt1.equals( optInt2 ) ? false
์ฃผ๋ํ๋์ ๊ธ์ด ๋ง์์ ๋์ จ๋์? ๊ตฌ๋ ๊ณผ ๊ณต๊ฐ! ๊ทธ๋ฆฌ๊ณ , ๋๊ธ์ ์ฃผ๋ํ๋์๊ฒ ๋ง์ ํ์ด ๋ฉ๋๋ค!
'๊ฐ๋ ์ ๋ฆฌ ์์ ์ค > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] ๋คํ์ฑ(polymorphism) (0) | 2021.09.18 |
---|---|
[JAVA] Class Method(static Method)์ ์ธ์คํด์ค Method (0) | 2021.09.13 |
[Java] Wrapper Class (0) | 2021.06.22 |
[JAVA] ํจ์ํ ์ธํฐํ์ด์ค (0) | 2021.06.21 |
[Java] Lamda Function (0) | 2021.06.21 |