Notice
                              
                          
                        
                          
                          
                            Recent Posts
                            
                        
                          
                          
                            Recent Comments
                            
                        
                          
                          
                            Link
                            
                        
                    | 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | 
| 9 | 10 | 11 | 12 | 13 | 14 | 15 | 
| 16 | 17 | 18 | 19 | 20 | 21 | 22 | 
| 23 | 24 | 25 | 26 | 27 | 28 | 29 | 
| 30 | 
                            Tags
                            
                        
                          
                          - Spring
 - 자바
 - 개발자
 - 데이터베이스
 - spring boot
 - 엘라스틱서치
 - ES
 - 코딩
 - 알고리즘
 - 애자일기법
 - cleancode
 - kotlin
 - Baekjoon
 - database
 - 백준
 - 그리디알고리즘
 - 코드
 - 개발
 - 프레임워크
 - 그리디
 - 스프링
 - 애자일프로그래밍
 - 읽기쉬운코드
 - framework
 - Elasticsearch
 - API
 - Java
 - 클린코드
 - JPA
 - 코딩테스트
 
                            Archives
                            
                        
                          
                          - Today
 
- Total
 
튼튼발자 개발 성장기🏋️
Stream 본문
반응형
    
    
    
  Stream은 JAVA 8에서 추가 된 도구로써 함수형 인터페이스를 활용해서 데이터를 매우 간편하고 간결하게 가공할 수 있도록 도와준다.
이번 포스트에서는 이 Stream의 built in method에 대해서 알아보는 시간을 가진다.
Stream은 데이터의 가공되는 흐름을 한 눈에 알아보기 쉽게 가독성을 향상시키는 장점이 있다. 이로인한 이유로 기존에 loop로 짰던 로직을 Stream으로 간결하고 직관적으로 대체가 가능하다. 또한 병렬처리도 가능하다.
다음 아래 내용은 Stream으로 변환하는 세 가지 방법을 소개한다.
// Stream 변환 A방법
Stream<String> nameStream = Stream.of("홍길동", "김길동", "박길동");
List<String> names = nameStream.collect(Collectors.toList());
System.out.println(names);  // [홍길동, 김길동, 박길동]
// Stream 변환 B방법
String[] nameArray = new String[] {"이길동", "강길동", "진길동"};
nameStream = Arrays.stream(nameArray);
names = nameStream.collect(Collectors.toList());
System.out.println(names);  // [이길동, 강길동, 진길동]
// Stream 변환 C방법
Set<String> nameSet = new HashSet<>(Arrays.asList("나길동", "신길동", "조길동"));
nameStream = nameSet.stream();
names = nameStream.collect(Collectors.toList());
System.out.println(names);  // [신길동, 나길동, 조길동]
Built In Method
- filter
- 만족하는 데이터만 걸러낼 때 사용
 - 매개변수 predicate에 true를 리턴하는 데이터만 존재하는 별도의 Stream 리턴
 
