Notice
Recent Posts
Link
Today
Total
10-06 00:17
๊ด€๋ฆฌ ๋ฉ”๋‰ด

dingdong coding

[ JAVA ] Optional ๋ณธ๋ฌธ

๐ŸฐJAVA/Basic

[ JAVA ] Optional

๐Ÿถ ๊ฐœ๋ฐœ๊ฐœ๋ฐœ ๐Ÿพ 2022. 6. 15. 11:23

Optional ์ด๋ž€? 

๊ฐœ๋ฐœ์„ ํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ ์ค‘ ํ•˜๋‚˜๋Š” ๋ฐ”๋กœ  NullPointerException ์ž…๋‹ˆ๋‹ค. NullPointerException ์„ ํ”ผํ•˜๊ณ  null ์ฒดํฌํ•˜๋Š” ๋กœ์ง์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋นˆ ๊ฐ’์ผ ๋•Œ null ๋Œ€์‹  ์ดˆ๊ธฐ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธธ ๊ถŒ์žฅํ•˜๊ณค ํ•ฉ๋‹ˆ๋‹ค.

List<String> names = getNames();
names.sort(); // names ๊ฐ€ null ์ด๋ผ๋ฉด NullPointerException ์ด ์ผ์–ด๋‚œ๋‹ค.

์ž๋ฐ” 8์—์„œ๋Š” Optional<T> ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•ด์„œ NullPointerException ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฆ‰, ๋ณต์žกํ•œ ์กฐ๊ฑด๋ฌธ ์—†์ด๋„ ๋„(null) ๊ฐ’์œผ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

public final class Optional<T> {

  // If non-null, the value; if null, indicates no value is present
  private final T value;
  
  ...
}

value ์— ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์ด null ์ด๋”๋ผ๋„ ๋ฐ”๋กœ ์ฐธ์กฐ ์‹œ NullPointerException ๊ฐ€ ๋‚˜์ง€ ์•Š๊ณ , ํด๋ž˜์Šค์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ์ข… ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•ด์ค๋‹ˆ๋‹ค.

 

Optional<T> ํด๋ž˜์Šค

Integer๋‚˜ Double ํด๋ž˜์Šค์ฒ˜๋Ÿผ 'T'ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ํฌ์žฅํ•ด ์ฃผ๋Š” ๋ž˜ํผ ํด๋ž˜์Šค(Wrapper class)์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Optional ์ธ์Šคํ„ด์Šค๋Š” ๋ชจ๋“  ํƒ€์ž…์˜ ์ฐธ์กฐ ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Optional ๊ฐ์ฒด์˜ ์ƒ์„ฑ

1. Optional.empty() ๋นˆ ๊ฐ์ฒด ์ƒ์„ฑ 

Optional<String> optional = Optional.empty();
System.out.println(optional); // Optional.empty

System.out.println(optional.isPresent()); // false

 

2. of() , ofNullable() 

 

 of() ๋ฉ”์†Œ๋“œ : null์ด ์•„๋‹Œ ๋ช…์‹œ๋œ ๊ฐ’์„ ๊ฐ€์ง€๋Š” Optional ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

      of() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ Optional ๊ฐ์ฒด์— null์ด ์ €์žฅ๋˜๋ฉด NullPointerException ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ

// Optional์˜ value๋Š” ์ ˆ๋Œ€ null์ด ์•„๋‹ˆ๋‹ค.
Optional<String> optional = Optional.of("MyName");

 

 ofNullable() ๋ฉ”์†Œ๋“œ : ์ฐธ์กฐ ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ๋งŒ์— ํ•˜๋‚˜ null์ด ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์„ ๋•Œ ์‚ฌ์šฉ

     ๋ช…์‹œ๋œ ๊ฐ’์ด null์ด ์•„๋‹ˆ๋ฉด ๋ช…์‹œ๋œ ๊ฐ’์„ ๊ฐ€์ง€๋Š” Optional ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜

     ๋ช…์‹œ๋œ ๊ฐ’์ด null์ด๋ฉด ๋น„์–ด์žˆ๋Š” Optional ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

// Optional ์•ˆ์—๋Š” ๊ฐ’์ด ์žˆ์„ ์ˆ˜๋„ ์žˆ๊ณ  ๋นˆ ๊ฐ์ฒด์ผ ์ˆ˜๋„ ์žˆ๋‹ค.
Optional<String> optional = Optional.ofNullable(getString());

String result = optional.orElse("other"); // ๊ฐ’์ด ์—†๋‹ค๋ฉด "other" ๋ฅผ ๋ฆฌํ„ด

Optional ๊ฐ์ฒด์— ์ ‘๊ทผ

