Stream API

박병주·2023년 2월 6일
0

Java

목록 보기
4/7

자바에서 스트림은 크게 두가지로 나뉘어지게 된다.
1. 입출력(File I/O, System I/O)에 사용하는 스트림
2. Collection을 통해 다량의 데이터를 처리할때 사용하는 스트림

이번에 알아볼 스트림은 Collection 을 통한 다량의 데이터 처리를 위한 스트림이다.
Stream API를 사용하면 기존에 반복문, 조건문 등을 통해서 구현해야 했던 코드들이
더욱 간결하고 가시성이 높아지게 할 수 있다.

List<String> list = Arrays.asList("Lee", "Park", "Kim");
// 기존
Iterator<String> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
List<String> list = Arrays.asList("Lee", "Park", "Kim");
// Stream 활용
list.stream().forEach(name -> System.out.println(name));

Stream API

  • Stream API는 Java 8에 추가되었다.
  • Collection F/W를 통해 관리하는 데이터를 처리하기 위해 주로 사용한다.
  • 수집된 다양한 데이터를 활용하는데 있어서 간결하고 가독성 있는 처리가 가능하다.
  • 다양한 기능들을 사용하기 위해서는 람다 표현식을 이해하고 사용할 수 있어야 한다.
  • 스트림을 이용한 연산 처리는 객체의 생성, 중간 연산, 최종 연산 단계로 구분할 수 있다.

Stream Interface

  • Stream API의 최상위 인터페이스는 BaseStream 인터페이스이다. (직접 사용하는 경우는 드물다.)
  • Stream을 구현한 객체의 주요 특징은 불변성이며, Stream을 통해 얻은 결과는 새롭게 생성된 데이터이다.

Stream 객체 생성

  • Stream 객체를 생성하는 방법은 두가지가 있다.
    1. Collection 객체를 통한 생성
    1. 스트림 빌더
  • Collection 객체들은 stream() 메소드를 기본으로 정의하고 있다.
  • stream() 메소드는 해당 컬렉션 객체가 가지고 있는 항목들에 대해 스트림 처리가 가능한 Stream 객체로 반환한다.
  • 한번 생성한 스트림은 사용 후 다시 사용할 수 없으며 최종 연산이 진행되면 종료된다.
List<String> list = Arrays.asList("Lee", "Kim", "Park", "Hong", "Choi", "Song");
Stream<String> stream = list.stream(); // Stream 생성
System.out.println(stream.count()); // Stream 사용
stream.forEach(System.out::println); // Exception 발생
Stream.Builder<String> builder = Stream.builder();
builder.accept("Kim");
builder.accept("Lee");
builder.accept("Song");
builder.accept("Park");
builder.accept("Lee");
Stream<String> stream = builder.build();
stream.forEach(System.out::println);

Stream 연산

중간 연산

  • 중간 연산은 반환 값이 Stream이기 때문에 체인형식(메소드 체이닝)으로 구현이 가능하다.
연산연산 인수
filterPredicate<T>
mapFunction<T, R>
limit
sortedComparator<T>
distinct

필터링

  • 필터링은 전체 데이터에서 불필요한 데이터를 없애고 원하는 데이터를 정확히 추출하기 위한 과정이다.
    Stream API의 filter(), distinct()와 같은 메소드를 이용해 데이터 추출이나 중복제거를 구현한다.
stream.filter( customer -> customer.getAge() > 30).forEach(System.out::println);

정렬

  • sorted()를 이용한 정렬을 위해서는 반드시 대상 객체들이 Comparable 인터페이스를 구현한 클래스, 즉 비교 가능한 객체여야 한다.
    Comparable 객체가 아닐 경우 오버라이딩을 통해 구현해 주거나 Comparator.comparing()을 이용한다.
    @Override
    public int compareTo(Customer customer) {
        if(this.age > customer.getAge()){
            return 1;
        }else if(this.age == customer.getAge()){
            return 0;
        }else {
            return -1;
        }
    }
customers.stream().sorted(Comparator.comparing(Customer::getName)).forEach(System.out::println);

맵핑

  • 스트림의 매핑 연산은 스트림이 관리하는 데이터를 다른 형태의 데이터로 변환할 수 있도록 한다.
    매핑 연산의 메소드는 map(), mapToInt(), mapToDouble(), mapToLong()이 있다.
    map()메소드를 주로 사용하며, 파라미터는 메소드 참조 람다 표현식이다.

최종 연산

  • 스트림이 관리하는 전체 데이터에 대한 순회 작업은 최종 연산인 forEach() 메소드를 이용한다.
  • collect() 메소드는 스트림 처리 이후 처리된 데이터에 대해 Collection 객체로 변환하여 반환시켜주는 메소드이다.
  • 그 외 count, findFirst, reduce, allMatch, anyMatch, noneMatch 등이 있다.

refer : youtube '나무소리' https://www.youtube.com/@namoosori

profile
Developer

0개의 댓글