Stream JavaSE8+

Stream 은 Java 8 μ—μ„œ μ§€μ›ν•˜λŠ” Lambda λ₯Ό μ΄μš©ν•œ κΈ°μˆ μ΄λ‹€.

μŠ€νŠΈλ¦Όμ€ Array ν˜Ήμ€ Collection Instance λ₯Ό μ΄μš©ν•˜μ—¬ μ‚¬μš©ν•˜λ©° 기쑴의 for / foreach 문을 λŒλ©΄μ„œ ν•˜λ‚˜μ”© κΊΌλ‚΄μ„œ λ‹€λ£¨λŠ” 방법은 μ½”λ“œμ˜ 양이 λ§Žμ•„μ Έ μ—¬λŸ¬ 둜직이 μ„žμ΄κ²Œ 되고 λ©”μ„œλ“œλ₯Ό λ‚˜λˆŒκ²½μš° 루프λ₯Ό μ—¬λŸ¬λ²ˆ λ„λŠ” κ²½μš°κ°€ λ°œμƒλ  수 μžˆλ‹€.

μŠ€νŠΈλ¦Όμ€ λ°μ΄ν„°μ˜ 흐름이며 Array λ˜λŠ” Collection Instance 의 ν•¨μˆ˜ μ—¬λŸ¬κ°œλ₯Ό μ‘°ν•©ν•΄μ„œ μ›ν•˜λŠ” κ²°κ³Όλ₯Ό ν•„ν„°λ§ν•˜κ³  κ°€κ³΅λœ κ²°κ³Όλ₯Ό μ–»μ„μˆ˜ μžˆλ‹€.

κ°€μž₯ 큰 μž₯점은 λ³‘λ ¬μ²˜λ¦¬ (multi-threading) 이 κ°€λŠ₯ν•˜μ—¬ ν•˜λ‚˜μ˜ μž‘μ—…μ„ λ‘˜ μ΄μƒμ˜ μž‘μ—…μœΌλ‘œ μž‘κ²Œ λ‚˜λˆ  λ™μ‹œμ— μ²˜λ¦¬ν•˜λŠ” λ³‘λ ¬μ²˜λ¦¬κ°€ κ°€λŠ₯ν•˜λ‹€.
Thread λ₯Ό μ΄μš©ν•˜μ—¬ λ§Žμ€ μš”μ†Œλ“€μ„ λΉ λ₯΄κ²Œ 처리 κ°€λŠ₯ν•˜λ‹€.

Stream Lifecycle

생성 ν•˜κΈ°

Stream Instance λ₯Ό μƒμ„±ν•˜λŠ” κ³Όμ •μœΌλ‘œ 졜초의 Array 혹 Collction Instance λ₯Ό μ΄μš©ν•˜μ—¬ 생성할 수 μžˆλ‹€.

Array Stream


Β 



String[] arrayStr = new String[]{"a", "b", "c"};
Stream<String> stream = Arrays.stream(arrayStr);

stream.forEach(System.out::println); // [a, b, c]

Β 



String[] arrayStr = new String[]{"a", "b", "c"};
Stream<String> streamOfPart = Arrays.stream(arrayStr, 1, 3);

streamOfPart.forEach(System.out::println); // [b, c]

Collection Stream



Β 
Β 

List<String> list = Arrays.asList("a", "b", "c");

Stream<String> stream = list.stream();
Stream<String> parallelStream = list.parallelStream(); // λ³‘λ ¬μ²˜λ¦¬ 슀트림

κΈ°λ³Έ νƒ€μž…ν˜• 슀트림

IntStream intStream = InsStream.range(1, 5); // [1, 2, 3, 4]
LongStream intStream = LongStream.range(1, 5); // [1, 2, 3, 4, 5]

μ œλ„€λ¦­μ„ μ‚¬μš©ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λΆˆν•„μš”ν•œ Auto-Boxing 이 μΌμ–΄λ‚˜μ§€ μ•ŠλŠ”λ‹€.
ν•„μš”ν•œ 경우 boxed λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ λ°•μ‹±ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.

Stream<Integer> boxedIntStream = IntStream.range(1, 5).boxed();