1. get() : Optional ๊ฐ์ฒด์— ์ €์žฅ๋œ ๊ฐ’์— ์ ‘๊ทผ

     ๋งŒ์•ฝ Optional ๊ฐ์ฒด์— ์ €์žฅ๋œ ๊ฐ’์ด null์ด๋ฉด, NoSuchElementException ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ get() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— isPresent() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Optional ๊ฐ์ฒด์— ์ €์žฅ๋œ ๊ฐ’์ด null์ธ์ง€ ์•„๋‹Œ์ง€๋ฅผ ๋จผ์ € ํ™•์ธํ•œ ํ›„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Optional<String> opt = Optional.ofNullable("์ž๋ฐ” Optional ๊ฐ์ฒด");

if(opt.isPresent()) {
    System.out.println(opt.get()); //์ž๋ฐ” Optional ๊ฐ์ฒด
}

 

2. orElse(), orElseGet(), orElseThrow() : null ๋Œ€์‹ ์— ๋Œ€์ฒดํ•  ๊ฐ’์„ ์ง€์ •

 

 orElse() ์ €์žฅ๋œ ๊ฐ’์ด ์กด์žฌํ•˜๋ฉด ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜

 orElseGet()  ์ €์žฅ๋œ ๊ฐ’์ด ์กด์žฌํ•˜๋ฉด ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๋žŒ๋‹ค ํ‘œํ˜„์‹์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜

orElseThrow()  ์ €์žฅ๋œ ๊ฐ’์ด ์กด์žฌํ•˜๋ฉด ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ด.

Optional<String> opt = Optional.empty(); // Optional๋ฅผ null๋กœ ์ดˆ๊ธฐํ™”ํ•จ.

System.out.println(opt.orElse("๋นˆ Optional ๊ฐ์ฒด")); //๋นˆ Optional ๊ฐ์ฒด
System.out.println(opt.orElseGet(String::new));

Optional ์‚ฌ์šฉํ•˜๊ธฐ

๋จผ์ € ์ž๋ฐ” 8 ์ด์ „์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด null ์ฒดํฌ๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

// ์ž๋ฐ” 8 ์ด์ „
List<String> list = getList();
List<String> listOpt = list != null ? list : new ArrayList<>();

 

Optional<T> ๊ณผ Lambda ๋ฅผ ์ด์šฉํ•˜๋ฉด ์ข€ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

List<String> listOpt = Optional.ofNullable(getList()).orElseGet(() -> new ArrayList<>());

 

null ์ฒดํฌ๋กœ ์ธํ•ด  ์ง€์ €๋ถ„ํ•ด์ง„ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

User user = getUser();
if (user != null) {
  Address address = user.getAddress();
  if (address != null) {
    String street = address.getStreet();
    if (street != null) {
      return street;
    }
  }
}
return "์ฃผ์†Œ ์—†์Œ";

 

map ๋ฉ”์†Œ๋“œ

 ๊ฐ’์ด null  ์•„๋‹Œ ๊ฒฝ์šฐ : mapper ๋ฅผ ์ด์šฉํ•ด ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” Optional ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

 ๊ฐ’์ด null ์ธ ๊ฒฝ์šฐ  : ๋นˆ Optional ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)

 

map ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Optional<User> user = Optional.ofNullable(getUser());
Optional<Address> address = user.map(User::getAddress);
Optional<String> street = address.map(Address::getStreet);
String result = street.orElse("์ฃผ์†Œ ์—†์Œ");

// ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ•์•ฝํ•ด์„œ ์“ธ ์ˆ˜ ์žˆ๋‹ค.
user.map(User::getAddress)
    .map(Address::getStreet)
    .orElse("์ฃผ์†Œ ์—†์Œ");

 

+ Optional์˜ ํŠน์„ฑ์ƒ ์ž˜๋ชป์‚ฌ์šฉํ•˜๋ฉด ์‹œ์Šคํ…œ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋˜๊ธฐ๋„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์—  null์ด ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์•„์ฃผ ๋†’์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. 

 

ํ•™์Šต์— ๋งŽ์ด ๋„์›€์ด ๋œ ๋ธ”๋กœ๊ทธ ๋งํฌ๋ฅผ  ์ฐธ์กฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ™‚

 

์ฐธ์กฐ ๋ฐ ์ถœ์ฒ˜

Optional ํด๋ž˜์Šค

Optional์ด๋ž€? Optional ๊ฐœ๋… ๋ฐ ์‚ฌ์šฉ๋ฒ•

์˜ต์…”๋„ Optional

'๐ŸฐJAVA > Basic' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[JAVA ] List Interface  (0) 2022.06.20
[JAVA ] Collection  (0) 2022.06.20
[ JAVA ] Lambda  (0) 2022.06.14
[ JAVA ] HashMap  (0) 2022.06.14
[ JAVA, DB ์œ„์ฃผ ] ๊ฐœ๋ฐœ ๊ด€๋ จ ์šฉ์–ด ์ •๋ฆฌ ( ๊ฐœ์ธ ํ•™์Šต์šฉ )  (0) 2022.06.14
Comments