반응형

1. 서론

 

이번 포스팅에서는 Modern Java In Action 의 1장인 자바 8, 9, 10, 11 : 무슨 일이 일어나고 있는가? 에 대해 알아보도록 하겠습니다.

 

2. 왜 아직도 자바는 변화하는가?

프로그래밍 언어 생태계는 끊임없이 변화하고 있습니다.

이러한 생태계에서 살아남기위해 프로그래밍 언어들은 계속 발전을 해왔고, 자바도 그 중 하나입니다.

 

자바는 살아남기 위해 무엇을 발전했는지 아래 설명하도록 하겠습니다.

 

 

1) 스트림 처리

 

자바8에서 java.util.stream 패키지가 추가되었습니다.

 

이 패키지에 있는 기능들은 리눅스의 파이프라인과 동일하다고 생각하시면 편합니다.

 

아래는 리눅스의 파일을 읽어 소문자로 변경하고 정렬하여 마지막 3줄만을 출력하는 command입니다.

 

cat file1 | tr "[A-Z]" "[a-z]" | sort | tail -3

 

각 파일읽기, 소문자 치환, 정렬 같은 일련의 작업을 ' | ' 사용하여 연결하는 것을 볼 수 있습니다.

 

이와 같이 자바 8에서도 Stream 패키지를 통해 각각의 작업을 하나의 일련의 작업으로 만들 수 있게 제공하고 있습니다.

 

 

2) 동작 파라미터화로 메서드에 코드 전달하기

 

자바 8에서는 메서드를 다른 메서드로 전달할 방법이 없었습니다.

 

하지만 자바 8에서 이를 지원하도록 개선되었고 이를 통해 복잡한 코드구조가 사라지게 되었습니다.

 

아래는 대표적인 메서드에 코드를 전달할 수 있는 함수형 인터페이스입니다.

패키지는 java.util.function 입니다.

 

  • Predicate
  • Consumer
  • Supplier

 

3) 병렬성과 공유 가변 데이터

 

자바 8에서는 스트림API를 지원하면서 간단히 병렬성을 가져갈수 있도록 제공하고 있습니다.

하지만, 이를 위해서는 멀티 쓰레드 환경에서도 서로 코드를 동시에 수행하더라도 안전하게 바꿔야하는 번거로움이 존재합니다.

 

스트림 함수 사용 시 외부접근 데이터를 Atomic한 객체로 만들어 사용해야 합니다.
이는, 위의 안전한 코드여야 하기 때문입니다.

 

 

 

 

 

반응형

 

 

 

 

 

3. 자바 함수

 

프로그래밍 언어에서 함수라는 용어는 메서드와 같은 의미로 사용됩니다.

자바 8에서는 이러한 메서드를 일급시민으로 올리도록 제공하고 있습니다.

 

일급시민이란, 각 구조체의 값을 전달할 수 있는 것을 의미합니다.

그러므로, 위의 메서드를 일급시민으로 올린다는 의미는 메서드라는 구조체의 값을 다른 구조체에게 전달할 수 있다는 의미입니다.

 

1) 메서드와 람다를 일급시민으로

 

1 - 메서드 참조

 

자바8 에서는 메서드참조를 제공합니다.

 

아래는 숨겨진 파일들만을 filter하여 얻어오는 코드입니다.

File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
	@Override
	public boolean accept(File pathname) {
		return pathname.isHidden();
	}
});

 

위의 코드는 자바 8이 나오기전의 코드입니다.

 

자바 8에서는 람다와 메서드 참조를 제공하였고 그 결과 아래와 같이 더욱 readable 있는 코드로 리팩토링이 가능해졌습니다.

 

File[] hiddenFiles = new File(".").listFiles(File::isHidden);

 

람다를 통해 익명클래스를 간단하게 바꾸었으며, ::isHidden 인 메서드 참조를 통해 한결 간단해진 코드가 되었습니다.

 

 

2- 코드 넘겨주기

 

 

아래는 사과 리스트에서 초록색이며, 무게가 200이 넘는 사과만 분류하는 코드입니다. - 자바 8 이전

 

private enum Color {
    GREEN,
    RED
}

