CHAP05 - Modern-Java-in-Action/Online-Study GitHub Wiki

5.1 ํ•„ํ„ฐ๋ง

  • filter : Predicate(boolean type)๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„์„œ ํ”„๋ ˆ๋””์ผ€์ดํŠธ์™€ ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ๋ฅผ ํฌํ•จํ•˜๋Š” ์ŠคํŠธ๋ฆผ ๋ฐ˜ํ™˜
 List<Dish> vegetarianMenu = menu.stream()
                                 .filter(Dish::isVegetarian)
                                 .collect(toList());
  • distinct : ๊ณ ์œ  ์š”์†Œ๋กœ ์ด๋ฃจ์–ด์ง„ ์ŠคํŠธ๋ฆผ ๋ฐ˜ํ™˜(๊ณ ์œ  ์—ฌ๋ถ€๋Š” hashCode, equals๋กœ ๊ฒฐ์ •)
 List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,6);
 numbers.stream()
        .filter(i->i%2 == 0)
        .distinct()
        .forEach(System.out::println);

5.2 ์ŠคํŠธ๋ฆผ ์Šฌ๋ผ์ด์‹ฑ(Java 9)

  • takewhile : ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ์„ ํฌํ•จํ•œ ๋ชจ๋“  ์ŠคํŠธ๋ฆผ์— ํ”„๋ ˆ๋””์ผ€์ดํŠธ๋ฅผ ์ ์šฉํ•ด ์ŠคํŠธ๋ฆผ์„ ์Šฌ๋ผ์ด์Šค ํ•  ์ˆ˜ ์žˆ๋‹ค.
 List<Dish> slicedMenu1 = specialMenu.stream()
                                     .takeWhile(dish -> dish.getCalories() < 320)
                                     .collect(toList());
  • dropwhile : ํ”„๋ ˆ๋””์ผ€์ดํŠธ๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ๊ฑฐ์ง“์ด ๋˜๋Š” ์ง€์ ๊นŒ์ง€ ๋ฐœ๊ฒฌ๋œ ์š”์†Œ๋ฅผ ๋ฒ„๋ฆฐ๋‹ค.
 List<Dish> slicedMenu2 = specialMenu.stream()
                                     .dropWhile(dish -> dish.getCalories() < 320)
                                     .collect(toList());
  • limit(n) : ์ฃผ์–ด์ง„ ๊ฐ’ ์ดํ•˜์˜ ํฌ๊ธฐ๋ฅผ ๊ฐ–๋Š” ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜
    • ์ •๋ ฌ๋˜์ง€ ์•Š์€ ์ŠคํŠธ๋ฆผ์—๋„ limit ์‚ฌ์šฉ ๊ฐ€๋Šฅ(์ •๋ ฌ๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ๋ฐ˜ํ™˜๋จ)
 List<Dish> slicedMenu3 = specialMenu.stream()
                                     .filter(dish -> dish.getCalories() > 300)
                                     .limit(3)
                                     .collect(toList());
  • skip(n) : ์ฒ˜์Œ n๊ฐœ ์š”์†Œ๋ฅผ ์ œ์™ธํ•œ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜
 List<Dish> slicedMenu4 = specialMenu.stream()
                                     .filter(dish -> dish.getCalories() > 300)
                                     .skip(2)
                                     .collect(toList());

5.3 ๋งคํ•‘

  • ์ŠคํŠธ๋ฆผ ๊ฐ ์š”์†Œ์— ํ•จ์ˆ˜ ์ ์šฉํ•˜๊ธฐ
    • ๋ณ€ํ™˜์— ๊ฐ€๊นŒ์šด ๋งคํ•‘ : ์ŠคํŠธ๋ฆผ์€ ํ•จ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” map ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•œ๋‹ค. ์ธ์ˆ˜๋กœ ์ œ๊ณต๋œ ํ•จ์ˆ˜๋Š” ๊ฐ ์š”์†Œ์— ์ ์šฉ๋˜๋ฉฐ ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•œ ๊ฒฐ๊ณผ๊ฐ€ ์ƒˆ๋กœ์šด ์š”์†Œ๋กœ ๋งคํ•‘๋œ๋‹ค.
