1. ํ™•์ธ

๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ํ•จ๊ป˜ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๋ฐ ์ด๋ฏธ ์ง€๋ฃจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์นจ๋‚ด ๋ฐ์ดํ„ฐ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ด Streamํด๋ž˜์Šค์—๋Š” ์ŠคํŠธ๋ฆผ์„ ๊ตฌ์„ฑํ•˜์ง€ ์•Š๊ณ  ์ŠคํŠธ๋ฆผ์— ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ํ‘œ์ค€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฉ”์„œ๋“œ๋Š” anyMatch(), allMatch()๋ฐ ์ž…๋‹ˆ๋‹ค noneMatch().

boolean anyMatch(rule)๋ฐฉ๋ฒ•

์ด ๋ฉ”์„œ๋“œ๋Š” ์ŠคํŠธ๋ฆผ์— ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌ๋œ ๊ทœ์น™์„ ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ๊ฐ€ ํ•˜๋‚˜ ์ด์ƒ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌํ•œ ์š”์†Œ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฉ”์„œ๋“œ๋Š” ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  true๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค false.

์˜ˆ

์•”ํ˜ธ ๋ฉ”๋ชจ
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).anyMatch(x -> x > 0);

false

๋งˆ์ง€๋ง‰ ์˜ˆ์—์„œ๋Š” ๋จผ์ € 0๋ณด๋‹ค ์ž‘์€ ์š”์†Œ๋งŒ ์œ ์ง€ํ•œ ๋‹ค์Œ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜์—ฌ ํ•„ํ„ฐ๋ง๋œ ์š”์†Œ ์ค‘ 0๋ณด๋‹ค ํฐ ๊ฒƒ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๊ทธ๋Ÿฌํ•œ ์š”์†Œ๋Š” ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ถ€์šธ allMatch(rule) ๋ฉ”์„œ๋“œ

์ด ๋ฉ”์„œ๋“œ๋Š” ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๊ฐ€ ๊ทœ์น™(์กฐ๊ฑด์ž๋ผ๊ณ ๋„ ํ•จ)๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ทœ์น™์€ ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

์•”ํ˜ธ ๋ฉ”๋ชจ
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(0๋ณด๋‹ค ํฐ ๋ชจ๋“  ์š”์†Œ)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(0๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(์šฐ๋ฆฌ๋Š” 0๋ณด๋‹ค ์ž‘์€ ์š”์†Œ๋ฅผ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค)

๋งˆ์ง€๋ง‰ ์˜ˆ์—์„œ๋Š” ๋จผ์ € 0๋ณด๋‹ค ์ž‘์€ ์š”์†Œ๋งŒ ํ•„ํ„ฐ๋ฅผ ํ†ต๊ณผํ•˜๋„๋ก ํ—ˆ์šฉํ•œ ๋‹ค์Œ ์œ ์ง€๋œ ๋ชจ๋“  ์š”์†Œ๊ฐ€ 0๋ณด๋‹ค ์ž‘์€์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ™•์ธ ๊ฒฐ๊ณผ ๊ธ์ •์ ์ธ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

๋ถ€์šธ noneMatch(rule) ๋ฉ”์„œ๋“œ

์ด noneMatch()๋ฉ”์„œ๋“œ๋Š” ์ŠคํŠธ๋ฆผ์— ์ „๋‹ฌ๋œ ๊ทœ์น™๊ณผ ์ผ์น˜ํ•˜๋Š” ์š”์†Œ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ anyMatch()๋ฐฉ๋ฒ•์˜ ๋ฐ˜๋Œ€์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•”ํ˜ธ ๋ฉ”๋ชจ
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).noneMatch(x -> x > 0);

true


2. ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค: Optionalํด๋ž˜์Šค

๋•Œ๋กœ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ฐธ์กฐ๋กœ ์ž‘์—…ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ๋ถˆํŽธํ•ฉ๋‹ˆ๋‹ค null. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‘ ๋ฌธ์ž์—ด์„ ๋น„๊ตํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ณ€์ˆ˜๊ฐ€ ๋ชจ๋‘ ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ null๊ฐ„๋‹จํžˆ ํ˜ธ์ถœํ•˜๋ฉด s1.equals(s2)๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋Ÿด s1์ˆ˜ ์žˆ๋‹ค๋ฉด .nullNullPointerException

์ด๊ฒƒ์ด ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์ด ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค๋ฅผ ์ƒ๊ฐํ•ด ๋‚ธ ์ด์œ ์ž…๋‹ˆ๋‹ค Optional<T>. ์ฝ”๋“œ๋Š” ๋Œ€๋žต ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•”ํ˜ธ ๋ฉ”๋ชจ
class Optional<Type>
{
   private final Type value;
   private Optional() { this.value = null;}
   private Optional(value) { this.value = value;}
   public static <Type> Optional<Type> of(Type value)
   {
      return new Optional<Type>(value);
   }

   public boolean isPresent()
   {
      return value != null;
   }

   public boolean isEmpty()
   {
      return value == null;
   }

   public Type get()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }

   public Type orElse(Type other)
   {
      return value != null ? value : other;
   }

   public Type orElseThrow()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }
}










๊ฐ’์ด ์•„๋‹Œ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. null



๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. null




์ €์žฅ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ’์ด null์ธ ๊ฒฝ์šฐ ์˜ˆ์™ธ๋ฅผ throwํ•ฉ๋‹ˆ๋‹ค.







์ €์žฅ๋œ null์ด ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜๋Š” ์ €์žฅ๋œ ๊ฐ’์ด ์ธ ๊ฒฝ์šฐ null๋ฉ”์„œ๋“œ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.



