Stream(스트림)
다양한 데이터 소스(컬렉션, 배열 등)를 표준화된 방법으로 다루기 위한 것
- 데이터 소스를 스트림으로 변환 후 여러 번의 중간 연산과 마지막의 최종 연산을 통해 다를 수 있음
- 배열, 컬렉션을 대상으로 연산 수행
- 한 번 생성하고 사용한 스트림 재사용 불가
- 중간 연산은 여러 개의 연산 적용 가능, 최종 연산은 마지막에 한 번 적용
- 최종 연산이 호출되어야 중간 연산에 대한 수행이 이루어지고 그 결과가 만들어짐
- 따라서 중간 연산에 대한 결과를 연산 중에 알 수 없음 → 이를 ‘지연 연산’이라 함
- 스트림 만들기
- 중간연산(반복 적용 가능, 연산 결과가 스트림)
- 최종연산(스트림의 요소를 소모) → 결과 리턴
list.stream() // 스트림 만들기
.distinct() // 중간연산
.limit(5) // 중간연산
.sorted() // 중간연산
.forEach(System.out::println) // 최종연산
Stream의 특징
- 데이터를 담고 있는 저장소(컬렉션)이 아님
- 원본 데이터 소스를 변경하지 않음
- 일회용(필요하면 다시 스트림 생성)
- 병렬 처리 가능(멀티 쓰레드 사용 → .parallel)
1. Stream 생성
Stream<Integer> stream = Arrays.asList(1, 2, 3, 4, 5).stream();
2. Stream의 중간 연산
- 중간 연산의 예 - filter(), map(), sorted() 등
- 조건에 맞는 요소를 추출(filter)하거나 요소를 변환함(map)
.distinct() // 중복 제거
.filter(Predicate<T> predicate) // 조건에 안맞는 요소는 제외
.limit(long maxSize) // maxSize 이후의 요소는 잘라냄
.skip(long n) // 앞에서부터 n개 건너뛰기
.sorted() // 정렬
// 스트림의 요소를 변환
// ex) map(s->s.subString(3))
.map(Function<T> mapper)
// 요소에 작업수행. 보통 중간 작업결과 확인으로 사용
// peek(s->System.out.println(s))
.peek(Consumer<T> action)
Stream.filter()
어떤 조건으로 Stream의 요소들을 필터링 함
List<String> list =
Arrays.asList("a1", "a2", "b1", "b2", "c2", "c1", "c3");
Stream<String> stream = list.stream();
Stream<String> filtered = stream.filter(s -> s.startsWith("c"));
filtered.forEach(System.out::println);
// 출력 결과
// c2
// c1
// c3
Stream.map()
Stream의 요소를 다른 형태로 변경
List<String> list =
Arrays.asList("a1", "a2", "b1", "b2", "c2", "c1", "c3");
Stream<String> stream = list.stream();
stream.map(s -> s.toUpperCase()).forEach(System.out::println);
// 출력 결과 :
// A1
// A2
// B1
// B2
// C2
// C1
// C3
Stream.sort()
Stream의 요소를 정렬
List<Integer> notSortedList = Arrays.asList(3, 5, 2, 4, 1, 7);
// 오름차순
Stream<Integer> streamAsc = notSortedList.stream().sorted();
// 내림차순
Stream<Integer> streamDesc = notSortedList.stream().sorted(Comparator.reverseOrder());
예제 1)
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class Stream_pr1 {
public static void main(String[] args) {
TravelCustomer customer1 = new TravelCustomer("이순신", 40, 100, "b");
TravelCustomer customer2 = new TravelCustomer("김유신", 20, 100, "a");
TravelCustomer customer3 = new TravelCustomer("홍길동", 13, 50, "c");
List<TravelCustomer> customerList = new ArrayList<TravelCustomer>();
customerList.add(customer1);
customerList.add(customer2);
customerList.add(customer3);
System.out.println("== 고객 명단 추가된 순서대로 출력 ==");
customerList.stream().map(c -> c.getName()).forEach(s -> System.out.println(s));
int sum = customerList.stream().mapToInt(c -> c.getPrice()).sum();
System.out.println("== 여행 총 비용 == " + sum);
System.out.println("== 20세 이상 고객 명단 정렬 출력 ==");
customerList.stream().filter(c -> c.getAge() >= 20).map(c -> c.getName()).sorted().forEach(s -> System.out.println(s));
System.out.println("== 고객 등급 대문자로 변경 출력 (2개 요소를 출력하되 앞에서 1개 건너뛰기) ==");
customerList.stream().map(c -> c.getTest().toUpperCase()).limit(2).skip(1).forEach(System.out::println);
}
}
class TravelCustomer {
private String name;
private int age;
private int price;
private String test;
public TravelCustomer(String name, int age, int price, String test) {
this.name=name;
this.age=age;
this.price=price;
this.test=test;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
public String toString() {
return "name=" + name + ", age=" + age + ", price=" + price + ", test=" + test;
}
}
3. Stream의 최종 연산
- 최종 연산의 예 - forEach(), count(), sum(), collect() 등
- 최종 연산 후에 스트림은 더 이상 다른 연산을 적용할 수 없음
Stream.collect()
Stream의 데이터를 변형 등의 처리를 하고 원하는 자료형으로 변환해줌
- List로 변환 → Collectors.toList()
- Map으로 변환 → Collectors.toMap()
- 그 외 Collections로 변환 → Collectors.toCollection(람다식)
- 문자열 결합 → Collectors.joining(”결합할 문자”)
//Collectors.toList()
Stream<String> stream = Stream.of("1", "2", "3", "4", "5");
List<String> streamToList = stream.collect(Collectors.toList());
System.out.println("streamToList = " + streamToList);
//Collectors.toMap()
Stream<String> stream2 = Stream.of("1", "2", "3", "4", "5");
Map<Integer, String> streamToMap = stream2.collect(Collectors.toMap((i) -> Integer.parseInt(i), (i) -> "\""+(i)+"\""));
System.out.println("streamToMap = " + streamToMap);
//List나 Map이 아닌 컬렉션으로의 변환
Stream<String> stream3 = Stream.of("1", "2", "3", "4", "5");
ArrayList<String> streamToArrayList = stream3.collect(Collectors.toCollection(() -> new ArrayList<>()));
System.out.println("streamToArrayList = " + streamToArrayList);
// 매개변수가 1개
Stream<String> stream = Stream.of("1", "2", "3", "4", "5", "6");
String joining = stream.collect(Collectors.joining(","));
System.out.println("joining = " + joining);
// 매개변수가 3개
Stream<String> stream2 = Stream.of("1", "2", "3", "4", "5", "6");
String joining2 = stream2.collect(Collectors.joining(",", "[", "]"));
System.out.println("joining2 = " + joining2);
'Programming Language > JAVA' 카테고리의 다른 글
[JAVA] 지역 변수 & 전역 변수 & static(정적) 변수 (0) | 2023.08.15 |
---|---|
[JAVA] 인터페이스(interface) (0) | 2023.08.12 |
[JAVA] 가비지 컬렉션(Garbage Collection) (0) | 2023.08.01 |
[JAVA] JVM (0) | 2023.08.01 |
[JAVA] 람다식 (0) | 2023.07.19 |