String[] arr = new String[]{"banana", "banana", "apple", "fruit", "apple", "bot"};
위와 같은 배열이 주어지고, 아래와 같은 조건이 주어지면 나는 항상 아래와 같이 forEach문만 활용하여 문제를 풀었었다.
1. 중복요소 제거
2. 5자리 이상만 추출
3. 내림차순으로 정렬
4. 각 앞자리 1번째 값만 최종출력
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
/*
1. 중복돼있는 것 제거
2. 5자리 이상만 추출
3. 내림차순으로 정렬
4. 각 앞자리 1번째 값만 최종출력
*/
public class Test {
public static void main(String[] args) {
String[] arr = new String[]{"banana", "banana", "apple", "fruit", "apple", "bot"};
// 중복제거용 HashSet 자료구조 생성
HashSet<String> hashSet = new HashSet<>();
// HashSet에 넣어 중복제거 + 5자리 이상만 추가
for (String s : arr) {
if (s.length() >= 5) {
hashSet.add(s);
}
}
// HashSet은 순서를 보장하지 않기 때문에, List 자료구조로 변경
List<String> arrayList = new ArrayList<>(hashSet);
// 자료구조 메서드인 sort 이용하여 arrayList 객체를 역정렬 진행
Collections.sort(arrayList, Collections.reverseOrder());
// 정렬된 자료구조 하나씩 추출하여 1번째 값만 출력
for (String s : arrayList) {
System.out.println(s.charAt(0));
}
}
}
출력값
f
b
a
헌데 stream을 활용하면 위와같이 for문 도배가 되는 상황을 막을 수 있다.
그 이유는 내부 반복자를 사용하기 때문이다. (개념, 특징, 장점, 단점에 대해서 더 공부 필요함)
활용하여 문제를 더 가독성있게 풀면 아래와 같은 코드가 탄생한다.
import java.util.*;
/*
1. 중복돼있는 것 제거
2. 5자리 이상만 추출
3. 내림차순으로 정렬
4. 각 앞자리 1번째 값만 최종출력
*/
public class Test {
public static void main(String[] args) {
String[] arr = new String[]{"banana", "banana", "apple", "fruit", "apple", "bot"};
Arrays.stream(arr) // 스트림 생성
.distinct() // 중간연산자로 중복제거
.filter(value -> value.length() >= 5) // 중간연산자로 5자리 이상만 스트림 추출 (람다활용)
.sorted(Collections.reverseOrder()) // 중간연산자로 내림차순 정렬
.forEach(value -> System.out.println(value.charAt(0))); // 최종 연산자로 1번째 값 출력 (람다활용)
}
}
출력값
f
b
a
stream 활용하여 다르게 풀어본 것들
import java.util.*;
/*
1. 문자열 길이순으로 정렬
2. 문자열 길이 1인 것은 제외
3. 각 앞자리 1번째 값만 최종출력
*/
public class Test {
public static void main(String[] args) {
String[] arr = new String[]{"a", "bb", "ccc", "dddd"};
Arrays.stream(arr) // 스트림 생성
.filter(value -> value.length() != 1) // 스트림 요소 길이가 1이 아닌 것들만 추출 (람다활용)
.sorted(Comparator.comparing(String::length)) // 중간연산자로 길이순 오름차순 정렬
// .sorted(Comparator.comparing(String::length).reversed()) 중간연산자로 길이순 내림차순 정렬
.forEach(value -> System.out.println(value.charAt(0))); // 최종 연산자로 1번째 값 출력 (람다활용)
}
}
출력값
b
c
d
@Transactional(readOnly = true)
public List<PostMainResDto> getPosts(String postType, Member member) {
List<Post> postList = postRepository.findByPostTypeAndCityName(PostType.valueOf(postType), member.getCityName());
return postList.stream() // postList를 stream으로 변환
.sorted(Comparator.comparing(Post::getCreatedAt).reversed()) // 생성일자 최신기준으로 정렬
.map(PostMainResDto::new)
/*메서드 반환타입을 맞추기 위해 map을 이용. stream의 map() 메서드는 입력 스트림의 각 요소를 다른 요소로 매핑하여,
매핑된 요소들을 새로운 스트림으로 변환하는 용도로 편하게 사용됨*/
//PostMainResDto::new는 클래스의 생성자를 참조하여 새로운 PostMainResDto 객체 생성함
//map메서드에서는 각각의 객체를 받아 stream 요소에서 PostMainResDto 객체로 매핑된 요소들을 새로운 stream으로 반환한다.
.collect(Collectors.toList());
/*collect 메서드는 스트림의 최종 연산 중 하나로, 스트림의 요소들을 모아서 특정한 컬렉션 타입으로 반환해준다.
매개변수는 Collector를 받으며, Collector는 스트림 요소를 수집하는 역할을 한다. Collector를 이용하여 스트림의 요소들을 모아서 List, Set, Map등의 구조로 변환할 수 있다.*/
/*Collectors 클래스는 Collector 객체를 생성하기 위한 static 메소드를 제공한다. 활용예시는 하단에 기재.
Collectors.toList()는 스트림 요소를 List로 수집하는 Collector를 생성
Collectors.toSet()은 스트림 요소를 Set으로 수집하는 Collector를 생성
Collectors.toMap()은 스트림 요소를 Map으로 수집하는 Collector를 생성*/
}
이번 stream 예제로 인해 파악한 stream의 장점
1. 가독성 증가
2. 생산성 증가
자주 써보면서 손에 익혀야겠다.
Stream 예제 및 사용법을 더 공부해서 추후 관련 글을 정리해보아야겠다.
'개인공부' 카테고리의 다른 글
2023.03.04 TIL (위치기반 정보공유 웹 신규 프로젝트 MVP 소개) (0) | 2023.03.04 |
---|---|
Stream 정리 (0) | 2023.02.26 |
Checked, Unchecked Exception 정리 (0) | 2023.02.20 |
JPA (Java Persistence API) 관련개념 간략 총정리 (0) | 2023.01.30 |
2023.01.17 TIL (0) | 2023.01.17 |
댓글