JAVA

[ Java ] - stream API 활용

algml0703 2022. 10. 9. 09:16
반응형

 Stream API 활용

stream api는 자바 8에서 새롭게 추가된 것으로, 데이터를 더욱 편리하게 활용할 수 있도록 도와주는 api이다. stream api를 통해 더욱 간결하고 가독성 있는 코드 작성이 가능해졌다. stream api의 경우 람다를 활용하여 사용할 수 있다.

비교 예시

ex1-1) 기존의 코드

public class Ex01 {
    //
    public static void main (String[] args ) {
        List<String> list = Arrays.asList("oh","mi","hee");

        Iterator<String> it = list.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
    
}

ex1-2) stream api를 사용하여 작성한 코드

public class Steam01 {
    //
    public static void main (String[] args ) {

        List<String> streamList = Arrays.asList("oh","mi","hee");

        streamList.stream().forEach( ele -> System.out.println(ele));
    }

}

ex2-1) 나이가 27이상인 사람만을 오름차순으로 정렬하여 이름 데이터만 추출 - 기존 코드

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Stream02 {
    // 조건
    // 1. 27이상
    // 2. 오름차순
    // 3. 이름만 출력

    public static void main (String[] args) {
        //
        List<Customer> customers = new ArrayList<>();

        customers.add(new Customer("oh", 27));
        customers.add(new Customer("kim", 28));
        customers.add(new Customer("seo", 26));
        customers.add(new Customer("song", 28));
        customers.add(new Customer("Lee",24));
        customers.add(new Customer("Choi", 29));

        List<Customer> list = new ArrayList<>();
        // 1. 27 이상인 경우만 list에 담아줌
        for (Customer customer: customers) {
            if (customer.getAge() >= 27) {
                list.add(customer);
            }
        }

        // 2. 오름차순 정렬
        Collections.sort(list);

        // 3. 이름만 출력
        List<String> nameList = new ArrayList<>();

        for (Customer customer: list) {
            nameList.add(customer.getName());
        }

        for (String name: nameList) {
            System.out.println(name);
        }


    }
}

ex2-1) 나이가 27이상인 사람만을 오름차순으로 정렬하여 이름 데이터만 추출 - stream api 활용

package io.namoosori.streamtest;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class Stream02 {
    // 조건
    // 1. 27이상
    // 2. 오름차순
    // 3. 이름만 출력

    public static void main(String[] args) {
        //
        List<Customer> customers = new ArrayList<>();

        customers.add(new Customer("oh", 27));
        customers.add(new Customer("kim", 28));
        customers.add(new Customer("seo", 26));
        customers.add(new Customer("song", 28));
        customers.add(new Customer("Lee",24));
        customers.add(new Customer("Choi", 29));

        List<String> nameList = customers.stream().filter((ele) -> ele.getAge()>=27)
                            .sorted()
                            .map((ele)->ele.getName())
                            .collect(Collectors.toList());

        for (String name: nameList) {
            System.out.println(name);
        }
    }
}

 

Stream 객체 생성 방법

일반적으로는 컬렉션을 이용하여 스트림을 생성하는 방식이 사용된다.

1. Collection 객체를 통한 방법 ~ 컬렉션의 경우 default 메서드로 stream메서드를 가진다.

2. Stream Builder를 통한 방법

stream builder를 통해 스트림 생성시 스트림 자체적으로 데이터를 추가할 수 있다.

* 관련 메서드
- void accept(T)
: 스트림 빌더에 데이터 추가
- Stream.Builder<T> add(T)
: 스트림 빌더에 데이터 추가후, 스트림 반환한다.  
- Stream<T> build();
: 스트림 빌더에 데이터 추가 종료 후 스트림 반환

* 방식
1.  Stream.Builder<[타입]> [변수명] = Stream.builder();   / Stream.
2. Stream<[타입]> [변수명] = Stream.<[타입]>builder().add().build();
// 2방식의 경우 한 번에 build()까지 해주어야 한다.

*스트림 재사용시 아래와 같은 에러 발생

3. 배열을 Stream으로 만드는 방법

 

Stream Interface

