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 |