Home NhnAcademy 선발교육과정 19일차 (Stream)
Post
Cancel

NhnAcademy 선발교육과정 19일차 (Stream)

문자열 스트림

  • 문자열에 대해서 Stream을 생성할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
public class Example12 {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("input String" + System.lineSeparator());
        System.out.println("### Stream<String> ###");
        Stream<String> stream1 = sb.toString().lines();
        stream1.forEach(System.out::println);
        System.out.println("### intStream ###");
        IntStream stream2 = sb.chars();
        System.out.println(Arrays.toString(stream2.toArray()));
    }
}

파일 스트림

  • File IO 관련 API를 이용해서 텍스트 파일을 라인 단위로 읽어드릴 수 있다. Stream 에서 텍스트 파일을 읽어 라인 단위로 처리할 수 있다.
1
2
3
4
5
6
7
8
9
public class FileStream {

  public static void main(String[] args){
    //Path path = Path.of(ClassLoader.getSystemResource("sample.txt").getPath());
    Path path = Path.of(ClassLoader.getSystemResource("sample.txt").toURI());
    Stream<String> stream = lines(path, StandardCharsets.UTF_8);
    stream.forEach(System.out::println);
  }
}

위와 같이 절대 경로가 아닌 상대 경로로 만들어 주어야 다른 환경에서 실행했을때 파일 경로를 잘 찾을수 있다.

Stream 중간 연산

  • 중간 연산은 조건에 맞는 요소를 구하기 위해서 사용

Filter

  • IntStream filter(IntPredicate predicate);
  • Filter는 인자로 IntPredicate 를 사용하고 데이터 중 필요한 데이터만 뽑아 낼때 사용한다.
1
2
3
4
5
6
7
public class FilterTest {

  public static void main(String[] args) {
    int[] arr = IntStream.iterate(1, n -> n + 1).limit(100).filter((n1) -> n1 % 2 == 0).toArray();
    System.out.println(Arrays.toString(arr));
  }
}

위와 같이 IntStream.iterate 로 1~100까지 수를 만들고 수중 % 2 == 0 을 만족하는 수를 배열에 저장하는 방식으로 사용할 수 있다.

Map

  • <R> Stream<R> map(Function<? super T, ? extends R> mapper);
  • Map은 T타입을 받아 R타입으로 변환 해주는 역활로 값 중 원하는 필드만 추출하거나 특정 형태로 변환해야 할 때 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
public class MapTest {

  public static void main(String[] args) {
    String[] colors = {"white", "blue", "red"};
    List<String> result = Arrays.stream(colors)//Stream<String>
      .map(o -> o.split(""))//<Stream<String[]>
      .collect(Collectors.toList());
    result.forEach(o -> System.out.print(Arrays.toString(o)));
  }
}

위와 같이 Map을 통해 1차원 배열을 split함수를 이용하여 2차원 배열로 만들어 준다.

FlatMap

  • <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
  • FlatMap은 Stream 평탄화로 중복 Stream을 1차원 배열로 만들어 준다.
1
2
3
4
5
6
7
8
9
10
public class FlatMapTest {
  public static void main(String[] args) {
    String[] colors = {"white", "blue", "red"};
    List<String> result = Arrays.stream(colors)//Stream<String>
        .map(o -> o.split(""))//<Stream<String[]>
        .flatMap(Arrays::stream)//Stream<String>
        .collect(Collectors.toList());
    System.out.println(Arrays.toString(result.toArray()));
  }
}

위와 같이 map을 통해 만들어진 Stream<String[]> 배열을 Stream 으로 1차원 배열으로 만들어 준다.

Sorted

  • Stream<T> sorted(Comparator<? super T> comparator);
  • Sort는 Comparator를 인자로 받아 간단하게 Stream 데이터를 정렬할 수 있다.
1
2
3
4
5
6
7
8
9
public class SortTest {
  public static void main(String[] args) {
    Stream<Integer> nums = Stream
        .generate(() -> new Random().nextInt(1000))
        .limit(5)
        .sorted(((o1, o2) -> o2 - o1));
    nums.forEach(System.out::println);
  }
}

위와 같이 랜덤으로 0~1000 숫자를 5개 만들고 정렬할 때 사용할 수 있다.

Peek

  • IntStream peek(IntConsumer action);
  • Peek은 int 타입을 인자로 하는 IntConsumer를 통해 중간 연산의 수행 결과를 알수 있다.
1
2
3
4
5
6
7
8
9
10
public class PeekTest {
  public static void main(String[] args) {
    List<Integer> intList = Arrays.asList(2, 4, 1, 5, 7, 6, 10);
    List<Integer> SortIntList = intList.stream()
      .sorted()
      .peek(o -> System.out.println(o))
      .collect(Collectors.toList());
    System.out.println(distinctIntList);
  }
}

위와 같이 정렬된 배열을 생성한다고 할때 중간 연산결과를 출력할 수 있다.

Distinct

  • Stream<T> distinct();
  • Distinct는 중복을 제거할때 사용한다.
1
2
3
4
5
6
7
8
9
public class DistinctTest {
  public static void main(String[] args) {
    List<Integer> intList = Arrays.asList(2, 5, 3, 2, 4, 3);
    List<Integer> distinctIntList = intList.stream()
        .distinct()
        .collect(Collectors.toList());
    System.out.println(distinctIntList);
  }
}//result : [2, 5, 3, 4]

