본문으로 바로가기

[JAVA] 자바 Stream API 사용방법 및 예제

category 1. 웹개발/1_2_4 Java 2020. 11. 23. 20:52

 

 

Stream API는 대량 데이터를 연속 처리하는 '스트림 처리'를 효율적으로 기술하기 위한 수단으로 도입되었습니다.

단, 대량 데이터가 아니더라도 컬렉션의 조작으르 효율적으로 실시할 수 있으므로 자주 이용되고 있습니다.

 

예제를 통하여 Stream API를 알아 보도록 하겠습니다.

아래의 코드는 70점 이상인 학생의 이름을 리스트로 표시하는 예제입니다.

 

Model -> Student.class

package model;

public class Student {
	
	private String studentId;
	private String studentNm;
	private int score;
	
	public String getStudentId() {
		return studentId;
	}
	public void setStudentId(String studentId) {
		this.studentId = studentId;
	}
	public String getStudentNm() {
		return studentNm;
	}
	public void setStudentNm(String studentNm) {
		this.studentNm = studentNm;
	}
	public int getScore() {
		return score;
	}
	public void setScore(int score) {
		this.score = score;
	}
	
	// 빈 생성자
	public Student() {
		
	}
	
	public Student(int score, String studentNm) {
		super();
		this.score = score;
		this.studentNm = studentNm;
	}
	
	@Override
	public String toString() {
		return "Student [studentId=" + studentId + ", studentNm=" + studentNm + ", score=" + score + "]";
	}
	
}

 

 

Service -> Test.class

package service;

import java.util.ArrayList;

import model.Student;

public class Test {

	public static void main(String[] args) {
		ArrayList<Student> student = new ArrayList<Student>();
		student.add(new Student(100, "Yang"));
		student.add(new Student(80, "Cho"));
		student.add(new Student(60, "Yan"));
		
		student.stream() // '작성' - Stream 인스턴스를 생성
			.filter(s->s.getScore() > 70) // '중간 작업' - 점수가 70점 이상만 
			.forEach(s->System.out.println(s.getStudentNm())); // '종료' - 이름을 출력
	}

}

 

 

Stream API의 세 가지 작업으로는 다음과 같습니다.

 

조작 처리 내용
인스턴스 생성 처음에 한 번 컬렉션이나 배열 등으로부터 Stream 작성
중간 작업 복수 Stream으로부터 Stream을 작성
종료 작업 마지막에 한 번 Stream으로부터 컬렉션잉나 배열로 반환하거나, 요소마다 처리를 하거나, 요소를 집계

 

 

1. 인스턴스 생성

ArrayList<Student> student = new ArrayList<Student>();
  student.add(new Student(100, "Yang"));
  student.add(new Student(80, "Cho"));
  student.add(new Student(60, "Yan"));

  student.stream() // '작성' - Stream 인스턴스를 생성

student 인스턴스를 변수에 직접 할당하는 일은 없고 메서드 체인(메서드를 연속해서 호출)을 이용하여 기술하는 경우가 대부분입니다.

 

 

 

2. 중간 작업

메서드명 처리 내용 ex)
filter 조건에 일치하는 요소만을 걸러냅니다. .filter(p-> p.length()>5)
limit 지정한 건수만을 추출합니다. .limit(5)
distinct 유니크한 요소만을 추출합니다. .distinct()
map 요소들을 특정 값으로 변환 .map(p-> "[" + p + "]")
collect Collectors와 함께 객체를 생성 .collect(Collectors.toList())

 

Stream API 중에서도 map, filter, collect는 매우 이용 빈도가 높기 때문에 처음부터 기억해야 할 메서드라고 말할 수 있습니다.

아래의 소스는 5 문자보다 긴 문자열만 괄호로 둘러싼 List를 생성하는 예제입니다.

package service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Test {

	public static void main(String[] args) {
		List<String> list = Arrays.asList("Yanghayan", "Thanggu", "bory"); // 요소가 3개인 리스트 생성
		
		List<String> newList = list.stream() // 인스턴스 생성
			.filter(p-> p.length() > 5) // list의 요소들 중에서 길이가 5이상인것들만
			.map(p-> "[" + p + "]") // [ ] 안에 출력
			.collect(Collectors.toList()); // 객체 생성
		
		newList.forEach(System.out::println); // 종료 및 newList 출력
	
	}

}

 

 

 

3. 종료 작업

1) 바로 앞의 예제에도 나왔지만 Stream의 마지막에 반복 처리를 실시하고 싶은 경우는 표에 나온 forEach 메서드를 사용합니다.

 

메서드명   처리 내용 예제
forEach   이 스트림의 각 요소에 대해 액션을 실행합니다. newList.forEach(System.out::println)

 

2) 아래 메서드는 결과를 정리해서 추출하는 종료 작업입니다.

- Collecors 클래스의 각 메서드가 반환하는 구상 클래스

 

메서드명 처리 내용 예제
toList List로 반환합니다. collect.(Collectors.toList())
toSet Set으로 반환합니다. collect.(Collectors.toSet())
joining 전체 요소를 하나의 문자열로 결합합니다. collect(Collectors.joining(","))
groupingBy 요소를 그룹으로 나눕니다. collect(Collectors.groupingBy(Student::getScore)

 

groupingBy 메서드와 forEach를 다루어 100점을 맞은 학생의 이름을 출력하는 예제입니다.

package service;

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

import model.Student;

public class Test {

	public static void main(String[] args) {
		ArrayList<Student> student = new ArrayList<Student>();
		student.add(new Student(100, "Yang"));
		student.add(new Student(100, "Cho"));
		student.add(new Student(80, "Lee"));
		student.add(new Student(60, "ha"));
		student.add(new Student(0, "yan"));
		
		// 그룹을 나눕니다. 키로 점수, 값에 대응하는 학생의 List가 들어 있는 Map이 만들어집니다.
		Map<Integer, List<Student>> map = student.stream()
				.collect(Collectors.groupingBy(Student::getScore));
		
		// map에서 키값이 100 즉, 100점을 얻은 학생의 리스트를 추출합니다.
		List<Student> perfect = map.get(100);
		perfect.forEach(s->System.out.println(s.getStudentNm())); // Yang, Cho
	}

}

 

 

3) 아래 메서드는 결과를 하나만 추출하는 종료 작업입니다.

 

메서드명 처리 내용 인수
findFirst 선두의 요소를 반환합니다. 없음
findAny 어떤 한 요소를 반환합니다. 없음
min 최솟값을 갖는 요소를 반환합니다. Comparator(인수가 Stream 대상 객체)
max 최댓값을 갖는 요소를 반환합니다. Comparator(인수가 Stream 대상 객체)

 

 

4) 아래 메서드는 요소를 집계하여 결과의 수치를 반환하는 종료 작업입니다. 인수는 없습니다.

 

메서드명 처리 내용 반환 값
count 요소의 개수를 반환합니다. long
min 최소 요소를 반환합니다. OptionalInt/OptionalDouble/OptionalLong
max 최대 요소를 반환합니다. OptionalInt/OptionalDouble/OptionalLong
sum 합계 값을 반환합니다. OptionalInt/OptionalDouble/OptionalLong
average 평균값을 반환합니다. OptionalDouble

 

이상으로 자바 Stream API 사용방법 및 예제를 마치도록 하겠습니다. 감사합니다.