λ¬Έμžμ—΄ 슀트림

각 문자λ₯Ό char 둜 IntStream 으둜 λ³€ν™˜ν•œλ‹€.

IntStream charsStream = "Stream".chars(); //[83, 116, 114, 101, 97, 109]

μ •κ·œν‘œν˜„μ‹μ„ μ΄μš©ν•˜μ—¬ 각 μš”μ†Œλ“€μ„ κ΅¬μ„±ν•œλ‹€.

Stream<String> regExStream = Pattern.compile(", ").splitAsStream("Eric, Elena, Java");  // [Eric, Elena, Java]

파일 슀트림

ν•΄λ‹Ή 파일의 각 라인을 슀트림으둜 λ§Œλ“€μ–΄μ€€λ‹€.

Stream<String> lineStream = File.lines(Paths.get("file.txt"), Charset.forName("UTF-8"));

병렬 슀트림

일반적으둜 μŠ€νŠΈλ¦Όμ„ μƒμ„±ν•˜λŠ” stream λ©”μ„œλ“œ λŒ€μ‹  parallelStream λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 병렬 μŠ€νŠΈλ¦Όμ„ μ‰½κ²Œ 생성할 수 μžˆλ‹€.

// 병렬 슀트림 생성
Stream<Product> parallelStream = productList.parallelStream();

// 병렬 μ—¬λΆ€ 확인
boolean isParallel = parallelStream.isParallel();

μ•„λž˜ μ½”λ“œλŠ” 각 μž‘μ—…μ„ μ“°λ ˆλ“œλ₯Ό μ΄μš©ν•˜μ—¬ λ³‘λ ¬μ²˜λ¦¬ λ©λ‹ˆλ‹€.

boolean isMany = parallelStream
  .map(product -> product.getAmount() * 10)
  .anyMatch(amount -> amount > 200);

λ‹€μŒμ€ 배열을 μ΄μš©ν•˜μ—¬ 병렬 μŠ€νŠΈλ¦Όμ„ μƒμ„±ν•˜λŠ” κ²½μš°μž…λ‹ˆλ‹€.

Arrays.stream(array).parallel();

μ»¬λ ‰μ…˜κ³Ό 배열이 μ•„λ‹Œ κ²½μš°μ—λ„ parallel λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄ μ²˜λ¦¬ν•œλ‹€.

IntStream intStream = IntStream.range(1, 150).parallel();
boolean isParallel = intStream.isParallel();

λ‹€μ‹œ μ‹œν€€μ…œ (Sequential) λͺ¨λ“œλ‘œ 돌리고 μ‹Άλ‹€λ©΄ sequential λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

IntStream intStream = intStream.sequential();
boolean isParallel = intStream.isParallel();

κ·Έ μ™Έ 방법

λΉ„μ–΄μžˆλŠ” 슀트림

Stream μš”μ†Œκ°€ μ—†μ„λ•Œ null λŒ€μ‹  μ‚¬μš©

public Stream<String> streamOf(List<String> list) {
  return (list == null || list.isEmpty())
    ? Stream.empty()
    : list.stream()
}

Stream.builder()

λΉŒλ” (Builder) λ₯Ό μ‚¬μš©ν•˜μ—¬ μŠ€νŠΈλ¦Όμ— μ§μ ‘μ μœΌλ‘œ μ›ν•˜λŠ” 값을 λ„£μ„μˆ˜ μžˆλ‹€.
λ§ˆμ§€λ§‰μœΌλ‘œ builder λ©”μ„œλ“œλ‘œ μŠ€νŠΈλ¦Όμ„ λ¦¬ν„΄ν•œλ‹€.

Stream<String> builder = Stream.<String>builder()
  .add("Eric").add("Elena").add("Java")
  .build();

Stream.generate

슀트림의 크기가 μ§€μ •λ˜μ§€ μ•Šκ³  λ¬΄ν•œνžˆ ν™•μž₯ν•˜λ‹ˆ limit 으둜 크기λ₯Ό μ œν•œν•΄μ€˜μ•Ό ν•œλ‹€.

Stream<String> generatedStream = Stream.generate(() -> "gen").limit(5); // [gen, gen, gen, gen, gen]

