java8

Hello World

  • 일반적인 자바 스레드 실행 코드
public class HelloWorld {

    public static void main(String[] args) {

        Runnable r = new InnerHelloWorld();
        Thread t = new Thread(r);
        t.start();

        // new Thread(new InnerHelloWorld()).start();
    }

    // Runnable 인터페이스를 구현, inner 클래스로 지정
    public static class InnerHelloWorld implements Runnable {

        @Override
        public void run() {
            System.out.println("Hello world");
        }
    }
}
  • java8에서의 람다식을 이용한 스레드 실행 코드
public class HelloWorld_java8 {

    public static void main(String[] args) {
        new Thread(
            () -> {System.out.println("Hello World!");}
        ).start();
    }

}

함수형 인터페이스 functional interface

public interface Runnable { // 인터페이스 정의
    public abstract void run(); // 추상 메소드가 단 하나
}
  • 추상 메소드가 하나 뿐인 모든 인터페이스
  • A Functional Interface is any interface with a single abstract method.
  • 단일 함수(기능) 규약
  • Runnable 함수형 인터페이스 인정!
  • 다수 디폴트 메소드와 정적 메소드 포함 가능

기본제공 함수형 인터페이스

  • java.util.function 패키지
  • 만들지 말자! 가져다 쓰자! (Don't Reinventing the wheel)
  • Predicate, Consumer, Function, Supplier, UnaryOperator, BinaryOperator

람다식 lambda expression

syntax : ( 인자 ) -> { 구문 }

  • 메소드와 비슷, JSR335
  • 람다식은 '익명 메서드 anonymous method (이름 없는 메서드)'라 생각하자
  • 대상 타입 추론, 매개변수 타입 추론 by compiler
  • 람다식은 함수 인터페이스의 구현체로 변환

          // java8 람다식을 이용한 스레드 실행 코드
         new Thread(() -> {
             System.out.println("Hello World!");
         }).start();
    
         // 익명 클래스로 구현한 코드로 이해하기
         new Thread(new Runnable() {
             @Override
             public void run() {
                 System.out.println("Hello world");
             }
         }).start();
     }
    
    * syntax : 문법, 구조, 또는 언어 문장 내에 있는 구성요소의 순서
    * JSR : Java Specification Requests

다양한 람다식 축약형

  • 람다 표현식을 더 간략하게 작성

람다식 적용

  • 제어 흐름 중복 DRY > 재사용
  • OOP 제어 흐름 추상화 기법을 대체 : 템플릿 메소드 패턴(상속), 전략 stratage 패턴(위임)
  • 제어 흐름 추상화를 위한 행위 매개변수

행위 매개변수 parameterized behaviors

  • 행위를 메소드 인자로 전달 : functional interface를 사용해서 행위(익명클래스, 람다식)를 매개변수로 전달
  • 객체가 아닌 메소드(함수) 수준으로 제어 흐름을 추상화, 로직 조합(전략패턴), 콜백 전달(옵저버패턴)
  • 객체를 사용하지 않는 경량
  • 고차함수 higher order function : 다른 함수를 인자로 받거나 그 결과로 함수를 반환하는 함수다.
* 객체 사용 비용
  • class 안에 코드를 구현, 클래스 이름, 상용구 boilerplate code, 캡슐화, 간접접근
* 행위 매개변수 보급
  • 다양한 언어에서 고차함수 지원, C++ 11, C# 3.0, .Net(LINQ), Guava, LambdaJ, Op4J
  • 함수형 프로그래밍 대중화 (멀티 코어 CPU)
  • spring xxxTemplage

익명 클래스

  • 적은 비용
  • 클래스 이름 불필요, 생성자 불필요
  • 클래스 생성과 인스턴스 생성이 동시, 클래스 하나에 인스턴스 하나
  • 문제점 : 매번 객체 생성, 클래스 선언 > 정작 중요한 건 override한 메소드의 구현 부분

람다 != 익명 클래스

  • compiler 처리가 다름
  • 람다식은 invokedynamic (JSR 292)

