Java 8의 주요 변경 사항은 아래와 같다.
// 익명 클래스로 Runnable을 구현
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Start to new thread!");
}
});
thread.start();
// 람다 표현식으로 단순하게 표현
Thread thread = new Thread(() -> System.out.println("Start to new thread!"));
thread.start();
(String str) -> System.out.println("parameter is " + str);
// 타입을 생략한 코드
(str) -> System.out.println("parameter is " + str);
// 람다 파라미터 괄호를 생략한 코드
str -> System.out.println("parameter is " + str);
// 람다 바디를 하나의 라인으로 표현
(i) -> i + 10;
// 람다 바디를 여러 라인으로 표현
(i) -> {
int result = i + 10;
return result;
};
()-> Integer.MAX_VALUE;
@FunctionalInterface
interface Calculation {
Integer apply(Integer x, Integer y);
}
Calculation addition = (x, y) -> x + y;
Calculation subtraction = (x, y) -> x - y;
public interface SampleInterface {
// abstract method
String returnHello(String msg);
// default method
default void hello(String msg) {
System.out.println("hello " + msg);
}
}
스트림은 Collection(컬렉션)을 멋지고 편리하게 처리하는 방법을 제공하는 API이다. 별다른 노력 없이 병렬 처리도 제공해주며, 마치 데이터베이스 쿼리를 작성하듯 직관적인 코드를 제공해준다.
요구사항을 통해 스트림의 기능을 알아보자.
<요구사항>
"책들 중 니체가 작성한 책의 ISBN 정보가 필요합니다. 정렬은 책 이름을 기준으로 해주세요."
books.sort(Comparator.comparing(Book::getName));
List<String> booksWrittenByNietzsche = new ArrayList<>();
for (Book book : books) {
if (book.getAuthor().equals("Friedrich Nietzsche")) {
booksWrittenByNietzsche.add(book.getIsbn());
}
}
List<String> booksWrittenByNietzsche =
books.stream()
.filter(book -> book.getAuthor().equals("Friedrich Nietzsche"))
.sorted(Comparator.comparing(Book::getName))
.map(Book::getIsbn)
.collect(Collectors.toList());
public class BookService {
// 파라미터로 Book 객체를 받는다.
// Book 객체가 가진 Author객체의 getName()으로 저자의 이름을 반환한다.
public String getAuthorName(Book book) {
if (book == null) {
throw new NullPointerException("This book is null");
}
Author author = book.getAuthor();
return author.getName();
}
}
public class BookService {
// Optional을 사용하여 null에서 안전한 코드 작성하기
public Optional<String> getAuthorName(Book book) {
return Optional.ofNullable(book)
.map(bookObject -> bookObject.getAuthor())
.map(authorObject -> authorObject.getName());
}
}
// 현재 시간을 유닉스 에포크 시간으로 나타내는 코드 (모든 시간을 초로 환산하여 표시)
System.out.println(Instant.now().getEpochSecond());
// 유닉스 에포크 시간의 기준시를 나타내는 코드(기준시기 때문에 초로 환산해도 0으로 출력된다)
System.out.println(Instant.ofEpochSecond(0).getEpochSecond());
기존의 Date 클래스는 이름과 다르게 날짜, 요일은 물론 시간까지 포괄하는 정보를 갖는다. 이름이랑 맞지 않게 너무 많은 역할을 하게 되는 문제가 있다. 따라서 Java 8에서 날짜, 시간 별로 클래스를 분리시켰다. 이들은 기본적으로 다루는 정보가 다른 것 외에는 모두 동일한 사용법을 가지고 있어서 시간과 날짜를 모두 포함하는 LocalDateTime을 샘플로 코드를 작성했다.
날짜&시간을 String으로 표현하는 코드다.
// 현재 날짜와 시간을 String 값으로 표현
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
// 2021-01-01T12:00:00 을 String 값으로 표현
System.out.println(LocalDateTime.of(2021, 1, 1, 12, 0).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
// LocalDateTime 객체를 사용한 코드
LocalDateTime plusTenDay = LocalDateTime.now().plusDays(10L);
// Date 객체를 사용한 코드
Date today = new Date();
today.setDate(today.getDate() + 10);
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);
출처:
https://bbubbush.tistory.com/23
https://github.com/devSquad-study/2023-CS-Study/blob/main/java/java_eight_characteristic.md