null์ด ์•„๋‹Œ ์ €์žฅ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ๊ฐ’์ด null์ธ ๊ฒฝ์šฐ ์˜ˆ์™ธ๋ฅผ throwํ•ฉ๋‹ˆ๋‹ค.

์ด ํด๋ž˜์Šค์˜ ๋ชฉ์ ์€ ๋‹จ์ˆœํžˆ T ๊ฐœ์ฒด(์œ ํ˜•์ด T์ธ ๊ฐœ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ)๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๊ฐ์ฒด Optional<T>์ฐธ์กฐ๋Š” null.

์ด ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์•ฝ๊ฐ„ ๋” ์˜ˆ์œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„๊ตํ•ด๋ณด์ž:

์˜ต์…˜ ์‚ฌ์šฉ ์„ ํƒ ์‚ฌํ•ญ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ
public void printString(String s)
{
   Optional<String> str = Optional.ofNullable(s);
   System.out.println(str.orElse(""));
}
public void printString(String s)
{
   String str = s != null ? s : "";
   System.out.println(str)
}

ํ•œ ๊ฐœ์ฒด๋Š” ์ฐธ์กฐ๋ฅผ ์ €์žฅํ•˜๋”๋ผ๋„ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ญ์ƒ ๋‹ค๋ฅธ ๊ฐœ์ฒด Optional์™€ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .Optionalequalsnull

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ ์ด ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด๊ฐ€ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ Optional"์•„๋ฆ„๋‹ค์šด" ๊ฒ€์‚ฌ ๋ฐ "์•„๋ฆ„๋‹ค์šด" ์ž‘์—…์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .nullOptionalnull



3. ์š”์†Œ ์ฐพ๊ธฐ

์ˆ˜์—… ์œผ๋กœ ๋Œ์•„๊ฐ€์ž Stream. ์ด Streamํด๋ž˜์Šค์—๋Š” ์ŠคํŠธ๋ฆผ์—์„œ ์š”์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” 4๊ฐœ์˜ ์ถ”๊ฐ€ ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฉ”์„œ๋“œ๋Š” findFirst(), findAny(), min()๋ฐ ์ž…๋‹ˆ๋‹ค max().

Optional<T> findFirst()๋ฐฉ๋ฒ•

์ด findFirst()๋ฉ”์„œ๋“œ๋Š” ๋‹จ์ˆœํžˆ ์ŠคํŠธ๋ฆผ์˜ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•ด์•ผ ํ•  ๋” ํฅ๋ฏธ๋กœ์šด ์ ์€ ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฐœ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ T๋ž˜ํผ Optional<T>๊ฐœ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. null์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ์ฒด ์ฐพ๊ธฐ์— ์‹คํŒจํ•œ ํ›„ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค .

์˜ˆ:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello

๋” ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋งˆ์ง€๋ง‰ ์ค„์„ ์—ฌ๋Ÿฌ ์ค„๋กœ ๋‚˜๋ˆ„๊ฒ ์Šต๋‹ˆ๋‹ค.

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello

๋งˆ์ง€๋ง‰ get()๋ฐฉ๋ฒ•์€ ๋‹จ์ˆœํžˆ ๊ฐœ์ฒด ๋‚ด๋ถ€์— ์ €์žฅ๋œ ๊ฐ’์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค Optional.

Optional<T> findAny()๋ฐฉ๋ฒ•

์ด findAny()๋ฉ”์„œ๋“œ๋Š” ์ŠคํŠธ๋ฆผ์—์„œ ๋ชจ๋“  ์š”์†Œ๋ฅผ โ€‹โ€‹๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฑฐ๊ธฐ์„œ ๋๋‚ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์™€ ์œ ์‚ฌ findFirst()ํ•˜์ง€๋งŒ ๋ณ‘๋ ฌ ์ž‘์—…์— ์‚ฌ์šฉ๋˜๋Š” ์ŠคํŠธ๋ฆผ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

์ŠคํŠธ๋ฆผ์„ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ŠคํŠธ๋ฆผ์˜ ์ผ๋ถ€์—์„œ ์š”์†Œ๊ฐ€ ์ด๋ฏธ ๋ฐœ๊ฒฌ๋˜์—ˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ฒซ ๋ฒˆ์งธ์ธ์ง€ ์—ฌ๋ถ€๋Š” ์•„์ง ๋ช…ํ™•ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ์š”์†Œ๊ฐ€ ๋ชจ๋“  ํ•„ํ„ฐ์™€ ์ผ์น˜ํ•˜๊ณ  ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๊ทธ ์ค‘ ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์–ป๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค๋ฉด ๋ฉ”์„œ๋“œ๋ฅผ findFirst()ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์‹ค์ œ๋กœ 0 ๋˜๋Š” 1๊ฐœ์˜ ์š”์†Œ๊ฐ€ ๋ชจ๋“  ํ•„ํ„ฐ์™€ ์ผ์น˜ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๋‹จ์ˆœํžˆ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋ฉฐ ์ด๋Š” findAny()๋” ๋น ๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Optional<T> min(Comparator<T>)๋ฐฉ๋ฒ•

์ด min()๋ฉ”์„œ๋“œ๋Š” comparator๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ โ€‹โ€‹๋น„๊ตํ•˜๊ณ  ์ตœ์†Œ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋น„๊ต ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฐ€์žฅ ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์€ ๋žŒ๋‹ค ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์งง์€ ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ์˜ˆ:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();

Optional<T> max(Comparator<T>)๋ฐฉ๋ฒ•

์ด max()๋ฉ”์„œ๋“œ๋Š” comparator๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๋ฅผ โ€‹โ€‹๋น„๊ตํ•˜๊ณ  ์ตœ๋Œ€ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋น„๊ต ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฐ€์žฅ ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์€ ๋žŒ๋‹ค ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๊ธด ๋ฌธ์ž์—ด์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ์˜ˆ:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();