클로저 closure

  • 익명 클래스 + 변수 포획 captured variable
  • 내부 객체는 외부 객체의 멤버 변수(final)에 접근 가능
  • effectively final : 멤버 변수가 final이 아니더라도 수정되지 않으면 변수 포획

람다식에서의 this

  • 람다식에서 this는 람다식을 가리키지 않음 > 람다는 새로운 객체를 만들지 않음

디폴트 메소드 Default method

  • 인터페이스에 기본 구현체 가능, 추가된 인터페이스의 하위 호환성 보장
  • 기본 메소드는 하위 클래스에서 사용 가능함(상속)
  • default 키워드, IF확장 시 재구현 (overriding) 또는 추상으로 지정가능
  • 다이아몬드 문제 발생 가능 > 충돌에 따른 컴파일 오류 발생으로 회피 기법 필요 (super로 선택 혹은 순서 지정, 명시적인 오버라이드)
*하위 호환성
  • 기존 클래스나 인터페이스에 새 필드, 매서드, 생성자등을 추가하면 하위 호환성이 깨짐
  • 이미 컴파일 된 어플리케이션이 망가짐(바이너리 하위 호환성)
  • 인터페이스의 모든 메소드는 public abstract 이므로 새로운 메소드 추가시 난리부르스
  • 람다식을 적용하기 위해 자바 SDK 수정하려고 하니 인터페이스 하위 문제가 발생

정적 메소드 static method

  • 인터페이스에 정적 메소드 포함 가능
  • 인터페이스에 필요한 별도 유틸리티 helper 클래스 분리 불필요, name space 역할
  • 클래스 메소드를 전역 함수로 사용하는 효과, 서술적인 API
  • 람다식와 정적 메서드, 정적 임포트(java5)로 전역 함수 활용도 증대

메소드 참조 method reference

  • 이미 만들어진 메소드의 이름을 사용해서 참조하는 표현 방식
  • 람다식을 더 간략하게 표현, 람다식을 대체
  • syntax : 클래스나 객체::메소드 이름
  • 함수형 인터페이스 및 기존 메소드 모두 가능

메소드 참조 유형

  • 정적 메소드 참조, 클래스이름::메소드 이름, Math::abs, Integer::parseInt
  • 인스턴스 메소드 참조, 객체참조::멤소드 이름, System.out::println
  • 람다 인자 객체 메서드 참조, 람다의 인자로 넘어오는 객체의 멤버 메소드 참조 인자의 타입명::메소드 이름, someObject::someMethod
  • 생성자 참조, 클래스이름::new , someObject::new
  • 상위 클래스의 메소드 참조, super::메소드 이름
  • 배열 생성자, 타입명[]::new

스트림 Stream API

  • java.util.stream
  • 연산의 선언적 서술, 반복구조는 내부에 캡슐화되며 로직에 집중하도록 분리
  • 불변 데이터
  • 지연 lazy, 병렬 parallel (순차 포함)
  • 무한 데이터 흐름 infinite stream
  • 다양한 데이터 원천 지원 : 컬렉션, 파일I/O
  • 다양한 소스 : Stream, Collection, BufferedReader, Random, Arrays, Stream.builder, BitSet

스트림과 컬렉션

  • collection (list, map, set)보다 높은 추상화, stream을 통한 다양한 연속적 데이터 적용
  • 컬렉션은 보관용 자료구조 <> 스트림은 처리용 자료구조

스트림 연산

  • 내부 반복 Internal Iteration (로직에 집중)<> 외부반복 External iteration (명시적인 제어 흐름 고려)
  • 중개 연산자 : 무상태 연산 map, filter, flatMap, skip, limit, sorted, distinct
  • 종단 연산자 : 결과 생산 forEach, collect, reduce, iterator
  • 지연 연산 lazy : 중개 연산은 캐쉬되며 즉시 수행하지 않고 종단 연산 시점에 수행
  • 병렬 처리 : parallel() 지원, 쉬운 병렬 전환

results matching ""

    No results matching ""