Stream.iterate()

Stream<Integer> iteratedStream = Stream.iterate(30, n -> n + 2).limit(5); // [30, 32, 34, 36, 38]

슀트림 μ—°κ²°ν•˜κΈ°

Stream.concat 두 개의 μŠ€νŠΈλ¦Όμ„ μ—°κ²°ν•΄μ„œ μƒˆλ‘œμš΄ μŠ€νŠΈλ¦Όμ„ μƒμ„±ν•œλ‹€.

Stream<String> stream1 = Stream.of("Java", "Scala", "Groovy");
Stream<String> stream2 = Stream.of("Python", "Go", "Swift");

Stream<String> concatStream = Stream.concat(stream1, stream2);
// [Java, Scala, Groovy, Python, Go, Swift]

κ°€κ³΅ν•˜κΈ°

Filtering

μŠ€νŠΈλ¦Όλ‚΄μ˜ μš”μ†Œλ“€μ„ κ±ΈλŸ¬λ‚΄λŠ” μž‘μ—…μž…λ‹ˆλ‹€.

인자둜 λ°›λŠ” Predicate λŠ” boolean νƒ€μž…μ„ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‘œ 평가식이 λ“€μ–΄κ°€κ²Œ λ©λ‹ˆλ‹€.

Stream<String> stream = names.stream()
  .filter(name -> name.contains("a"));
  // [Elena, Java]

각 μš”μ†Œμ—μ„œ "a" λ¬Έμžμ—΄μ΄ λ“€μ–΄κ°„ μ΄λ¦„λ§Œ λ“€μ–΄κ°„ 슀트림이 λ°˜ν™˜λ©λ‹ˆλ‹€.

Mapping

μŠ€νŠΈλ¦Όλ‚΄μ˜ μš”μ†Œλ“€μ„ ν•˜λ‚˜μ”© νŠΉμ • κ°’μœΌλ‘œ λ°˜ν™˜ν•΄μ€λ‹ˆλ‹€.

Stream<String> stream = names.stream()
  .map(String::toUpperCase);
  // [ERIC, ELENA, JAVA]

μ•„λž˜μ™€ 같이 객체 μš”μ†Œμ—μ„œ κΊΌλ‚΄μ˜¬μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

Stream<Integer> stream = productList.stream()
  .map(Product::getAmount);
  // [23, 14, 13, 23, 13]

flatMap 은 쀑첩ꡬ쑰λ₯Ό μ œκ±°ν•œ ν›„ μž‘μ—…ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

List<List<String>> list = Arrays.asList(
  Arrays.asList("a"),
  Arrays.asList("b")
); // [[a], [b]]
List<String> flatList = list.stream()
  .flatMap(Collection::stream)
  .collect(Collectors.toList());
  // [a, b]

μ‹€μ œλ‘œ μ μš©μ‹œμ—λŠ” μ•„λž˜ μ˜ˆμ‹œμ™€ 같이 μ‚¬μš©ν•©λ‹ˆλ‹€.

students.stream()
  .flatMapToInt(student -> IntStream.of(student.getKor(), student.getEng(), student.getMath()))
  .average().ifPresent(avg -> System.out.println(Math.round(avg * 10)/10.0));

Sorting

정렬방법은 λ‹€λ₯Έ μ •λ ¬κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ Comparator 을 μ΄μš©ν•œλ‹€.

인자 없이 ν˜ΈμΆœν•  경우 μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬ν•©λ‹ˆλ‹€.


Β 




IntStream.of(14, 11, 20, 39, 23)
  .sorted()
  .boxed()
  .collect(Collectors.toList());
  // [11, 14, 20, 23, 39]

λ¬Έμžμ—΄ 리슀트λ₯Ό μ•ŒνŒŒλ©§ μˆœμ„œλŒ€λ‘œ μ •λ ¬ν•˜λŠ” μ½”λ“œμ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

List<String> lang =
  Arrays.asList("Java", "Scala", "Groovy", "Python", "Go", "Swift");

// μ˜€λ¦„μ°¨μˆœ
lang.stream()
  .sorted()
  .collect(Collectors.toList());  // [Go, Groovy, Java, Python, Scala, Swift]