// map ๋ฉ”์„œ๋“œ์˜ ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์€ Stream<String>
List<String> dishNames = menu.stream()
                             .map(Dish::getName)
                             .collect(toList());
  • Arrays.stream : ๋ฌธ์ž์—ด์„ ๋ฐ›์•„ ์ŠคํŠธ๋ฆผ์„ ๋งŒ๋“ ๋‹ค.
 String[] arrayOfWords = {"Hello", "World"};
 Stream<String> streamOfWords = Arrays.stream(arrayOfWords);
 
 words.stream()
      .map(word -> word.split("");
      .map(Arrays::stream)
      .distinct()
      .collect(toList();
  • flapMap : ๊ฐ ๋ฐฐ์—ด์„ ์ŠคํŠธ๋ฆผ์˜ ์ฝ˜ํ…์ธ ๋กœ ๋งคํ•‘ํ•˜์—ฌ ํ•˜๋‚˜์˜ ํ‰๋ฉดํ™”๋œ ์ŠคํŠธ๋ฆผ์„ ๋ฐ˜ํ™˜
 List<String> uniqueCharacters = words.stream()
                                      .map(word -> word.split("");
                                      .flatMap(Arrays::stream)
                                      .distinct()
                                      .collect(toList());

5.4 ๊ฒ€์ƒ‰๊ณผ ๋งค์นญ

  • anyMatch : ํ”„๋ ˆ๋””์ผ€์ดํŠธ๊ฐ€ ์ฃผ์–ด์ง„ ์ŠคํŠธ๋ฆผ์—์„œ ์ ์–ด๋„ ํ•œ ์š”์†Œ์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธ. ์ตœ์ข… ์—ฐ์‚ฐ
 if(menu.stream().anyMatch(Dish::isVegetarian)
    System.out.println("The menu is (somewhat) vegetarian friendly!!");
  • allMatch : ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์ฃผ์–ด์ง„ ํ”„๋ ˆ๋””์ผ€์ดํŠธ์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ
 boolean isHealthy = menu.stream()
                         .allMatch(dish -> dish.getCalories() < 1000);
  • noneMatch : ์ฃผ์–ด์ง„ ํ”„๋ ˆ๋””์ผ€์ดํŠธ์™€ ์ผ์น˜ํ•˜๋Š” ์š”์†Œ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธ
 boolean isHealthy = menu.stream()
                         .noneMatch(dish -> dish.getCalories() >= 1000);
  • ์‡ผํŠธ์„œํ‚ท : ์ „์ฒด ์ŠคํŠธ๋ฆผ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•˜๋”๋ผ๋„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ

    • &&, ||, allMatch, noneMatch, findFirst, findAny...
  • findAny : ํ˜„์žฌ ์ŠคํŠธ๋ฆผ์—์„œ ์ž„์˜์˜ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜. ๋‹ค๋ฅธ ์ŠคํŠธ๋ฆผ ์—ฐ์‚ฐ๊ณผ ์—ฐ๊ฒฐํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

    • ์ŠคํŠธ๋ฆผ ํŒŒ์ดํ”„๋ผ์ธ์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹จ์ผ ๊ณผ์ •์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ตœ์ ํ™”๋œ๋‹ค
 Optional<Dish> dish = menu.stream()
                           .filter(Dish::isVegetarian)
                           .findAny();
  • findFirst : ํ˜„์žฌ ์ŠคํŠธ๋ฆผ์—์„œ (๋…ผ๋ฆฌ์ ์ธ ์•„์ดํ…œ ์ˆœ์„œ ์ค‘)์ฒซ๋ฒˆ์งธ ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜.
 List<Integer> someNumbers = Arrays.asList(1,2,3,4,5);
 Optional<Integer> firstSquareDivisibleByThree 
 = someNumbers.stream()
              .map(n -> n*n)
              .filter(n -> n%3 == 0)
              .findFirst();
  • Optional<T> (java.util.Optional)
    • ๊ฐ’์˜ ์กด์žฌ๋‚˜ ๋ถ€์žฌ ์—ฌ๋ถ€๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ ํด๋ž˜์Šค
    • findAny ๋“ฑ์˜ ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ์‹œ ์•„๋ฌด ์š”์†Œ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋“ค์— ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ• ์ง€ ๊ฐ•์ œํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณต
      • isPresent() : ๊ฐ’์„ ํฌํ•จํ•˜๋Š” true, ํฌํ•จํ•˜์ง€ ์•Š์œผ๋ฉด false
      • isPresent(Consumer<T> block) : ๊ฐ’์ด ์žˆ์œผ๋ฉด ์ฃผ์–ด์ง„ block ์‹คํ–‰
      • T get() : ๊ฐ’์ด ์กด์žฌํ•˜๋ฉด ๊ฐ’์„ ๋ฐ˜ํ™˜, ๊ฐ’์ด ์—†์œผ๋ฉด NoSuchElementException
      • T orElse(T other) : ๊ฐ’์ด ์žˆ์œผ๋ฉด ๊ฐ’์„ ๋ฐ˜ํ™˜, ๊ฐ’์ด ์—†์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜
 menu.stream()
     .filter(Dish::isVegetarian)
     .findAny()     <- Optional<Dish> ๋ฐ˜ํ™˜
     .ifPresent(dish -> System.out.println(dish.getName());

5.5 ๋ฆฌ๋“€์‹ฑ

  • ๋ฆฌ๋“€์‹ฑ ์—ฐ์‚ฐ : ๋ชจ๋“  ์ŠคํŠธ๋ฆผ ์š”์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•ด์„œ ๊ฐ’์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์งˆ์˜
  • reduce
    • ์ดˆ๊นƒ๊ฐ’
    • ๋‘ ์š”์†Œ๋ฅผ ์กฐํ•ฉํ•ด์„œ ์ƒˆ๋กœ์šด ๊ฐ’์„ ๋งŒ๋“œ๋Š” BinaryOperator
 int product = numbers.stream().reduce(1, (a, b) -> a*b);
  • ์ž๋ฐ”8์—์„œ๋Š” Integer ํด๋ž˜์Šค์— ๋‘ ์ˆซ์ž๋ฅผ ๋”ํ•˜๋Š” ์ •์  sum ๋ฉ”์†Œ๋“œ ์ œ๊ณต
 int sum = numbers.stream().reduce(0, Integer::sum);
  • ์ŠคํŠธ๋ฆผ ์—ฐ์‚ฐ : ์ƒํƒœ ์—†์Œ๊ณผ ์ƒํƒœ ์žˆ์Œ
    • map, filter ๋“ฑ์€ ์ž…๋ ฅ ์ŠคํŠธ๋ฆผ์—์„œ ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ›์•„ 0 ๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณด๋‚ธ๋‹ค. ์ƒํƒœ๊ฐ€ ์—†๋Š”, ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ๊ฐ–์ง€ ์•Š๋Š” ์—ฐ์‚ฐ์ด๋‹ค.
    • reduce, sum, max ๊ฐ™์€ ์—ฐ์‚ฐ์€ ๊ฒฐ๊ณผ๋ฅผ ๋ˆ„์ ํ•  ๋‚ด๋ถ€ ์ƒํƒœ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์ŠคํŠธ๋ฆผ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ์š”์†Œ ์ˆ˜์™€ ๊ด€๊ณ„์—†์ด ๋‚ด๋ถ€ ์ƒํƒœ์˜ ํฌ๊ธฐ๋Š” ํ•œ์ •๋˜์–ด์žˆ๋‹ค.

5.7 ์ˆซ์žํ˜• ์ŠคํŠธ๋ฆผ

  • ๊ธฐ๋ณธํ˜• ํŠนํ™” ์ŠคํŠธ๋ฆผ : ์ŠคํŠธ๋ฆผ api ์ˆซ์ž ์ŠคํŠธ๋ฆผ์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ŠคํŠธ๋ฆผ
    • ์ˆซ์ž ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋งคํ•‘(IntStream, DoubleStream, LongStream)
      • reduce์™€ ๊ฐ™์€ ์ŠคํŠธ๋ฆผ์— ์ˆจ์–ด์žˆ๋Š” ๋ฐ•์‹ฑ ๋น„์šฉ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณต. ๋ฐ•์‹ฑ ๊ณผ์ •์—์„œ ์ผ์–ด๋‚˜๋Š” ํšจ์œจ์„ฑ๊ณผ ๊ด€๋ จ ์žˆ์œผ๋ฉฐ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋Š” ์•Š์Œ
      • mapToInt, mapToDouble, mapToLong
      • max, min, average ๋“ฑ ๋‹ค์–‘ํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์„œ๋“œ ์ง€์›
    • ๊ฐ์ฒด ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณต์›
      • boxed ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํŠนํ™” ์ŠคํŠธ๋ฆผ์„ ์ผ๋ฐ˜ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ ํ•  ์ˆ˜ ์žˆ๋‹ค
 int clories = menu.stream()    <- Stream<Dish> ๋ฐ˜ํ™˜ 
                   .mapToInt(Dish::getcalories)      <- IntStream ๋ฐ˜ํ™˜
                   .sum();
 IntStream intStream = menu.stream().mapToInt(Dish::getCalories);       <- ์ŠคํŠธ๋ฆผ์„ ์ˆซ์ž ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜
 Stream<Integer> stream = intStream.boxed();            <- ์ˆซ์ž ์ŠคํŠธ๋ฆผ์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜
  • ๊ธฐ๋ณธ๊ฐ’ : OptionalInt
    • ์ŠคํŠธ๋ฆผ์— ์š”์†Œ๊ฐ€ ์—†์„ ๋•Œ์™€ ์ตœ๋Œ“๊ฐ’์ด 0์ธ ์ƒํ™ฉ์— ๋Œ€ํ•œ ๊ตฌ๋ณ„ ๋ฐฉ๋ฒ• : OptionalInt, OptionalDouble, OptinalLong
    • orElse : ๊ฐ’์ด ์—†์„ ๋•Œ ๊ธฐ๋ณธ ์ตœ๋Œ“๊ฐ’์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •
 OptionalInt maxCalories = menu.stream()
                               .mapToInt(Dish::geCalories)
                               .max();
 int max = maxCalories.orElse(1);
  • ์ˆซ์ž ๋ฒ”์œ„
    • range : ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์‹œ์ž‘๊ฐ’, ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ข…๋ฃŒ๊ฐ’. ์‹œ์ž‘๊ฐ’, ์ข…๋ฃŒ๊ฐ’์€ ๊ฒฐ๊ณผ์— ํฌํ•จ๋˜์ง€ ์•Š์Œ
    • rangeClosed : ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์‹œ์ž‘๊ฐ’, ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ข…๋ฃŒ๊ฐ’. ์‹œ์ž‘๊ฐ’, ์ข…๋ฃŒ๊ฐ’์€ ๊ฒฐ๊ณผ์— ํฌํ•จ๋จ
 IntStream evenNumbers = IntStream.rangeClosed(1, 100)
                                  .filter(n -> n%2 == 0);
 System.out.println(evenNumbers.count());

5.8 ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ

  • ๊ฐ’์œผ๋กœ ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ
    • Stream.of : ์ž„์˜์˜ ์ˆ˜๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ์ •์  ๋ฉ”์„œ๋“œ
    • Stream.empty : ์ŠคํŠธ๋ฆผ์„ ๋น„์šฐ๋Š” ๋ฉ”์„œ๋“œ
 // ์ŠคํŠธ๋ฆผ์˜ ๋ชจ๋“  ๋ฌธ์ž์—ด์„ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•œ ํ›„ ๋ฌธ์ž์—ด์„ ํ•˜๋‚˜์”ฉ ์ถœ๋ ฅ
 Stream<String> stream = Stream.of("Modern", "Java", "In", "Action");
 stream.map(String::toUpperCase).forEach(System.out::println);
 
 // ์ŠคํŠธ๋ฆผ์„ ๋น„์›€
 Stream<String> emptyStream = Stream.empty();
  • null์ด ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋กœ ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ
    • System.getProperty : ์ œ๊ณต๋œ ํ‚ค์— ๋Œ€์‘ํ•˜๋Š” ์†์„ฑ์ด ์—†์œผ๋ฉด null์„ ๋ฐ˜ํ™˜
    • Stream.ofNullable : null์„ ๋ช…์‹œ์ ์œผ๋กœ ํ™•์ธ
 String homeValue = System.getProperty("home");
 Stream<String> homeValueStream = homeValue == null ? Stream.empty() : Stream.of(value);
 
 Stream<String> homeValueStream = Stream.ofNullable(System.getProperty("home"));
 
 Stream<String> values = Stream.of("config", "home", "user")
                               .flatMap(key -> Stream.ofNullable(System.getProperty(key)));
  • ๋ฐฐ์—ด๋กœ ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ
    • Arrays.stream : ๋ฐฐ์—ด์„ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š” ์ •์  ๋ฉ”์„œ๋“œ. int๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฐฐ์—ด์„ IntStream์œผ๋กœ ๋ณ€ํ™˜
 int[] numbers = {2,3,5,7,11,13};
 int sum = Arrays.stream(numbers).sum();
  • ํŒŒ์ผ๋กœ ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ
    • Files.lines : ์ฃผ์–ด์ง„ ํŒŒ์ผ์˜ ํ–‰ ์ŠคํŠธ๋ฆผ์„ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜
    • Stream ์ธํ„ฐํŽ˜์ด์Šค๋Š” AutoCloseable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ try ๋ธ”๋ก ๋‚ด์˜ ์ž์›์ด ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ๋œ๋‹ค
 long uniqueWords = 0;
 try(Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())) {
                                uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
                                                   .distinct()
                                                   .count();
 } catch(IOException e) {
                                
 }
  • ํ•จ์ˆ˜๋กœ ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ ๋งŒ๋“ค๊ธฐ
    • Stream.iterate : ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •๋˜์ง€ ์•Š๋Š” ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ(์–ธ๋ฐ”์šด๋“œ ์ŠคํŠธ๋ฆผ) ์ƒ์„ฑ. ์ž๋ฐ”9์—์„œ๋Š” ํ”„๋ ˆ๋””์ผ€์ดํŠธ๋ฅผ ์ง€์›
    • Stream.generate : ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •๋˜์ง€ ์•Š๋Š” ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ(์–ธ๋ฐ”์šด๋“œ ์ŠคํŠธ๋ฆผ) ์ƒ์„ฑ. Supplier๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„์„œ ์ƒˆ๋กœ์šด ๊ฐ’์„ ์ƒ์‚ฐ.
    • ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ์˜ ์š”์†Œ๋Š” ๋ฌดํ•œ์ ์œผ๋กœ ๊ณ„์‚ฐ์ด ๋ฐ˜๋ณต๋˜๋ฏ€๋กœ ์ •๋ ฌํ•˜๊ฑฐ๋‚˜ ๋ฆฌ๋“€์Šคํ•  ์ˆ˜ ์—†๋‹ค.
 Stream.iterate(0, n -> n+2)
       .limit(10)
       .forEach(System.out::println);
 IntStream.iterate(0, n -> n < 100, n -> n+4)
          .forEach(System.out::println);
 IntStream.iterate(0, n -> n+4)
          .filter(n -> n < 100)     // ๋ถˆ๊ฐ€๋Šฅ!
          .forEach(System.out::println);
          
 IntStream.iterate(0, n -> n+4)
          .takeWhile(n -> n < 100)
          .forEach(System.out::println);
 Stream.generate(Math::random)
       .limit(5)
       .forEach(System.out::println);
 // IntStream์˜ generate ๋ฉ”์„œ๋“œ๋Š” Supplier<T> ๋Œ€์‹ ์— IntSupplier๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์Œ
 IntStream ones = IntStream.generate(() -> 1);
 
 IntStream twos = IntStream.generate(new IntSupplier(){
    public int getAsInt(){
        return 2;
    }
 });

 IntSupplier fid = new IntSupplier() {
    private int previous = 0;
    private int current = 1;
    public int getAsInt() {
        int oldPrevious = this.previous;
        int nextValue = this.previous + this.current;
        this.previous = this.current;
        this.current = nextValue;
        return oldPrevious;
    }
 };
 IntStream.generate(fib)
          .limit(10)
          .forEach(System.out::println());
โš ๏ธ **GitHub.com Fallback** โš ๏ธ