public static void main(String[] args) {
    List<Apple> appleList = Arrays.asList(new Apple(Color.RED, 200), new Apple(Color.GREEN, 30), new Apple(Color.GREEN, 300));
    final List<Apple> filterdGreenAppleList = filterGreenApples(appleList);
    final List<Apple> filterdGreenWithHeavyAppleList = filterHeavyApples(filterdGreenAppleList, 200);
}

@Getter
@RequiredArgsConstructor
private static class Apple {
    private final Color color;
    private final int weight;
}

private static List<Apple> filterGreenApples(List<Apple> apples) {
    List<Apple> result = new ArrayList<>();
    for(Apple apple: apples) {
        if(Color.GREEN.equals(apple.getColor())) {
            result.add(apple);
        }
    }
    return result;
}

private static List<Apple> filterHeavyApples(List<Apple> apples, int weight) {
    List<Apple> result = new ArrayList<>();
    for(Apple apple: apples) {
        if(apple.getWeight() > weight) {
            result.add(apple);
        }
    }
    return result;
}

 

하지만, 자바 8의 스트림 함수와 람다를 사용하면 아래와 같이 간단하게 바뀔 수 있습니다.

 

public static void main(String[] args) {
    List<Apple> appleList = Arrays.asList(new Apple(Color.RED, 200), new Apple(Color.GREEN, 30), new Apple(Color.GREEN, 300));
    final List<Apple> filterdGreenWithHeavyAppleList = appleList
            .stream()
            .filter(apple -> Color.GREEN.equals(apple.getColor()))
            .filter(apple -> apple.getWeight() > 200)
            .collect(Collectors.toList());
}

 

단, filter 에 있는 조건들이 일회성이 아니라면 별도 함수로 추출해서 사용해야 합니다.

 

4. 스트림

이전 옛날 자바에서는 한개의 CPU만을 사용하는 단점이 있었습니다.

하지만 자바 8에서는 한개가 아닌 멀티 CPU를 점유해서 사용하도록 변경되었고 이는 성능의 극대화를 가져다 주었습니다

 

대표적으로 parallelStream 을 들 수 있습니다.

parallelStream은 멀티 CPU를 통해 분할로 처리할때 사용합니다.

 

단, Parallel Stream 작업이 독립적이면서 CPU사용이 높은 작업에 사용해야합니다.

 

5. 디폴트 메서드와 자바 모듈

자바 8에서는 인터페이스에 디폴트 메서드를 제공합니다.

 

디폴트 메서드는 기존의 코드를 수정하지 않고 확장하기 위해서 만들어진 것이며,

간단하게 인터페이스에도 기본적으로 정의된 구현 메서드가 있을 수 있다고 생각하면 됩니다.

 

아래는 List의 default sort 함수입니다.

 

default void sort(Comparator<? super E> c) {
    Object[] a = this.toArray();
    Arrays.sort(a, (Comparator) c);
    ListIterator<E> i = this.listIterator();
    for (Object e : a) {
        i.next();
        i.set((E) e);
    }
}

 

6. 함수형 프로그래밍에서 가져온 다른 유용한 아이디어

 

자바 8에서 제공되는 기능들은 대체로 함수형 프로그래밍 특성을 가져다 주는 것입니다.

이런 함수형 프로그래밍의 패러다임을 가져오면서 많은 프로그램에 도움이 되는 아이디어가 나왔습니다.

 

한가지 예로, null을 회피하는 방법이며 자바에서는 Optional<T> 라는 컨테이너 클래스를 통해 제공하고 있습니다.

 

7. 마무리

이번 포스팅에서는 자바 8부터의 변화에 대해 간단한 소개와 설명을 했습니다.

다음에는 동작 파라미터화 코드 전달에 대해 포스팅하겠습니다.

반응형

'Programming > ModernJavaInAction' 카테고리의 다른 글

(6) 스트림으로 데이터 수집  (0) 2020.04.04
(5) 스트림 활용  (0) 2020.04.04
(4) 스트림 소개  (0) 2020.03.28
(3) 람다 표현식  (0) 2020.03.28
(2) 동작 파라미터화 코드 전달하기  (0) 2020.03.21

+ Recent posts