// λ‚΄λ¦Όμ°¨μˆœ
lang.stream()
  .sorted(Comparator.reverseOrder())
  .collect(Collectors.toList());  // [Swift, Scala, Python, Java, Groovy, Go]

λ¬Έμžμ—΄ 길이λ₯Ό κΈ°μ€€μœΌλ‘œ μ •λ ¬ν•˜λŠ” μ½”λ“œμ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

lang.stream()
  .sorted(Comparator.comparingInt(String::length))
  .collect(Collectors.toList());  // [Go, Java, Scala, Swift, Groovy, Python]

lang.stream()
  .sorted((s1, s2) -> s2.length() - s1.length())
  .collect(Collectors.toList());  // [Groovy, Python, Scala, Swift, Java, Go]

Iterating

μŠ€νŠΈλ¦Όλ‚΄μ˜ μš”μ†Œλ“€μ„ 각각의 λŒ€μƒμœΌλ‘œ νŠΉμ • 연산을 μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ” λ©”μ„œλ“œλ‘œλŠ” peek 이 μžˆλ‹€.

peek 은 κ·Έλƒ₯ ν™•μΈλ§Œ ν•΄λ³΄λŠ” λ©”μ„œλ“œλ‘œ 특쑍 κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ Consumer λ₯Ό 인자둜 λ°›λŠ”λ‹€.

int sum = IntStream.of(1, 3, 5, 7, 9)
  .peek(System.out::println)
  .sum();

μ‘°ν•©ν•˜κΈ°

Calculating

μ΅œλŒ€, μ΅œμ†Œ, 합계, 평균 λ“± κΈ°λ³Έν˜• νƒ€μž…μœΌλ‘œ λ‹€μ–‘ν•œ κ²°κ³Όλ₯Ό λ§Œλ“€μ–΄λ‚Ό 수 μžˆλ‹€.

long count = IntStream.of(1, 3, 5, 7, 9).count();
long sum = LongStream.of(1, 3, 5, 7, 9).sum();

슀트림이 λΉ„μ–΄μžˆλŠ” 경우 count 와 sum 은 0 을 좜λ ₯ν•˜λ©΄ λ˜μ§€λ§Œ
평균, μ΅œλŒ€, μ΅œμ†ŒμΈ κ²½μš°μ—λŠ” ν‘œν˜„λΆˆκ°€ν•˜κΈ° λ•Œλ¬Έμ— Optional 을 μ΄μš©ν•˜μ—¬ λ¦¬ν„΄ν•œλ‹€.

OptionalInt min = IntStream.of(1, 3, 5, 7, 9).min();
OptionalInt max = IntStream.of(1, 3, 5, 7, 9).min();

μŠ€νŠΈλ¦Όμ—μ„œ ifPresent λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄μ„œ Optional 을 μ²˜λ¦¬ν•  수 μžˆλ‹€.

DoubleStream.of(1.1, 2.2, 3.3, 4.4, 5.5)
  .average()
  .ifPresent(System.out::println);

Reduction

μŠ€νŠΈλ¦Όμ—μ„œ reduce λ©”μ„œλ“œλ₯Ό μ΄μš©ν•  수 μžˆλ‹€.
reduce λ©”μ„œλ“œλŠ” 총 μ„Έκ°€μ§€μ˜ νŒŒλΌλ―Έν„°λ₯Ό λ°›μ„μˆ˜ μžˆλ‹€.

  • accmulator
    • 각 μš”μ†Œλ₯Ό μ²˜λ¦¬ν•˜λŠ” 계산 둜직
    • 각 μš”μ†Œκ°€ 쀑간결과λ₯Ό μ²˜λ¦¬ν•˜μ—¬ μƒμ„±ν•˜λŠ” 둜직
  • identity
    • 계산을 μœ„ν•΄ μ΄ˆκΈ°κ°’
  • combiner
    • 병렬 μŠ€νŠΈλ¦Όμ—μ„œλ§Œ μ‚¬μš©κ°€λŠ₯ν•˜λ©° 계산결과λ₯Ό ν•©μΉ˜λŠ” 둜직
