[Modern Java In Action] ch1 - 자바 8, 9, 10, 11
ch1. 자바 8, 9, 10, 11
1. 역사의 흐름은 무엇인가?
자바 역사를 통틀어 가장 큰 변화가 자바 8에서 일어났다.
자바 8은 어떤 변화를 불러왔는가?
Collections.sort(inventory, new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compareTo(a2.getWeight());
}
});
inventory.sort(comparing(Apple::getWeight));
2. 왜 아직도 자바는 변화하는가?
프로그래밍 언어의 세계는 생태계와도 같고 진화하지 않으면 도태되어 사라집니다.
그러므로 자바는 자바 8, 9, 10, 11.. 계속해서 발전 했고, 가장 큰 발전이었던 자바 8의 밑바탕을 이루는 세 가지 프로그래밍 개념을 알아보겠습니다.
1. 스트림
- 스트림 : 한 번에 한 개씩 만들어지는 연속적인 데이터 항목들의 모임
2. 동작 파라미터화로 메서드에 코드 전달하기
- 동작 파라미터화 : 메서드를 변수처럼 다른 메서드의 파라미터로 던짐으로써 메서드가 다양한 동작을 수행할 수 있게 합니다.
3. 병렬성과 공유 가변 데이터
- 다른 코드와 동시에 실행하더라도 안전하게 실행할 수 있는 코드를 만드려면 함수를 순수함수, 부작용 없는 (side-effect-free) 함수, 상태 없는 (stateless) 함수를 만들어야 합니다.
- 순수함수 : 공유 가변 데이터에 접근하지 않아야 합니다.
3. 자바 함수
1. 메서드와 람다를 일급 시민으로
- 메서드 참조 : 메서드를 값으로 참조할 수 있습니다.
::
을 이용하면 가능합니다. - 람다 : 익명 함수.
(int x) -> x + 1
은x라는 인수를 호출하면 x+1을 반환
이라는 동작을 수행하는 람다이다.
자바의 메소드 전달과 람다 예시
class Apple{
public static void main(String[] args) {
List<Apple> inventory = new ArrayList<>();
inventory.add(new Apple(80, "green"));
inventory.add(new Apple(155, "green"));
inventory.add(new Apple(120, "red"));
//메서드 전달
List<Apple> heavyApples = filterApples(inventory, Apple::isHeavyApple);
List<Apple> greenApples = filterApples(inventory, Apple::isGreenApple);
//람다
List<Apple> heavyApples = filterApples(inventory, (Apple a) -> a.getWeight() > 150);
List<Apple> greenApples = filterApples(inventory, (Apple a) -> "green".equals(a.getColor()));
}
public static boolean isHeavyApple(Apple apple) {
return apple.getWeight() > 150;
}
public interface Predicate<T> {
boolean test(T t);
}
public static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (p.test(apple)) {
result.add(apple);
}
}
return result;
}
}
4. 스트림
스트림 적용전 ⛔️
Map<Currency, List<Transaction>> transactionsByCurrencies = new HashMap<>();
for (Transaction transaction : transactions) {
if (transaction.getPrice() > 1000) {
Currency currency = transaction.getCurrency();
List<Transaction> transactionsForCurrency = transactionsByCurrencies.get(currency);
if (transactionsForCurrency == null) {
transactionsForCurrency = new ArrayList<>();
transactionsByCurrencies.put(currency, transactionsForCurrency);
}
transactionsForCurrency.add(transaction);
}
}
스트림 적용후 ☘️
Map<Currency, List<Transaction>> transactionsByCurrencies = transactions.stream()
.filter((Transaction t) -> t.getPrice() > 1000)
.collect(groupingBy(Transaction::getCurrency));
멀티스레딩은 어렵다
- 자바 8의 스트림 API는 컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드 문제 그리고 멀티코어 활용의 어려움이라는 두 가지 문제를 모두 해결했다.
- 스트림과 람다를 사용하면 병렬성을 공짜로 얻을 수 있다. 아래 예시 코드가 있다.
// 순차 처리 List<Apple> heavyApples = inventory.stream() .filter((Apple a) -> a.getWeight() > 150) .collect(toList()); // 병렬 처리 List<Apple> heavyApples = inventory.parallelStream() .filter((Apple a) -> a.getWeight() > 150) .collect(toList());
5. 디폴트 메소드와 자바 모듈
- 자바 8은 구현 클래스에서 구현하지 않아도 되는 메서드를 인터페이스에 추가할 수 있는 디폴트 메소드라는 기능을 제공한다.
- 디폴트 메서드를 이용하면 기존의 코드를 건드리지 않고 인터페이스 설계를 자유롭게 확장할 수 있다.
댓글남기기