Stream<T> filter(Predicate<? super T> predicate);
아래 예제는 isVerified = true인 user만 걸러내는 방법으로, filter를 사용한 코드다.
@Getter
@Builder
@ToString
class User {
    private int id;
    private String name;
    private String email;
    private boolean isVerified;
}
public class Exercise {
    public static void main(String[] args) {
        User user1 = User.builder()
                .id(1)
                .name("아이언맨")
                .email("ironMan@aaa.co.kr")
                .isVerified(true)
                .build();
        User user2 = User.builder()
                .id(2)
                .name("캡틴")
                .email("captain@aaa.co.kr")
                .isVerified(false)
                .build();
        User user3 = User.builder()
                .id(3)
                .name("토르")
                .email("thor@aaa.co.kr")
                .isVerified(false)
                .build();
        List<User> users = Arrays.asList(user1, user2, user3);
        List<User> verifiedUsers = users.stream()
                .filter(User::isVerified)
                .collect(Collectors.toList());
        System.out.println(verifiedUsers);  // [User(id=1, name=아이언맨, email=ironMan@aaa.co.kr, isVerified=true, friendUserIds=null)]
    }
}
- Map
- 데이터를 변형할 때 사용
 - 매개변수 mapper가 데이터에 적용된 별도의 Stream을 리턴
 
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
아래 예제는 isVerified = true인 user의 이름을 추출하는 방법으로, filter와 map을 사용한 코드다.
@Getter
@Builder
@ToString
class User {
    private int id;
    private String name;
    private String email;
    private boolean isVerified;
}
public class Exercise {
    public static void main(String[] args) {
        User user1 = User.builder()
                .id(1)
                .name("아이언맨")
                .email("ironMan@aaa.co.kr")
                .isVerified(true)
                .build();
        User user2 = User.builder()
                .id(2)
                .name("캡틴")
                .email("captain@aaa.co.kr")
                .isVerified(false)
                .build();
        User user3 = User.builder()
                .id(3)
                .name("토르")
                .email("thor@aaa.co.kr")
                .isVerified(false)
                .build();
        User user4 = User.builder()
                .id(4)
                .name("스파이더맨")
                .email("spiderMan@aaa.co.kr")
                .isVerified(true)
                .build();
        List<User> users = Arrays.asList(user1, user2, user3, user4);
        List<String> verifiedUserNames = users.stream()
                .filter(User::isVerified)
                .map(User::getName)
                .collect(Collectors.toList());
        System.out.println(verifiedUserNames);  // [아이언맨, 스파이더맨]
    }
}
- sorted
- 데이터가 정렬되어 있는 Stream을 리턴
 - 데이터 종류에 따라서 Comparator가 필요
 
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
아래 예제는 sorted를 사용하여 정렬하는 코드다.
@Getter
@Builder
@ToString
class User {
    private int id;
    private String name;
    private String email;
    private boolean isVerified;
}
public class Exercise {
    public static void main(String[] args) {
        User user1 = User.builder()
                .id(1)
                .name("아이언맨")
                .email("ironMan@aaa.co.kr")
                .isVerified(true)
                .build();
        User user2 = User.builder()
                .id(2)
                .name("캡틴")
                .email("captain@aaa.co.kr")
                .isVerified(false)
                .build();
        User user3 = User.builder()
                .id(3)
                .name("토르")
                .email("thor@bbb.co.kr")
                .isVerified(false)
                .build();
        User user4 = User.builder()
                .id(4)
                .name("스파이더맨")
                .email("spiderMan@bbb.co.kr")
                .isVerified(true)
                .build();
        User user5 = User.builder()
                .id(5)
                .name("슈퍼맨")
                .email("superMan@aaa.co.kr")
                .isVerified(true)
                .build();
        User user6 = User.builder()
                .id(6)
                .name("배트맨")
                .email("batMan@bbb.co.kr")
                .isVerified(true)
                .build();
        List<User> users = Arrays.asList(user6, user5, user1, user2, user3, user4);
        List<Integer> sortedByUserIds = users.stream()
                .filter(User::isVerified)
                .filter(user -> user.getEmail().contains("@aaa.co.kr"))
                .map(User::getId)
                .sorted()
                .collect(Collectors.toList());
        System.out.println(sortedByUserIds);  // [1, 5]
        sortedByUserIds = users.stream()
                .filter(User::isVerified)
                .filter(user -> user.getEmail().contains("@aaa.co.kr"))
                .map(User::getId)
                .sorted(Comparator.reverseOrder())
                .collect(Collectors.toList());
        System.out.println(sortedByUserIds);  // [5, 1]
        List<String> sortedByUserNames = users.stream()
                .filter(User::isVerified)
                .filter(user -> user.getEmail().contains("@bbb.co.kr"))
                .sorted(Comparator.comparing(User::getName))
                .map(User::getName)
                .collect(Collectors.toList());
        System.out.println(sortedByUserNames);  // [배트맨, 스파이더맨]
    }
}
- distinct
- 중복 데이터가 제거된 Stream을 리턴
 
Stream<T> distinct();
@Getter
@Builder
@ToString
class User {
    private int id;
    private String name;
    private String email;
    private boolean isVerified;
}
public class Exercise {
    public static void main(String[] args) {
        User user1 = User.builder()
                .id(1)
                .name("아이언맨")
                .email("ironMan@aaa.co.kr")
                .isVerified(true)
                .build();
        User user2 = User.builder()
                .id(2)
                .name("아이언맨")
                .email("ironMan@aaa.co.kr")
                .isVerified(true)
                .build();
        User user3 = User.builder()
                .id(3)
                .name("토르")
                .email("thor@bbb.co.kr")
                .isVerified(false)
                .build();
        List<User> users = Arrays.asList(user1, user2, user3);
        List<String> distinctUserNames = users.stream()
                .filter(User::isVerified)
                .map(User::getName)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(distinctUserNames);  // [1, 5]}
    }
}
- flatMap
- 데이터에 함수를 사용한 후 중첩된 Stream을 하나로 연결하여 하나의 Stream을 리턴
 
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
아래 예제는 flatMap을 사용하는 방법을 설명한다.
Stream의 Stream과 같이 어색하고 이상하고 찝찝한 객체가 생성된다면 flatMap을 사용해서 하나로 연결시켜주면 간단하게 해결할 수 있다.
String[][] names = {
        {"스파이더맨", "토르"},
        {"캡틴", "아이언맨"}
};
Stream<Stream<String>> nameStreamStream = Arrays.stream(names).map(x -> Arrays.stream(x));
List<Stream<String>> result = nameStreamStream.collect(Collectors.toList());
System.out.println(result); // [java.util.stream.ReferencePipeline$Head@{주소값}, java.util.stream.ReferencePipeline$Head@{주소값}]
Stream<String> nameStream = Arrays.stream(names).flatMap(x -> Arrays.stream(x));
List<String> result2 = nameStream.collect(Collectors.toList());
System.out.println(result2);    // [스파이더맨, 토르, 캡틴, 아이언맨]반응형
    
    
    
  '프로그래밍 > JAVA' 카테고리의 다른 글
| STREAM 활용 (0) | 2022.08.23 | 
|---|---|
| Optional (0) | 2022.08.12 | 
| Method Reference (0) | 2022.07.14 | 
| Functional Interface (0) | 2022.07.06 | 
| Lambda Expression (0) | 2022.07.06 |