OptionalInt reduced = IntStream.range(1, 4) // [1, 2, 3]
  .reduce((a, b) -> {
    return Integer.sum(a, b);
  }); // 6 (1 + 2 + 3)
int reducedTwoParams = IntStream.range(1, 4) // [1, 2, 3]
  .reduce(10, Integer::sum); // 16 (10 + 1 + 2 + 3)
Integer reducedParallel = Arrays.asList(1, 2, 3)
  .parallelStream()
  .reduce(10,
    Integer::sum,
    (a, b) -> {
      System.out.println("combiner was called");
      return a + b;
    }); // 36 (10 + 1 = 11, 10 + 2 = 12, 10 + 3 = 13)

Collecting

μŠ€νŠΈλ¦Όμ„ μ’…λ£Œν•˜λŠ” λ˜λ‹€λ₯Έ μž‘μ—…μœΌλ‘œ Collector νƒ€μž…μ˜ 인자λ₯Ό λ°›μ•„μ„œ μ²˜λ¦¬ν•œλ‹€.

Collectors.toList()

μŠ€νŠΈλ¦Όμ—μ„œ μž‘μ—…ν•œ κ²°κ³Όλ₯Ό 리슀트둜 λ°˜ν™˜ν•œλ‹€.

List<String> collectorCollection = productList.stream()
  .map(Product::getName)
  .collect(Collectors.toList());
// [potatoes, orange, lemon, bread, sugar]

Collectors.joining()

μŠ€νŠΈλ¦Όμ— μž‘μ—…ν•œ κ²°κ³Όλ₯Ό ν•˜λ‚˜μ˜ λ¬Έμžμ—΄λ‘œ 이어 뢙인닀.

String listToString = productList.stream()
  .map(Product::getName)
  .collect(Collectors.joining());
// potatoesorangelemonbreadsugar
  • delimiter
    • 각 μš”μ†Œ 쀑간에 λ“€μ–΄κ°€ μš”μ†Œλ₯Ό κ΅¬λΆ„μ‹œμΌœμ£ΌλŠ” κ΅¬λΆ„μž
  • prefix
    • κ²°κ³Ό 맨 μ•žμ— λΆ™λŠ” 문자
  • suffix
    • κ²°κ³Ό 맨 뒀에 λΆ™λŠ” 문자
String listToString = productList.stream()
  .map(Product::getName)
  .collect(Collectors.joining(", ", "<", ">"));
// <potatoes, orange, lemon, bread, sugar>

Collectors.averageingInt()

μˆ«μžκ°’μ˜ 평균 (avg) 을 λ‚Έλ‹€.

Double averageAmount = productList.stream()
  .collect(Collectors.averagingInt(Product::getAmount));
// 17.2

Collectors.summingInt()

μˆ«μžκ°’μ˜ ν•© (sum) 을 λ‚Έλ‹€.

Integer summingAmount = productList.stream()
  .collect(Collectors.summingInt(Product::getAmount));
// 86
Integer summingAmount = productList.stream()
  .mapToInt(Product::getAmount)
  .sum(); // 86

Collectors.summarizingInt()

개수, 합계, 평균, μ΅œμ†Œ, μ΅œλŒ€μ˜ 값을 μΌκ΄„μ μœΌλ‘œ λ°˜ν™˜ν•œλ‹€.

IntSummaryStatistics statistics = productList.stream()
  .collect(Collectors.summarizingInt(Product::getAmount));
IntSummaryStatistics {count=5, sum=86, min=13, average=17.200000, max=23}

Collectors.groupingBy()

νŠΉμ •μš”μ†Œλ“€λ‘œ κ·Έλ£Ήμ§€μ„μˆ˜ μžˆλ‹€.

Map<Integer, List<Product>> collectorMapOfLists = productList.stream()
  .collect(Collectors.groupingBy(Product::getAmount));

κ²°κ³ΌλŠ” Map νƒ€μž…μœΌλ‘œ λ‚˜μ˜¨λ‹€.

