'''
이 블로그를 많이 참고하였습니다.
https://bbubbush.tistory.com/23
https://coding-start.tistory.com/355 [코딩스타트]
https://www.javacodegeeks.com/2020/12/jdk-16-stream-to-list-in-one-easy-call.html
https://velog.io/@gkskaks1004/Java-16%EC%97%90%EC%84%9C-instanceof-%EC%97%B0%EC%82%B0%EC%9E%90%EC%97%90-%EB%8C%80%ED%95%9C-pattern-matching
https://www.youtube.com/watch?v=7SlDdzVk6GE
https://www.youtube.com/watch?v=GJB-RyHKHjY
감사합니다.
##### 자바8 #####
1. 람다 표현식
- 람다 파라미터 (어떤 값이 들어가면) -> 람다 바디 (결과물이 나온다.)
- 예시
(String str) -> System.out.println("parameter is " + str);
// 타입 생략 가능
(str) -> Sytem.out.println("parameter is " + str);
// 괄호 생략 가능, 단 파라미터가 1개일 경우
str -> System.out.println("parameter is " + str);
// 람다 바디가 긴 경우, return 키워드 필요
(i) -> {
int result = i + 10;
return result;
}
// 파라미터가 없는 경우, 빈 괄호를 명시적으로 표시
2. 함수형 인터페이스
- 단 하나의 추상 메서드를 갖는 인터페이스이다.
- 대표적으로 Runnable 인터페이스는 추상메소드 run() 하나만 가진다.
- 예시
public interface Car {
String drive(int driveLevel);
}
// 익명 클래스 구현
Car car = new Car() {
@Override
public String drive(int driveLevel) {
return driveLevel == 0 ? "" : "자동차가 " + driveLevel + " 의 속도로 이동합니다.";
}
}
System.out.println(car.drive(10));
// 람다 표현식으로 간결화
Car car = (i) -> i ==0 ? "" : "자동차가 " + i + " 의 속도로 이동합니다.";
3. 디폴트 메서드
- default 키워드 이용
- 인터페이스에서 구현된 메서드를 만들 수 있다.
- 기존의 인터페이스 기반으로 구현된 구현체들의 변경 없이 공통적인 기능을 추가할 때 사용한다.
- 인터페이스 기반으로 구현할 때 사용하지 않는 메서드를 빈 상태로 두는 경우, 디폴트 메서드를 사용하면 불필요한 코드를 줄일 수 있다. 필요한 구현체에서만 Override 하여 사용할 수 있따. 그러나 인터페이스가 같는 추상 메서드 구현의 강제성이 사라지므로 주변 담당자에게 노티가 필요하다.
- 예시
public interface SampleInterface {
String returnHello(String msg);
default void hello(String msg) {
System.out.println("hello " + msg);
}
default void notAllwaysUsed() {
}
}
4. 스트림
- Collection을 편리하게 처리하는 기능을 제공하는 API 이다.
- 병렬처리, 직관적인 코드를 제공한다.
- for if 문 코드를 스트림으로 변경한 예시
List<String> booksWrittenByNietzsche =
books.stream()
.filter(book -> book.getAuthor().equals("Friedrich Nietzsche"))
.sorted(Comparator.comparing(Book::getName))
.map(Book::getIsbn)
.collect(Collectors.toList());
- 파이프라이닝 지원 filter(), sorted(), map(), collect()
- '내부' 반복을 지원한다. for문 없이 비지니스 로직에 집중한 코드 작성 가능
- 연산 중간 값을 저장하지 않는다.
- lazy 방식으로 동작한다. 스트림은 종료연산이 있어야만 실행된다.
- 중간연산? Stream<T> 형태의 스트림이 반환된다. ex. filter(), sorted()
- 종료연산? 중간연산이 아니면 모두 종료연산이다. ex. foreach(), count(), collect()
5. 옵셔널
- null 발생 가능성을 막음
- if null을 판단하는 과정을 optional로 대체하여 비지니스로직을 파악하기 좋다.
- 객체를 Optional로 감싸는 메서드 : of, ofNullable, empty
- 중간 연산 : filter, map, flatMap
- 종료 연산 : get, orElse, orElseGet, orElseThrow
- 기타 : isPresent, ifPresent
**
of : 파라미터가 null이면 npe
ofNullable : 파라미터가 null이면 Optional 반환
empty : 중간 연산 중 null이되면 호출되는 메소드
**
filter : stream의 filter와 동일
map : stream의 map과 동일
flatMap : optional 안의 optional이 있는 이중 구조일 때, 단일 구조로 변경하여 map() 수행
**
get : optional 반환. 빈값이면 npe
orElse : get과 동일, 값이 비어있다면 파라미터에서 제공하는 값 반환
orElseThrow : get과 동일, 값이 비어있다면 파라미터에서 생성한 exception 발생
**
isPresent : optional 값이 비어 있다면 true, 비어있으면 false. 상태를 확인할 뿐 값에 어떤 영향도 미치지 않는다.
ifPresent : optional 값이 없다면 파라미터를 실행하고, 비어있다면 false를 반환한다.
6. 날짜 API
- 기존 Date, Calendar 문제 보완. Date 객체는 1월이 0으로 표기됨
- 기계용 : Instant (초)
- 사람용 : LocalDate, LocalTime, LocalDateTime
LocalDateTime plusTenDay = LocalDateTime.now().plusDays(10L);
- 간격 : Duration(시간 차이), Period(날짜 차이-LocalDate만 파라미터로 사용)
Duration duration = Duration.between(now, newYear);
System.out.println(duration.getSeconds());
Period period = Period.between(now.toLocalDate(), newYear.toLocalDate());
System.out.println(period.getDays());
- 포맷 : DateTimeFormatter
7. 컴플리터블 퓨처
- 비동기프로그래밍이 갖고 있는 단점을 개선
- 생성한 스레드가 동작중인지, 정상적으로 종료인지, 예외가 발생했는지 메인스레드에서 알기 어려운 점을 보완
- 자바5에서 Future 클래스를 제공한다. (미래 시점에서 결과를 사용할 수 있다.)
** Future : Thread 보다 직관적이고, 스레드 풀도 직접 정하고, timeout도 설정 가능하다.
예외처리를 위한 try-catch, Future의 동작을 외부에서 강제종료가 불가능하다.
get()이 블로킹 코드이기 때문에 기다려야 한다. 다른 스레드의 결과 값이 필요할 때는 이런 방식이 괜찮지만, 결과 값이 불필요할 때는 비동기로 처리해야 한다.
** CompletableFuture : 예외처리 지원메서드, 순서의존관계맺는 스레드프로그래밍, 콜백지원
CompletableFuture<Integer> lowPriceSearchFuture = CompletableFuture.supplyAsync(() -> {
int bookPrice = Enterpark.getBookPrice();
System.out.println("Enterpark : " + bookPrice);
return bookPrice;
})
.thenCombine(CompletableFuture.supplyAsync(() -> {
int bookPrice = Illidan.getBookPrice();
System.out.println("Illidan : " + bookPrice);
return bookPrice;
}), (enterpartBookPrice, illidanBookPrice) -> printPriceAndBookstore(enterpartBookPrice, illidanBookPrice))
.exceptionally(throwable -> {
System.out.println(throwable.getMessage());
return -1;
});
lowPriceSearchFuture.get(3, TimeUnit.SECONDS);
8. JVM
- 기존 PermGen 영역 제거, Metaspace 영역 추가
** PermGen : 클래스의 메타정보 관리하는 메모리 공간 (클래스 이름, 어노테이션, 필드 등)
힙 메모리에 저장되어서 oop 발생 가능성 있었다.
** Metaspace : 동일한 기능을 한다. 힙 영역이 아니라 metaspace 영역이 가변적으로 늘어나 수용 가능하다.
oom 발생할 여지가 줄어들었다.
##### 자바9 #####
1. 인터페이스 private 메서드 추가
2. try-catch에서 try(final 타입 변수면 넣을 수 있다.)
3. 콜렉션 팩토리 메소드
- List.of, Map.of, Set.of
4. Arrays.comapre, mismatch
- 배열 비교
- 배열이 몇 번 인덱스에서 다른지
##### 자바10 #####
1. var
- 로컬변수를(필드,파라미터변수x) 타입 생략하고 변수 선언
- 11에서는 람다식에 사용가능하다.
##### 자바11 #####
1. String 메소드 추가
- isBlank() : 공백문자만 포함했는지
- lines() : 스트림으로 각 라인을 사용
- repeat() : 반복하여 문자열 생성
stript(), stripLeading(), stripTrailing() : 제거
2. Files 메소드 추가
- writeString() : 지정 경로에 문자열을 파일로 저장
- readString() : 지정 경로에서 문자열을 읽어온다.
##### 자바12 #####
1. String 메소드 추가
- indent(int n) : 들여쓰기, 내어쓰기
- transform() : 문자열을 원하는 포맷으로 변경
##### 자바14 #####
1. switch
- case 문에서 값을 생성할 수 있다.
- 화살표 표현을 써야한다.
##### 자바15 #####
1. 텍스트 블록
- """, """ 여러줄에 걸쳐 문자열을 입력하기 위함
2. formatted()
- String.format 대신
3. NPE 메세지 개선
- 자세해짐
##### 자바16 #####
1. 스트림 메소드 추가
- toList
Stream.collect(Collectors.toList()): list 원소 추가 정렬 가능
Stream.toList() : list 원소 추가 정렬 불가능
- mapMulti
파라미터를 받아서 결과 여러 개를 생성
2. instanceof와 패턴 매칭
- 자바8 : instanceof 인지 확인 후, casting 실행문이 필요
- 자바16 : obj instanceof Student student
3. record 클래스
- 자바14 에 도입, 자바16에서 정식 인정
- 순수하게 데이터를 보유학 위한 클래스
- entity, dto 클래스를 생성할 떄 좋다.
public record SampleRecord(
String name,
Integer age,
Address address
) {}
- private final 멤버변수, requiredAllArgument todtjdk, getter 필드 ㅇ,;ㅁ;
- final 클래스라 상속 불가능
- json serialize 위해 각 필드에 @JsonProperty("name") String name, 처럼 표현한다.
- static 변수, 메소드 + public 메소드를 가질 수 있다.
- 생성자를 명시적으로 만들어 유효성검사도 가능하다.
##### 자바17 #####
1. sealed 클래스 인터페이스
- 상속할 수 있는 타입을 제한한다.
public sealed interface FList<T> permits Cons, Empty {
}
- 상속받는 조건
final, sealed, non-sealed, record 키워드 필요
같은 패키지 또는 모듈에 위치 필요
2. switch case문에서 패턴 매칭 가능
Book Review/Effective Java