BackEnd/Java
Java 9. 주요 변경 내용 (2)
hanseom
2024. 12. 4. 23:00
반응형
Collection 기능 추가
Collection 객체를 생성하는 간결한 방법이 추가되었습니다.
// Java 9 이전
List<Integer> oldList = Arrays.asList(1, 2);
// Java 9 이후 정적 팩토리 메소드 of가 생겼습니다.
List<Integer> newList = List.of(1, 2);
// Set
Set<Integer> oldSet = new HashSet<>(Arrays.asList(1, 2));
Set<Integer> newSet = Set.of(1, 2);
// Map
Map<String, Integer> oldMap = new HashMap<>();
oldMap.put("A", 1);
oldMap.put("B", 2);
Map<String, Integer> newMap = Map.of("A", 1, "B", 2);
// key-value가 많다면 ofEntries를 사용할 수도 있습니다.
Map.ofEntries(entry("A", 1), entry("B", 2));
of로 만들어진 컬렉션은 불변의 특징을 가지고 있습니다. 즉, 원소를 추가, 삭제, 업데이트하려 하면 에러가 발생합니다. 또한, 기존에 불변 컬렉션을 만들기 위해 사용했던 Collections.unmodifiableXX()와 구현체가 다르기 때문에 조금 더 메모리 효율적인 구조를 가지고 있습니다.
Optional
- ifPresentOrElse: 기존 ifPresent(action) 기능에서 값이 없는 경우에도 제어가 가능한 기능입니다.
public static void optional(Optional<String> str) {
str.ifPresentOrElse(
s -> System.out.println("값이 있으면 출력: " + s),
() -> {
// 값이 없으면 출력하지 않습니다.
}
);
}
- or: 체이닝을 통해 값이 없을 경우 다른 Optional로 변환해주는 기능입니다.
public static void optional(Optional<Integer> optionalNum) {
Optional<Integer> num = optionalNum
.or(() -> Optional.of(3));
}
- stream: Optional 안에 값이 있으면 원소 1개의 Stream, 값이 없으면 비어 있는 Stream으로 변환해주는 기능입니다.
public static void optional(Optional<Integer> str) {
Stream<Integer> stream = str.stream();
}
Stream
- takeWhile: filter와 비슷한 기능으로 false가 나오는 순간 뒤의 데이터는 모두 버립니다.
Stream.of(10, 5, 15, 3, 20)
.takeWhile(num -> num <= 10)
.collect(Collectors.toList());
// 15를 만나는 순간 뒤의 데이터는 모두 버립니다.
- dropWhile: takeWhile과 비슷하지만 반대로 동작합니다. 즉, 조건이 true인 경우 데이터를 버리고 false를 만나면 모두 남깁니다.
Stream.of(10, 5, 15, 3, 20)
.dropWhile(num -> num <= 10)
.collect(Collectors.toList());
// 10, 5는 버리고 15가 나오는 순간 뒤의 데이터를 모두 남깁니다.
- ofNullable: null이면 비어 있는 Stream, 값이 있으면 원소가 하나인 Stream을 생성합니다.
Stream.ofNullable("ABC");
- Stream.iterate(): 기존 iterate()에서 제약조건을 추가할 수 있게 되었습니다.
// 기존
Stream.iterate(0, i -> i + 2)
.limit(5) // limit이 없으면 무한 스트림이 됩니다.
.forEach(System.out::println);
// 개선된 Stream.iterate()은 제약조건을 넣을 수 있습니다.
Stream.iterate(0, i -> i < 10, i -> i + 2)
.forEach(System.out::println);
CompletableFuture API
Java 8의 CompletableFuture에 다음과 같은 기능들이 추가되었습니다.
- CompletableFuture 복사 기능
- default Executor를 가져오는 기능
- 타임아웃 / 지연 실행 기능
Process API
운영 체제 프로세스를 제어하고 관리하기 위한 Process API가 개선되었습니다.
- Process: 프로세스 자체를 표현합니다.
- ProcessHandle: 프로세스를 제어하는 기능들이 존재합니다.
- ProcessHandle.Info: 프로세스 관련 세부 정보를 제공합니다.
StackWalker API
해당 시점의 스택 프레임을 제어하는 기능이 추가되었습니다.
public class Main {
public static void main(String[] args) {
callA();
}
private static void callA() {
callB();
}
private static void callB() {
callC();
}
private static void callC() {
List<String> walk = StackWalker.getInstance()
.walk(s -> s.map(StackWalker.StackFrame::getMethodName)
.collect(Collectors.toList()));
for (String s : walk) {
System.out.println("Stack : " + s);
}
}
}
/* [실행결과]
Stack : callC
Stack : callB
Stack : callA
Stack : main
*/
Compact Strings
Java 9에서는 String 클래스의 내부 표현 방식이 char[] 배열에서 byte[] 배열로 변경되었습니다. 문자열이 Latin-1 문자만 포함하는 경우 1바이트로, 그 외의 경우 2바이트로 저장됩니다. 이를 통해 메모리 사용량을 최대 50%까지 줄일 수 있습니다.
Flow API
리액티브 프로그래밍 지원을 위한 Flow API가 추가 되었습니다. Flow API란 리액티브 스트림즈 인터페이스가 JDK 표준으로 들어온 것입니다.
- 리액티브 핵심철학: https://www.reactivemanifesto.org/
- 리액티브 스트림즈: 리액티브 프로그래밍을 위한 라이브러리 표준 (인터페이스)
- 리액티브 프로그래밍: 응답이 빠르고, 탄력성과 회복성이 좋으며, 메시지 기반으로 통신하는 비동기 non-blocking 방식의 프로그래밍
- Sample Code
RxJava | reactor | Flow API | |
JDK 버전 | 8 미만에서 사용 가능 | 8 이상에서만 사용 가능 | 9 이상에서만 사용 가능 |
활용 | 클라이언트 | Spring Webflux | 호환성, 표준 라이브러리 |
리액티브 스트림즈 | 약간 다르다 | 완전히 동일 | 완전히 동일 |
반응형