다양한 데이터 소스(컬렉션, 배열 등)를 표준화된 방법으로 다루기 위한 것
- 데이터 소스를 스트림으로 변환 후 여러 번의 중간 연산과 마지막의 최종 연산을 통해 다를 수 있음
- 배열, 컬렉션을 대상으로 연산 수행
- 한 번 생성하고 사용한 스트림 재사용 불가
- 중간 연산은 여러 개의 연산 적용 가능, 최종 연산은 마지막에 한 번 적용
- 최종 연산이 호출되어야 중간 연산에 대한 수행이 이루어지고 그 결과가 만들어짐
- 따라서 중간 연산에 대한 결과를 연산 중에 알 수 없음 → 이를 ‘지연 연산’이라 함
- 스트림 만들기
- 중간연산(반복 적용 가능, 연산 결과가 스트림)
- 최종연산(스트림의 요소를 소모) → 결과 리턴
| list.stream() |
| .distinct() |
| .limit(5) |
| .sorted() |
| .forEach(System.out::println) |
- 데이터를 담고 있는 저장소(컬렉션)이 아님
- 원본 데이터 소스를 변경하지 않음
- 일회용(필요하면 다시 스트림 생성)
- 병렬 처리 가능(멀티 쓰레드 사용 → .parallel)
Stream<Integer> stream = Arrays.asList(1, 2, 3, 4, 5).stream();
- 중간 연산의 예 - filter(), map(), sorted() 등
- 조건에 맞는 요소를 추출(filter)하거나 요소를 변환함(map)
| .distinct() |
| .filter(Predicate<T> predicate) |
| .limit(long maxSize) |
| .skip(long n) |
| .sorted() |
| |
| |
| |
| .map(Function<T> mapper) |
| |
| |
| |
| .peek(Consumer<T> action) |
어떤 조건으로 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); |
| |
| |
| |
| |
| |
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); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
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()); |
| 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; |
| } |
| |
| |
| } |
- 최종 연산의 예 - forEach(), count(), sum(), collect() 등
- 최종 연산 후에 스트림은 더 이상 다른 연산을 적용할 수 없음
Stream의 데이터를 변형 등의 처리를 하고 원하는 자료형으로 변환해줌
- List로 변환 → Collectors.toList()
- Map으로 변환 → Collectors.toMap()
- 그 외 Collections로 변환 → Collectors.toCollection(람다식)
- 문자열 결합 → Collectors.joining(”결합할 문자”)
| |
| Stream<String> stream = Stream.of("1", "2", "3", "4", "5"); |
| List<String> streamToList = stream.collect(Collectors.toList()); |
| System.out.println("streamToList = " + streamToList); |
| |
| |
| 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); |
| |
| |
| Stream<String> stream3 = Stream.of("1", "2", "3", "4", "5"); |
| ArrayList<String> streamToArrayList = stream3.collect(Collectors.toCollection(() -> new ArrayList<>())); |
| System.out.println("streamToArrayList = " + streamToArrayList); |
| |
| |
| Stream<String> stream = Stream.of("1", "2", "3", "4", "5", "6"); |
| String joining = stream.collect(Collectors.joining(",")); |
| System.out.println("joining = " + joining); |
| |
| |
| Stream<String> stream2 = Stream.of("1", "2", "3", "4", "5", "6"); |
| String joining2 = stream2.collect(Collectors.joining(",", "[", "]")); |
| System.out.println("joining2 = " + joining2); |