위와 같이 배열에 중복을 제거한다고 할때 distinct를 넣으면 된다.

Limit && Skip

  • Limit : Stream<T> limit(long maxSize);
    • long타입의 요소까지 제한한다.
  • Skip : Stream<T> skip(long n);
    • long타입의 요소 건너뛰기 한다.

ForEach

  • void forEach(Consumer<? super T> action);
  • ForEach는 Stream에서 나오는 값에 대해서 순회하면서 작업이 필요할 때 사용한다.
1
2
3
4
5
6
public class ForEachTest {
  public static void main(String[] args) {
    List colors = List.of("red", "white", "blue", "green", "yellow");
    colors.stream().forEach(System.out::println);
  }
}

위와 같이 배열을 순차적으로 출력할 때 사용할 수 있다.

Reduce

  • OptionalInt reduce(IntBinaryOperator op);
  • Reduce는 Stream의 데이터를 변환하지 않고, 사칙연산을 수행하여 하나의 값을 만들때 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ReduceTest {
  public static void main(String[] args) {
    IntSupplier intSupplier = new IntSupplier() {
      private int a = 1;
      @Override
      public int getAsInt() {return a++;}};

    OptionalInt sum = IntStream.generate(intSupplier)
        .limit(10)
        .reduce((o1, o2) -> o1 + o2);
    if (sum.isPresent()) {
      System.out.println("sum:" + sum.getAsInt());
    }
  }
}

위와 같이 1~10까지 수의 합을 구할때 사용할 수 있다.

FindFirst , FindAny

  • FIndFirst : Optional<T> findFirst();
    • 조건에 일치하는 요소들 중에 Stream에서 가장 앞에 있는 요소를 반환
  • FindAny : Optional<T> findAny();
    • 가장 먼저 탐색되는 요소를 반환

anyMatch , allMatch , nonMatch

  • anyMatch() : 최소한 한 개의 요소가 조건에 만족하는지 탐색
  • allMatch() : 모든 요소가 매개 값으로 주어진 조건을 만족하는지 탐색
  • noneMatch() : 모든 요소가 주어진 조건을 만족하지 않는지 탐색

기본 집계

SummaryStatistics

-

Collect

  • Collector는 Stream에서 종단연산에 해당되는 .collect() 함수의 파라미터에 해당하는 인터페이스이다.
    • stream().collect(Collectors.함수) 다음과 같은 형태로 접근할 수 있다.
  • counting : counting() 으로 갯수를 카운트
1
long counting = users.stream().collect(Collectors.counting());
  • MaxBy, MinBy : 조건에 따른 최댓값 , 최솟값을 반환
1
2
3
4
Optional<User> maxUser = users.stream().collect(
              Collectors.maxBy(Comparator.comparingInt(User::getUserAge)));
Optional<User> minUser = users.stream().collect(
              Collectors.minBy(Comparator.comparingInt(User::getUserAge)));

Optional로 한 이유는 nullPointException 을 막아준다.

  • summarizingInt, summarizingLong, summarizingDouble : 숫자의 합계 반환
1
users.stream().collect(Collectors.summingInt(User::getUserAge));
  • averagingint, averagingLong, averagingDouble : 숫자의 평균을 반환
1
users.stream().collect(Collectors.averagingInt(User::getUserAge));
  • 숫자 통계 : count,min,max,sum,average 등
1
2
3
IntSummaryStatistics summarizing = users.stream()
                             .collect(Collectors.summarizingInt(User::getUserAge));
summarizing.getSum() // .getAverage() .getMax ~~
  • Joining : joining() 괄호 안의 값으로 연결 Split 의 반대
1
users.stream().map(User::getUserName) .collect(Collectors.joining(","));
  • toList , toSet ,toCollection : Type 변환
1
2
3
List userList = users.stream().collect(Collectors.toList());
Set userSet = users.stream().collect(Collectors.toSet());
LinkedList<User> userLinkedList = users.stream().collect(Collectors.toCollection(LinkedList::new));
  • groupingBy : 해당 기준으로 그룹화
1
2
var result = users.stream().collect(groupingBy(o -> o.userAge > 30));
Iterator iterator = result.entrySet().iterator();

출력 결과:

false=[User{userName='marco1', userAge=10}'] true=[User{userName='marco8', userAge=50}]

  • collectingAndThen : Collectors 를 이용해서 collecting 을 진행 후 반환된 결과를 기준으로 method 를 한번 더 실행 할 수있다.

  • partitioningBy : Predicate 함수형 인터페이스를 이용하여 특정 기준을 기준으로 분류

1
2
var userMap = users.stream().collect(Collectors.
              partitioningBy(t -> t.getUserAge() > 30, Collectors.toList()));

직렬화

  • java 시스템 내부에서 사용되는 객체(Obect) 또는 데이터(json , xml, csv) 외부 java 시스템에서도 사용할 수 있도록 byte 형태로 변환하는 기술

역질렬화

  • byte로 변환된 Object or Data를 원래의 Object나 Data로 변환하는 기술
This post is licensed under CC BY 4.0 by the author.