- spring security 6
- ORM
- 스프링부트
- java
- nginx
- Docker
- Git
- SSL
- select
- PYTHON
- 데이터베이스
- spring mvc
- mysql
- Django
- 문자열
- session
- DI
- springboot
- @transactional
- AWS
- join
- 1차원 배열
- jpa
- 프로그래머스
- spring
- 스프링
- sql
- 자바
- string
- spring boot
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
개발하는 자몽
Collections, Collector, stream의 함수 본문
오랜만에 코딩테스트 문제를 풀어보면서 다른 사람들의 풀이를 보니 stream을 정말 잘 활용하고 있었다. 평소 stream을 잘 활용하지 못하기 때문에 복습 겸 정리한다.
Collection Framework, Collectors
Collections는 컬렉션 프레임워크(collection framework)로 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 클래스의 집합이다. 컬렉션 프레임워크는 자바의 인터페이스를 사용하여 구현된다.
참고 Collection은 인터페이스, Collections는 클래스이다.
Collector는 요소들을 축적(accumulate)하고 이를 병렬로 또는 순차적으로 처리하게 해주는 감소/축소(reduction) 연산이다. stream의 마지막 단계에서 사용된다. Collectors는 이러한 컬렉터 인터페이스의 구현을 모아둔 클래스의 집합이다.
Collections.swap()
Collections.swap()은 말 그대로 값을 서로 바꿀 때 사용할 수 있다. 이 메서드를 사용하면 for문을 만들고 그 안에서 힘들게 임시 저장할 변수를 따로 선언하면서 이리저리 바꿀 필요가 없다!
Collections.swap(list, i, j);
파라미터
- List<?> list: 위치를 바꿀 요소들이 속한 리스트
- int i: j와 위치를 바꿀 인덱스
- int j: i와 위치를 바꿀 인덱스
Collector.joining()
Collector.joining()는 String(CharSequence, StringBuilder, String)에 입력받은 파라미터를 순서대로 연결시켜서 Collector로 반환한다. 이 메서드를 사용하면(당연히 stream의 마지막 단계에서) 반복문에서 +나 StringBuilder로 문자열을 합치지 않아도 된다! (메서드 내부를 보면 StringBuilder.append()로 합치고 있다)
Arrays.stream(strArr).collect(Collectors.joining())
위 코드는 어떻게 사용되는지 보여주기 위해 작성했다. stream의 마지막 단계에서 사용되며, String 배열의 값을 순서대로 연결시켜서 Collector로 반환한다.
위 방법보다는 아래 코드처럼 filter()로 조건을 넣거나 String이 아닌 입력값을 형변환한 후에 사용하는 방법이 많이 보인다.
Integer.parseInt(Arrays.stream(arr).filter(i -> i % 2 == 0).mapToObj(String::valueOf).collect(Collectors.joining()))
IntStream.mapToObj()
IntStream.mapToObj()는 stream의 중간 연산으로 사용된다. 흔히 mapTo원시타입()의 형태로 많이 볼 수 있는데, 이 메서드는 원시 타입 stream을 참조 타입 stream으로 변환한다.
위 Collector.joining()의 두번째 코드에서 int형 stream을 새로운 String형 stream으로 반환하는 용도로 쓰인다.
IntStream.boxed()
IntStream.boxed()는 stream의 각 원시 타입 요소를 참조 타입으로 박싱하여 Stream으로 반환한다. 예를 들어 int형 Stream이라면 boxed()를 사용하여 Integer형의 Stream으로 반환된다.
IntStream intStream = Arrays.stream(arr);//int
Stream<Integer> boxed = intStream.boxed();//Integer
String.chars()
String.chars()는 stream이나 Collection이 아닌 String 클래스의 메소드이다. 이 메서드도 문제를 풀다가 stream과 같이 사용되는 코드를 발견해서 정리한다. 이 메서드는 String을 char값의 IntStream으로 반환한다.
String str = "Hello World";
str.chars().forEach(System.out::println);
72
101
108
108
111
32
87
111
114
108
100
이 메서드를 사용한 문제에는 어떤 수를 구성하는 수가 a 또는 b로만 이루어져야 하는 조건이 있다.
예를 들어, 550가 5와 0으로만 이루어져 있다는 조건을 만족하는지 확인해 보자. 550이 조건을 만족하는지 확인하려면 10으로 나눈 값을 확인할 수 있다. 또는 해당 입력값을 String으로 변환하고 char[]/stream으로 다시 변환, 그리고 각 char 값이 '5' 또는 '0'인지 확인하면 된다.
IntStream.allMatch()
IntStream.allMatch()는 모든 요소들이 술어(Predicate)로 주어진 조건을 만족하는지 검사하고, 조건을 모두 만족하거나 stream이 비어 있으면 true를 반환한다. 그렇지 않으면 false를 반환한다. 이 메서드는 Collector.joining()처럼 stream의 마지막 단계에서 사용된다.
파라미터
- IntPredicate predicate: stream의 요소에 적용할 술어(라고 하지만 if문에 넣는 조건이라고 생각하면 된다)
IntStream.rangeClosed()
IntStream.rangeClosed()는 순차적으로 정렬된 IntStream을 반환한다.
List<Integer> list = IntStream.rangeClosed(start, end)
.filter(i -> String.valueOf(i).chars().allMatch(ch -> ch == '0' || ch == '5'))
.boxed().toList();
위 코드는 이전에 먼저 정리한 chars()와 allMatch(), boxed()가 모두 나온다.
스트림의 요소를 start부터 end까지 String으로 변환하고 char값의 IntStream으로 반환한다. 해당 스트림의 모든 요소들이 allMatch() 안의 조건을 만족하면 Stream<Integer>으로 박싱하고 List<Integer>로 축적한다.
파라미터
- int startInclusive: 초기화 값
- int endInclusive: 마지막 값(Inclusive라는 변수명에서 알 수 있는 것처럼 ≤ 를 의미한다)
위 코드의 rangeClosed(start, end)를 for문으로 하면 아래와 같다.
for (int i = start ; i <= end; i++) {
...
}
Integer.intValue()
Integer.intValue()는 Integer에서 int 값으로 반환한다. String을 int형으로 파싱하는 Integer.parseInt()와 다르다.
list.stream().mapToInt(Integer::intValue).toArray()
위 코드는 Integer형의 Stream의 요소를 int 값으로 반환하여 배열로 축적한다(accumulate).
'Java' 카테고리의 다른 글
[TIL / JPA] 데이터베이스 스키마 자동 생성, UNIQUE 제약 조건 관련 TIL (0) | 2024.06.30 |
---|---|
[TIL / JPA] 영속성 컨텍스트 (0) | 2024.06.29 |
[Tomcat Error] java.lang.IllegalArgumentException: The main resource set specified [...\tomcat\tomcat.8080/webapps] is not valid (0) | 2023.04.12 |
리플렉션(Reflection) (0) | 2023.03.28 |
동시성 문제와 쓰레드 로컬 (0) | 2023.03.22 |