Java Stream과 Stream 활용한 예시

    스트림이란?

    스트림은 Collection 계열을 다루는 방식을 표준화하는데 많은 도움이 된다. 예를 들어 List를 정렬하기 위해서는 Collection.sort()를 사양했다. 배열을 정렬할 때는 Arrays.sort()를 사용했다. 그런데 스트림을 사용하면 sotr()로만 이런 Collectino 무리들을 손쉽게 정렬할 수 있다. 

    쉽게 말하면 스트림은 데이터 소스를 추상화하고, 데이터를 다루는데 자주 사용되는 메서드를 정의해둔 것이다. 추상화 되었다는 말은 공통된 방법으로 다룰 수 있게 되었다는 것이다. 이렇게 되면 코드 재사용성이 증가한다. 

     


    스트림의 특징

    스트림은 데이터 소스를 변경하지 않는다.

    스트림은 데이터 소스를 읽기만 한다. 실제 데이터 소스를 스트림은 변경하지 않는다.

    스트림은 일회용이다.

    한번 만들어진 스트림은 한번 사용되면 다시는 사용할 수 없다. 

    스트림의 연산

    스트림의 연산은 중간 연산과 최종 연산으로 나누어진다. 중간 연산은 최종 연산이 이루어지기 전까지 발생하는 연산이다. 중간 연산의 결과물은 스트림이기 때문에 중간 연산을 여러번 반복할 수 있다. 최종 연산은 만들어진 스트림을 소모하는 연산이다. 따라서 최종 연산은 한번만 사용이 가능하다. 따라서 스트림을 사용하기 위해서는 반드시 최종 연산을 해야한다. 

     

     

     

    스트림 만들기

    컬렉션

    myList.stream(); // 스트림 생성

    컬렉션의 최고 조상인 Collection 클래스에는 stream()이 정의되어있다. 그래서 stream() 메서드를 이용하면 손쉽게 스트림을 만들 수 있다. 

     

    배열

    Arrays.stream(myArray);

    배열은 Arrays의 스태틱 메서드를 이용해서 만들 수 있다. 

     

     

    스트림의 중간 연산 

    스트림은 기존의 스트림을 이런저런 형태의 스트림으로 바꿔주는 중간 연산이 있다. 중간 연산의 결과물은 스트림이기 때문에 중간 연산을 계속해서 반복할 수 있다. 

    메서드 하는 일
    skip 스트림의 일부를 건너뛸 때 사용한다. skip(3)을 하면 처음 3개 요소를 건너뜀.
    limit 스트림 요소를 제한한다. limit(5)면 5개로 제한함.
    filter predicate 연산을 넣어, 스트림 요소를 걸러냄
    distinct 스트림에서 중복된 요소를 제거함.
    sort 스트림을 정렬함. Compartor, 람다식 등을 넣어서 정렬 조건 튜닝 가능
    map 원하는 필드를 원하는 형태로 뽑아서 새로운 스트림을 만듦.
    mapToInt,Long,Double 숫자 형태의 스트림으로 만듦.

     

     

     

     

     

     

     

     

     

     

     

    Stream이란?


    • Stream은 배열 및 Collections(ArrayList 같은 것들) 를 대상으로 자료형에 관계없이 동일한 연산을 수행한다.
    • Stream은 소모되는 타입으로, 한번 생성하고 사용한 Stream은 재사용할 수 없다. 즉, 사용할 때 마다 만들어야 한다.
    • Stream은 중간 연산과 최종 연산으로 구분된다.
      > 중간 연산은 여러 연산이 올 수 있다. 단. 최종 연산이 호출되어야 중간 연산이 수행된다. 즉, 중간 연산의 결과는 최종 연산이 끝날 때까지 알 수 없다.
      > 최종 연산은 Stream에 있는 요소를 처음부터 끝까지 한번씩 살핀다.
    • ArrayList는 stream()으로 바로 Stream 자료형 생성이 가능하다. 그렇지만 Array는 바로 생성이 안되며, Arrays.stream(array 객체)로 Stream을 생성 할 수 있다.
    중간 연산자 최종 연산자
    filter() / map() / sorted() 등등 ForEach() / count() / sum() / reduce()

    Java의 Reduce 정의

    Stream을 활용한 예시


      A B C
    이름
    나이 40 20 15
    100 50 50

    위의 표를 Stream으로 만든 후에 1) 이름을 한칸씩 출력하기 2) 사람들이 가진 돈의 합 구하기 3) 나이가 20살 이상인 사람들을 정렬해서 출력하기를 수행한다.

    package ch07;
    
    import java.util.ArrayList;
    
    public class MemberTest {
    
    	public static void main(String[] args) {
    		// stream 함수를 이용해서 다음과 같이 진행한다.
    		ArrayList<Member> myList = new ArrayList<>();
    		
    		Member a = new Member("이", 40, 100);
    		Member b = new Member("박", 20, 50);
    		Member c = new Member("김", 13, 50);
    		
    		
    		myList.add(a);
    		myList.add(b);
    		myList.add(c);
    		
    		
    		System.out.println("1번 결과");
    		myList.stream().map(n -> n.getName()).forEach(n -> System.out.println(n));
    		
    		System.out.println();		
    		System.out.println("2번 결과");
    		System.out.println(myList.stream().mapToInt(n -> n.getCost()).sum());
    		
    		System.out.println();		
    		System.out.println("3번 결과");
    		myList.stream().filter(n -> n.getAge() >= 20).map(n -> n.getName()).sorted().forEach(n -> System.out.println(n));
    		
    		
    	}
    
    }

    위는 메인함수의 코드다

    1. Member Class에 toString을 구현했으나, 이름만 가져오고 싶다. map 함수를 이용해 stream의 특정 이름만 가져오게 했다. 
    2. 합을 구해야 하는데, 합과 관련된 최종 연산자는 sum()이 있다. sum은 mapToInt와 함께 쓰여야 한다.
    3. 먼저 Filter 연산으로 나이가 20 이상인 사람들에 대한 스트림을 만들어 준 후에, 이름만 뽑은 Stream을 만들어 주어 넘겨주었다. 그리고 Sorted 중간 연산자를 이용해 정렬된 Stream을 넘겨주었고, 마지막으로 최종 연산자로 각각을 출력했다. 이 때, sorted()가 가능한 이유는 String에 대한 Comparable 혹은 Comparator가 이미 선언되어있어서다. 

    '프로그래밍 언어 > JAVA' 카테고리의 다른 글

    Java : Primitive Type / Reference Type  (0) 2023.02.05
    Java의 상속  (0) 2023.01.20
    멀티 쓰레드 관련 공부  (0) 2022.02.25
    Java : 사용자 정의 어노테이션 만들기  (0) 2022.02.24
    람다식  (0) 2022.02.24

    댓글

    Designed by JB FACTORY