{
  23=[Product{amount=23, name='potatoes'}, Product{amount=23, name='bread'}],
  13=[Product{amount=13, name='lemon'}, Product{amount=13, name='sugar'}],
  14=[Product{amount=14, name='orange'}]
}

Collectors.partitioningBy()

groupingBy μ—μ„œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ Function 을 μ΄μš©ν•΄μ„œ νŠΉμ •κ°’μ„ κΈ°μ€€μœΌλ‘œ 슀트림 λ‚΄μ˜ μš”μ†Œλ“€μ„ λ¬Άμ—ˆλ‹€λ©΄
partitioningBy λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ Predicate λ₯Ό λ°›μ•„ μ²˜λ¦¬ν•œλ‹€.

Map<Boolean, List<Product>> mapPartitioned = productList.stream()
  .collect(Collectors.partitioningBy(el -> el.getAmount() > 15));

ν•¨μˆ˜λ₯Ό 톡해 μŠ€νŠΈλ¦Όλ‚΄μ˜ μš”μ†Œλ“€μ„ true 와 false λ‘κ°€μ§€λ‘œ λ‚˜λ‰œλ‹€.

{
  false=[Product{amount=14, name='orange'},
        Product{amount=13, name='lemon'},
        Product{amount=13, name='sugar'}],
 true=[Product{amount=23, name='potatoes'},
       Product{amount=23, name='bread'}]
}

n κΉŒμ§€μ˜ μžμ—°μˆ˜λ₯Ό μ†Œμˆ˜μ™€ λΉ„ μ†Œμˆ˜λ‘œ λΆ„ν• 

private boolean isPrime(int candidate) {
  int candidateRoot = (int) Math.sqrt((double) candidate);
  return IntStream.rangeClosed(2, candidateRoot).noneMatch(i -> candidate % i == 0);
}

public Map<Boolean, List<Integer>> partitionPrimes(int n) {
  return IntStream.rangeClose(2, n).boxed().collect(Collectors.partitioningBy(candidate -> isPrime(candidate)));
}

Collectors.collectingAndThen()

νŠΉμ • νƒ€μž…μ˜ κ²°κ³Όλ₯Ό collect ν•œ 이후에 좔가적인 μž‘μ—…μ΄ ν•„μš”ν• λ•Œ μ‚¬μš©κ°€λŠ₯ν•˜λ‹€.

λ‹€μŒ μ˜ˆμ œλŠ” Collectors.toSet 을 μ΄μš©ν•΄μ„œ κ²°κ³Όλ₯Ό Set 으둜 collect ν•œ ν›„
μˆ˜μ •λΆˆκ°€ν•œ Set 으둜 λ³€ν™˜ν•˜λŠ” μž‘μ—…μ„ μΆ”κ°€λ‘œ μ‹€ν–‰ν•˜λŠ” μ½”λ“œμ΄λ‹€.

Set<Product> unmodifiableSet = productList
  .stream()
  .collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));

Collectors.of()

reduce λ©”μ„œλ“œλ₯Ό λ™μ μœΌλ‘œ μ‚¬μš©ν•˜μ—¬ collect ν•˜λŠ” μ½”λ“œμ΄λ‹€.

Collector<Product, ?, LinkedList<Product>> toLinkedList = Collector.of(LinkedList::new,
  LinkedList::add,
  (first, second) -> {
    first.addAll(second);
    return first;
  });
LinkedList<Product> linkedListOfPersons = productList.stream()
  .collect(toLinkedList);

Matching

쑰건을 λ§Œμ‘±ν•˜λŠ” κ²°κ³Όλ₯Ό μ²΄ν¬ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.

List<String> names = Arrays.asList("Eric", "Elena", "Java");

boolean anyMatch = names
  .stream()
  .anyMatch(name -> name.contains("a"));

boolean allMatch = names
  .stream()
  .allMatch(name -> name.length() > 3);

boolean noneMatch = names
  .stream()
  .noneMatch(name -> name.endsWith("s"));

Iterating

foreach λŠ” μš”μ†Œλ₯Ό λŒλ©΄μ„œ μ‹€ν–‰λ˜λŠ” μ΅œμ’… μž‘μ—… μž…λ‹ˆλ‹€.

names.stream().forEach(System.out::println);