- 스트림의 데이터 가공은 각 메서드가 연결되어 사용되며, 가공된 결과물이 다음 메서드에 전달되어 사용된다.
- 스트림의 연산은 중간 연산과 최종 연산으로 이루어져 있다.
- 중간 연산은 연속해서 호출하는 메서드 체이닝으로 구현 가능하다.
- filter, map, limit, sorted, distinct, peek, skip등이 중간연산에 사용되는 메서드들이다.
- 중간 연산이 최종적으로 실행되기 위해서는 최종 연산이 필요하다.
- 최종연산이 이루어진 후에 사용된 스트림을 재사용할 수는 없다.
- forEach, count, collect, sum, reduct등이 대표적으로 최종 연산에 사용되는 메서드들이다.

* 주요 메서드
Stream concat(Stream, Stream)
: 인자로 준 두 개의 스트림 객체를 하나의 스트림 객체로 결합하여 반환하여 준다.
Stream filter()
: 인자로 조건식을 주어 필터링작업후 그 결과를 반환하여 준다.
Object[] toArray()
: 요소들을 배열 객체로 반환하여 준다.
Stream sorted()
: 요소들을 정렬하여 반환하여 준다. sorted메서드를 사용하기 위해서는 대상 객체가 Comparable 인터페이스를 구현한 클래스여야 한다. ex) public class Customer implements Comparable<Customer> { @Override public int compareTo(Customer customer) {if (...){return1;} else if(...)return 0; } else { return -1;}} , 즉 정렬의 기준에 대한 정의를 오버라이딩하여 작성해주는 것이다.
Stream map()
: 요소들의 반환 형식을 설정하여 그 결과문을 반환하여 준다. map이외에도, mapToInt(), mapToDouble(), mapToLong() 이 있다.
Stream limit()
: 인자로 숫자를 주면, 스트림의 요소 중에서 인수로 준 수만큼만 반환하여 준다.
Stream distinct()
: 중복된 데이터를 제거하여 준다. 해당 메서드를 사용하기 위해서는 중복 객체의 비교를 위해 equals()메서드를 정의해주어야 한다.
Stream peek()
:
Stream skip
:
long count()
: 요소의 수를 반환하여 준다. (반환타입: Long)
R collect(Collector)
:  요소를 컬렉션 타입의 객체로 반환하여 준다.  (반환타입: List, Map 형태의 컬렉션) ex).collect(Collectors.toList());
void forEach()
: 각 요소들을 순회하여 준다. (반환타입: void)
sum()
: 요소들의 합을 반환하여 준다.
Optional reduce( )
: 인자에 (previousValue, currentValue ) -> previousValue+currentValue 이와 같은 누산식을 넣어준다. (반환타입: Optional)

* sorted 메서드 활용하려 할 때 해당 객체의 클래스는 Comparable 인터페이스를 구현하여야 한다.

public class Customer implements Comparable<Customer>{

    private String name;
    private int age;

    public Customer (String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString(){
        return "[ Name : " + name + ", Age : " + age +"]" ;
    }

    @Override
    public boolean equals (Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Customer customer = (Customer) o;

        return name.equals(customer.name);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public int compareTo(Customer customer) {
        //
        if(this.age > customer.getAge()) {
            return -1;
        } else if (this.age==customer.getAge()) {
            return 0;
        } else {
            return -1;
        }
    }

}

* 데이터 검색 및 검증 메서드
allMatch()
: 데이터가 모두 일치하는지 확인하여 준다.
anyMatch()
: 데이터가 하나라도 일치하는지 확인하여 준다.
noneMatch()
: 데이터가 모두 일치하지 않는 것을 확인하여 준다.
findFirst()
: 데이터 중 가장 첫번째 데이터를 반환하여 준다.

 

[ 출처 ] : https://www.youtube.com/playlist?list=PLOSNUO27qFbtjCw-YHcmtfZAkE79HZSOO 

 

반응형

'JAVA' 카테고리의 다른 글

[ Java ] - 어노테이션(annonation)  (0) 2022.12.24
[ Spring ] - IoC컨테이너와 DI  (0) 2022.12.09
[ Java ] - 유용한 클래스  (0) 2022.09.28
[ Java ] - Object 클래스  (0) 2022.09.28
[ Java ] - jsp 기본 문법 / jsp 라이프사이클  (0) 2022.09.15