기록.

자바8 소개 본문

Programming/Java

자바8 소개

Youngheon 2016. 4. 27. 17:48

본 자료는 자바카페 스터디 (04/09)에 진행된 자료이며

출처는 다음과 같습니다. http://www.slideshare.net/heungrae_kim/1-introduction-to-java8




자바8의 주요 변화

  • 람다표현식(Lambda Expression)
  • 메서드 레퍼런스(Method Reference)
  • 스트림(Stream)
  • 자바함수(Function)
  • 디폴트 메서드 (Default Method)
  • 동작 파라메터화 (Behavior Parameterization)

추가 된 배경

간결한 코드를 위한 개발자의 요구사항

List<Apple> inventory = new ArrayList<>();
inventory.addAll(Arrays.asList(new Apple(80,"green"), new Apple(155, "green"), new Apple(120,"red")))

//익명클래스를 이용하는 방법
Collection.sort(inventory, new Comparator<Apple>(){
    @Override
    public int compare(Apple o1, Apple o2){
        return 01.getWeight().compareTo(getWeight());
    }
});

//메서드 레퍼런스를 이용하는 방법
inventory.sort(comparing(Apple::getWeight));

멀티코어 CPU 대중화 (하드웨어적)

  • 기존에는 멀티코어를 활용하기 위해 Thread를 사용
    • Java 1 : Thread, Lock
    • Java 5 : Thread Pool, Concurrent Collection
    • Java 7 : Fork-Join Framework
  • 자바 8에서는 병렬처리를 지원하는 Stream API지원
    • Synchronized 키워드를 사용하지 않음
    • 병렬 처리 코드를 JVM으로 넘겨 처리(추상화)
    • parallelStream()

자바 함수

  • 자바8에서는 함수를 새로운 값의 형식으로 추가 (함수를 값으로 넘김)
    • Primitive Data Type : int, boolean, float
    • Reference Data Type : String, new 키워드로 생성한 각종 객체들
    • Method (메서드 레퍼런스) : 메서드 블럭의 메모리상 주소값
    • Function (익명함수 또는 람다) : 익명함수 블록의 메모리상 주소값
  • 람다와 메서드 레퍼런스를 이용하여 스트림의 기능 구현

메서드 레퍼런스

File클래스에 isHidden() 메서드가 존재하고 있지만 복잡하게 FileFilter클래스로 감싼후 new 키워드를 사용하여 인스턴스를 객체 만든 후, 파라메타로 전달
File [] hiddenFiles = new File(".").listFiles(new FileFilter(){
    @Override
    public boolean accept(File pathname){
        return pathname.isHidden();
    }
});
//File클래스가 가지고 있는 isHidden()메서드를 직접 파라메타로 전달
File[] hiddenFiles2 = new File(".").listFiles(File::isHidden);

람다(익명함수)

//File클래스를 이용하여 익명함수를 작성하여 직접 파라메타로 전달
File[] hiddenFiles3 = new File(".").listFiles(file->file.isHidden());
  • 람다코드가 길어지면 메서드 레퍼런스로 넘기는 방식 구현
  • 필터와 같은 집합연산은 직접 구현하지 말고 가급적 스트림 API를 사용

스트림(Stream)

  • 한번에 한개씩 만들어지는 연속적인 데이터 항목들의 모임
  • 자바8에서는 하려는 작업을 고수준으로 추상화하여 일련의 스트림으로 만들어 처리
  • 스트림 파이프라인을 이용하면 추상화된 병렬처리 가능
List<Apple> heavyApples = inventory.stream()
    .filter((Apple a) -> a.getWeight() > 150)
    .collect(toList());

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

디폴트 메서드

  • 특정 메서드 구현을 인터페이스가 포함하는것
  • 자바8에서는 Default 키워드 지원
  • 기존의 인터페이스 설계를 자유롭게 확장 가능
  • 개발자가 디폴트 메서드를 직접 구현할 일은 거의 없어야 한다.
  • 미래에 프로그램이 쉽게 변화할 수 있는 환경을 제공

동작 파라메터화

  • 전략 패턴 (Stratege Pattern)
  • 알고리즘(전략)을 미리 정의해 둔 다음 런타임에 알고리즘을 선택하는 패턴
public interface ApplePredicate{
    public boolean test(Apple a);
}

public class AppleWeightPredicate implements ApplePredicate{
    @Override
    public boolean test(Apple a){
        return a.getWeight() > 150;
    }
}

public class AppleColorPredicate implements ApplePredicate{
    @Override
       public boolean test(Apple a){
        return "green".equals(a.getColor());
    }
}
@SuppressWanings("unused")
public static void main(String [] args){
    List<Apple> inventory = new ArrayList<>();
    inventory.addAll(Arrays.asList(new Apple(80,"green"), new Apple(155,"green"), new Apple(120,"red")));
    List<Apple> weightApples = filter(inventory, new AppleWeightPredicate());
    List<Apple> colorApples = filter(inventory, new AppleColorPredicate());
}
public static List<Apple> filter(List<Apple> inventory, ApplePredicate p){
    List<Apple> result = new ArrayList<>();
    for(Apple a : inventory){
        if(p.test(a)){
            result.add(a);
        }
    }
    return result;
}
//필요한 전략을 런타임에 결정할 수 있다. 단, 전략을 반드시 클래스로 만들어야 하나?
//진짜 실행에 필요한 알고리즘보다, 코드를 보내기 위해 작성된 불필요한 코드량이 더 많다.
return a.getWeight() > 150;
return "green".equals(a.getColor());

익명클래스로 전환해도 불필요한 코드는 여전히 존재한다.

@SuppressWarnings("unused")
public static void main(String [] args){
    List<Apple> inventory = new ArrayList<>();
    inventory.addAll(Arrays.asList(new Apple(80,"green"),new Apple(155,"green"),new Apple(120,"red")));

    List<Apple> weightApples = filter(inventory, new ApplePredicate(){
        @Override
        public boolean test(Apple a){
            return a.getWeight()>150;
        }
    });
    List<Apple> colorApples = filter(inventory, new ApplePredicate(){
        @Override
        public boolean test(Apple a){
            return "green".equals(a.getColor());
        }
    });
}
public static List<Apple> filter(List<Apple> inventory, ApplePredicate p){
    List<Apple> result = new ArrayList<>();
    for(Apple a : inventory){
        if(p.test(a)){
            result.add(a);
        }
    }
    return result;
}

리스트 형식을 Generic으로 추상화하고 알고리즘을 람다식으로 적용

@SuppressWarnings("unused")
public static void main(String[] args){
    List<Apple> inventory = new ArrayList<>();
    inventory.addAll(Arrays.asList(new Apple(80,"green"),new Apple(155,"green"), new Apple(120,"red")));
    List<Apple> weightApples = filter(inventory, (Apple a) -> a.getWeight()>150);
    List<Apple> colorApples = filter(inventory, (Apple a) -> "green".equals(a.getColor()));
}
public static <T> List<T> filter(List<T> list, Predicate<T> p){
    List<T> result = new ArrayList<>();
    for(T e: list){
        if(p.test(e)){
            result.add(e);
        }
    }
    return result;
}

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

자바 관련 문제  (0) 2017.12.22