오늘 이거 알았네요/Java
[Java] Stream
로그관리자
2023. 2. 22. 22:13
728x90
Stream
- 데이터 소스가 무엇이든 간에 같은 방식으로 다룬다 (재사용성 up)
- 데이터 소스를 변경하지 않고 읽기만 한다
- 반복문을 메서드 내부에 숨겨 처리한다 (e.g. forEach())
- 일회용이다 (한 번 사용하면 다시 사용 불가)
[생성하기]
배열
Arrays라는 클래스를 통해 생성
int[] intArr = new int[10];
IntStream stream = Arrays.stream(array);
String[] strArr = {"hello", "world"};
Stream<String> strStream = Arrays.stream(strArr);
Collection
Collection interface에 추가된 메서드 .stream()을 통해 생성 (e.g. List, stream)
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
Stream<Integer> stream = list.stream();
자체 생성
Stream.of() : 이는 입력받은 값을 stream으로 변환해 주는 기능을 한다.
Stream<Integer> stream = Stream.of(1, 2, 3);
[가공하기]
- 각각의 요소에 접근해서 사용한다
- 가공해야 하는 메서드가 return 하는 객체는 또다시 stream이다
List<String> list = Arrays.asList("lemon", "gimbap", "strawberry", "bolonesa");
.filter()
조건에 부합하는 요소들만 남긴다. (필터링)
Stream<String> strStream = list.stream()
.filter(x -> x.contains("m"));
// {"lemon", "gimbap"}
→ x는 임의로 붙이는 임시변수이다. 자바의 for-each에서 각 요소를 접근하는 것처럼
.map()
각각의 요소들을 조건에 맞게 변환
Stream<String> stream = list.stream()
.map(x -> x.substring(0,2));
// {"le", "gi", "st", "bo"}
.sorted()
Stream을 소비하지 않고 각각의 요소를 한 번 확인하는 정도의 역할만 하고 return 되는 결과에는 영향을 미치지 않는다.
→ 자료구조에서의 .peek()과 비슷
Stream<String> streamPeek = list.stream().peek(x -> x.substring(0,2));
// 아무런 영향을 미치지 않으므로 {"lemon", "gimbap", "strawberry", "bolonesa"} 유지
Stream<String> streamMap = list.stream().peek(x -> System.out.println(x));
// lemon, gimbap, strawberry, bolonesa 순서대로 출력
[활용하기]
.min() .max() .sum()
숫자형일 때 최소, 최대, 합의 값을 구해주는 연산이다.
int[] arr = {4,5,6,7,8};
OptionalInt oMax = Arrays.stream(arr).max(); // optionalInt[8]
OptionalInt oMin = Arrays.stream(arr).min(); // optionalInt[4]
int sum = Arrays.stream(arr).sum(); // 30
이때, max()와 min()으로 나온 값은 Optional 객체이므로 이는 getAsInt()를 뒤에 붙여주어야 한다.
→ getAsInt() : 정수로 값을 얻는다
int max = oMax.getAsInt();
int min = oMin.getAsInt();
.toArray()
stream을 배열로 변환
List<String> list = Arrays.asList("lemon", "gimbap", "strawberry", "bolonesa");
String[] strArr = list.stream()
.map(x -> x.substring(0, 2))
.toArray(x -> new String[x]);
// {"le", "gi", "st", "bo"}
parameter를 넘기지 않으면 Object 객체의 배열로 넘어가게 된다.
.collect()
Collection 객체로 모으는 역할 ( Collector 객체를 파라미터로 넘겨주어야 한다.)
Set<String> set = list.stream()
.collect(Collector.toSet());
// Set = {"lemon", "gimbap", "strawberry", "bolonesa"}
.forEach()
각 요소에 대해서 어떤 작업을 하고 그대로 실행하는 Consumer를 받는다.
e.g. System.out.println()
list.stream()
.map(x -> x.substring(0, 4))
.forEach(x -> System.out.println(x));
// 순서대로 출력
// lemo, gimb, stra, bolo
아래 그냥 한 번 만들어 봤다.
List를 Stream으로 변환하여 (+ 조건 필터) 배열로 출력
import java.util.Arrays;
import java.util.List;
public class StreamTest {
/*
* list를 stream으로 변환 후 조건 걸어보기
* 배열로 출력해보자
*/
public static void main(String[] args) {
List<String> list = Arrays.asList("lemon", "gimbap", "strawberry", "bolonesa");
System.out.println("======== 1 ========");
Object[] strStream1 = list.stream()
.filter(x -> x.contains("m")).toArray();
System.out.println(Arrays.toString(strStream1));
System.out.println("======== 2 ========");
Object[] strStream2 = list.stream()
.map(x -> x.substring(0, 2))
.toArray();
System.out.println(Arrays.toString(strStream2));
}
}
// ======== 1 ========
// [lemon, gimbap]
// ======== 2 ========
// [le, gi, st, bo]
728x90