Java/Java8

(JAVA8) Java8 개요

주누 2019. 11. 11. 15:22

자바8을 사용해야하는 이유

  1. 자연어에 가까운 간단한 방식으로 코드 구현 가능
  2. 병렬 실행 환경의 새롭고 단순한 방식을 지원

예1. 스트림 처리

리눅스 or 유닉스의 경우

cat file1 fil2 | tr "A-Z" "a-z" |sort| tail -2

  • sort는 여러행의 스트림을 입력받아 병렬로 처리한다. (->여러행의 스트림을 출력)
    • cat, tr, sort, tail은 모두 병렬로서 처리된다.

이처럼 자바8의 스트림 API는 한번에 처리하던 기존방식을 탈히여 병렬로 처리하게끔 도와준다.(스레드 사용X)

 

예2. 메세지에 코드 전달하기

 

 

 

 

 

 

 

 

 

 

sort를 처리하는 메서드를 통으로 파라미터로 전달하기


예3. 간결화된 코드(like ::)

/*예시코드(파일 경로 찾기)*/
File[] hiddenFiles = new File(".").listFiles(new FileFilter(){
   public boolean accept(File file){
       return file.isHidden();
   } 
});

위의 코드는 굳이 accept 메서드로 묶어서 isHidden()의 결과를 리턴한다.(자바 8이전에는 어쩔수 없음)

 

 

내부소스 파헤치기!

->listFiles가 해당 인터페이스를 파라미터로 받기 때문에 구현이 강제되어 진다.
-> 여기서 파라미터에 주목! 받는 파라미터의 타입이 인터페이스이다.
-> 해당 메서드의 결과를 File Class 내부에 있는 ishidden()으로 return

 

aceept로 감싸지 않고 직관적으로 표현하는 방법이 만들어짐.

 

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

예4. 람다의 등장

난 잘 모르겠다. 위에 :: 처럼 클래스를 만들어서 쓰면 되는 것 아닌가?

 

 

자바8 이전 예시코드

 

자바8 예시코드

 

하지만 이렇게 한번만 사용하고 쓸 메서드를 사용할때마다 정의하는 것이 비효율적이라고 판단.

 

(람다식은 위의 문제점을 개선 해줄 수 있음. - 아래코드 참조)

filterApples(inventory, (Appla a) -> "green".equals(a.getColor()));

filterApples(inventory, (Appla a) -> a.getWeight()>150);

filterApples(inventory, (Appla a) -> a.getWeight()>150 || "green".equals(a.getColor()));
  • 익명의 클래스로 정의

but! 람다식의 코드가 길어 진다면 이전의 방법으로 "::" 를 써서 사용하자!


예5. 스트림의 등장

[자바 8 이전의 멀티스레드의 문제점]

 

스레드1이 쓰는 도중 스레드 2가 읽어버리면 예상하지 못한 값이 발생하게 된다.

 

기존 자바의 문제점 두가지

  1. 컬렉션을 처리하면서 발생하는 반복적, 모호한 코드 발생
  2. 멀티코어 활용의 어려움

해당 문제를 [1. 필터링 2.추출 3. 그룹화] 로 해결가능

컬렉션과 스트림의 차이

컬렉션 : 데이터를 어떻게 저장하고 접근할지에 집중

스트림 : 데이터를 어떻게 계산할지에 집중

멀티코어 활용의 어려움의 문제를 스트림이 해결가능 하다.

why?

스트림내의 요소들이 병렬로 쉽게 처리하게금 도와주기 떄문

그럼 스트림은 어떻게 사용하는가?

주요 흐름

컬렉션 -> 스트림(병렬처리) -> 다시 컬렉션변환

 


예6. 디폴트 메서드

 

 

위의 코드는 자바8 이전에는 컴파일 불가 : 리스트가 stream(), parrellelStream()을 지원x

굳이 구현을 해야한다면?

  1. Collection interface에 stream(), parrellelStream()을 추가
  2. ArrayList에서 구현

이 방법은 새로운 메서드가 interface에 추가될때마다

해당 interface를 상속받는 모든 class는 추가된 method를 구현해야한다는 단점이 있다.

-> 클래스의 구현이 아닌 interface의 일부로 보는 Defaultmethod 탄생

 

 

List<Apple> heavyApples1 = 
    inventory.stream().filter((Apple a)->a.getWeight()>150)
    							.collect(toList());
List<Apple> heavyApples2 = 
    inventory.parallelstream().filter((Apple a)->a.getWeight()>150)
    							.collect(toList());

동적 파라미터화 (유지보수에 용이)

  1. 아직 어떻게 실행될지 모르는 코드 실행 block
  2. 나중에 프로그램에서 호출(like callback?)

 

자바8 이전의 방식의 한계(예시)

1. 특정 색깔의 사과 필터링

문제점 : 녹색사과만 필터링 가능

 

2. 파라미터로 색깔을 받아서 필터링

문제점 : 중복된 코드의 발생

3. boolean 값을 이용한 필터링

문제점 : 만약 무게, 색깔 말고 다른 요구사항이 생긴다면 ... true false 로 구별하기 힘들어진다.


문제점 해결을 위한 도구 : 전략디자인패턴

 

전략디자인 패턴이란?

캡슐화하는 알고리즘 패밀리를 정의하고 다음 런타임에 알고리즘을 선택

 

개선사항 : Applepredicate가 다양한 동작을 수행하도록 하기 위해

              filterApples 메서드가 Applepredicate를 받도록 설계

 

결론 : Applepredicate를 상속받는 특정 객체를 filterApples 에 전달하면서

 해당메서드의 실행결과를 결정짓는다.

간단하게.. 동작 파라미터화는 메서드를 파라미터로 넘기는 작업이라 할 수 있음.

 


[익명 클래스로 좀더 가독성 높은 코드를 구현해보자]

나의생각: 익명클래스느 한번쓰고 버릴 코드라 재사용이 힘든데 다형성 문제는 어떻게 해결할 것인가?

  • 현재 코드를 1)익명클래스 2) 람다식 으로 바꾸어가는 과정

밑의 람다식을 보면 test메서드로 감쌀 필요가 없다.(이전의 File()메서드로 감싸지 않았던것과 동일한 효과)

 


리스트 형식으로 추상화 : : 현재 code는 Apple만이 동작하도록 한정되어있음.

 


References

자바 8 인 액션
국내도서
저자 : 라울-게이브리얼 우르마(RAOUL-GABRIEL URMA),마리오 푸스코(MARIO FUSCO),앨런 마이크로프트(ALAN MYCROFT) / 우정은역
출판 : 한빛미디어 2015.04.01
상세보기