럿고의 개발 노트
자바 8의 새로운 개념과 기능 본문
자바 8의 새로운 개념과 기능
- 멀티코어 CPU가 대중화 되면서 자바는 병렬 실행에 대해서 고민하게 되었다.
- 그 전에는 나머지 코어를 활용할 수 있는
Thread
가 있었지만, 관리와 사용이 너무 어렵다는 단점이 있었다. - 자바 8에서 병렬 실행을 새롭게 단순한 방식으로 접근할 수 있는 방법을 제공했으며 그것이
Stream
이다. - 또한 자바 8에서는 간결한 코드와 멀티코어 프로세서의 쉬운 활용이라는 두 가지 요구사항을 기반으로 새로운 기능들이 나타났다.
1. 스트림 API
- 스트림이란 한 번에 한 개씩 만들어지는 연속적인 데이터 항목의 모임이다.
- 이론적으로 프로그래밍은 입력 스트림에서 한 개씩 읽고 출력 스트림에서 데이터를 한 개씩 기록한다.
- 또한 어떤 프로그램의 출력 스트림은 다른 프로그램의 입력 스트림이 될 수도 있다.
- 자바 8에서는 병렬로 지원하는
java.util.stream
패키지를 추가하였다. - 기존에는 한 번에 한 항목씩 처리했지만, 위의 작업을 구수준으로 추상화해서 일련의 스트림으로 만들어 처리할 수 있는 것이다.
- 스레드를 사용하지 않아도 병렬성을 얻을 수 있게 되었다.
- 또한 컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드 문제와 멀티코어 활용 어려움이라는 두가지 문제를 동시에 해결하게 되었다.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FilteringApples {
private final static List<Apple> inventory = Arrays.asList(
new Apple(80, "red"),
new Apple(155, "green"),
new Apple(120, "green")
);
// 순차 처리 방식
final static List<Apple> heavyApples1 = inventory.stream().filter((Apple apple) -> apple.getWeight() > 150).collect(Collectors.toList());
// 병렬 처리 방식
final static List<Apple> heavyApples2 = inventory.parallelStream().filter((Apple apple) -> apple.getWeight() > 150).collect(Collectors.toList());
}
2. 메서드 참조
자바는 메서드나 클래스 등은 이급 시민이였다. 즉, 프로그램을 실행하는 동안 모든 구조체를 자유롭게 전달할수 없는 것이다.
그래서 자바는 함수형 프로그래밍에서 제공하는 메서드를 일급값으로 사용할 수 있는 기능을 만들었다.
예제 코드
public class HiddenFiles{ // java 8 이전 코드 File[] hiddenFiles = new File(".").listFiles(new FileFilter() { @Override public boolean accept(File file) { return file.isHidden(); } }); // java 8 메서드 참조 이용 코드 File[] hiddenFiles = new File(".").listFiles((File)::isHidden); }
이와 같이, 예전에 객체를 참조해서 객체를 이리저리 주고 받은 것 처럼, 메서드 참조를 이용해 메서드도 똑같은 기능을 할 수 있는 것이다.
3. 람다
- 메스드를 일급값으로 취급할 뿐 아니라 람다(익명함수)를 포함하여 함수도 값으로 취급할 수 있게 되었다.
- 람다 문법 형식으로 구현된 프로그램을 함수형 프로그래밍 즉,
함수를 일급값으로 넘겨주는 프로그래밍
이라고 한다.
public class filter{
public static List<Apple> filterGreenApples(List<Apple> inventory){
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory){
if("green".equals(apple.getColor())){
result.add(apple);
}
}
return result;
}
public static List<Apple> filterHeavyApples(List<Apple> inventory){
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory){
if(apple.getWeight() > 150){
result.add(apple);
}
}
return result;
}
}
- 자바 8 이전에는 이런식으로 비슷한 기능을 하는 메서드들을 중복코드가 보이도록 구현했어야 했다.
- 그러나 자바 8에서는 중복 코드를 최소화 할 수 있게 되었다.
public class Apple {
private int weight;
private String color;
public Apple(int weight, String color) {
this.weight = weight;
this.color = color;
}
public int getWeight() {
return weight;
}
public String getColor() {
return color;
}
public static boolean isGreenApple(Apple apple){
return "green".equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple){
return apple.getWeight() > 150;
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FilteringApples {
private final static List<Apple> inventory = Arrays.asList(
new Apple(80, "red"),
new Apple(155, "green"),
new Apple(120, "green")
);
public interface Predicate<T>{
boolean test(T t);
}
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;
}
public static void main(String[] args) {
filterApples(inventory, (Apple apple) -> "green".equals(apple.getColor()));
filterApples(inventory, (Apple apple) -> apple.getWeight() > 150);
}
}
- 이런식으로
Predicate
를 이용해서 함수형 프로그래밍을 구현할 수 있다. - 아울러 한번만 사용할 메서드를 따로 구현할 필요가 없어졌다.
- 그러나 람다가 길어진다면 가독성이 떨어지는 현상이 있기 떄문에, 이를 잘 설명하는 메서드명을 지정해서 메서드 참조를 하는 것이 더 좋다.
4. 인터페이스 디폴트 메서드
- 디폴트 메서드는 구현 클래스에서 구현하지 않아도 되는 메서드를 인터페이스에 추가할 수 있는 기능을 제공한다. 메서드 본문은 클래스 구현이 아니라 인터페이스의 일부로 포함된다.- 인터페이스를 쉽게 변경할 수 있도록 디폴트 메서드를 지원하게 되었다.
- 그러나 디폴트 메서드를 사용하는 상황은 흔치 않다. 미래를 위한 기능이기 떄문이다.
정리
- 자바 8은 프로그램을 더 효과적이고 간결하게 구현할 수 있는 새로운 개념과 기능을 제공한다.
- 스트림의 개념의 일부는 콜렉션에서 가져왔다. 스트림과 컬렉션을 적절하게 활용한다면 스트림의 인수를 병렬로 처리도 가능하며 가독성도 좋은 코드가 완성될 것이다
- 책정보
'Java Note > 모던 자바 인 액션(Modern Java in Action)' 카테고리의 다른 글
동작 파라미터화 (0) | 2020.03.11 |
---|
Comments