5.1 필터링과 슬라이싱

Predicate

distinct

limit

skip

 

5.2 매핑

transform

flatmap

 

5.3. 검색과 매칭

allMatch

nonMatch

findAny

findFirst

 

5.4 리뷰싱

결과 도출

합, 최대/최소, 연산

어플리케이션 : 컬랙션을 만들고 처리하는 과정이 대부분

프로그래밍 : 할당, 분기, 루프

 

4.1 스트림이란 무엇인가?

투명하게, (blackbox, transparent) 병렬로 처리

선언형으로 코드 구현

뭔하는 동작을 선언 : 구현은 내부로직

 

4.2 스트림 시작하기

연속된 요소, 소스로부터 데이터 소비, 데이터 처리 연산 ( filter, map, reduce, match, sort) 파이프라이닝 ( 메소드 체이닝)

 

4.3 스트림과 컬렉션

컬렉션 : 메모리에 데이터 저장

스트림 : laziness로 필요시 연산

스트림은 한번만 탐색 가능

 

4.4 스트림 연산

시작 : stream화

중간 : filter, map, limit, loop fusion (서로다른 연산이지만 하나의 연산으로 합치는 것), short curcuit ( A && B : A가 false이면 B 수행 안함)

최종 : for each, count, collect 

 

https://steadyzest.tistory.com/14

 

쇼트서킷(Short-circuit)

관계 연산자 A == B : A와 B가 같으면 참(1) A != B : A와 B가 다르면 참(1) 논리 연산자 A && B : A와 B 모두 참일 경우 참(1). 논리곱 A || B : A와 B 둘 중 하나가 참이면 참(1). 논리합 !A : A의 결과를 참..

steadyzest.tistory.com

 

https://www.geeksforgeeks.org/short-circuit-logical-operators-in-java-with-examples/

 

Short Circuit Logical Operators in Java with Examples - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

https://core.ac.uk/download/pdf/190372509.pdf

 

3.1 람다란 무엇인가?

 

람다 lambda라는 용어는 람다 미적분학 학계에서 개발한 시스템에서 유래

람다 표현식을 사용하면 코드를 더 쉽게 구현, 간결한 표현으로 구현

람다 : 

(파라미터 리스트) -> (람다 바디)

(parameters) -> expression

(parameters) -> {statements;}

 

3.2 어디에, 어떻게 람다를 사용할까?

3.2.1 함수형 인터페이스

@FunctionalInterface

interface에 하나의 추상 메서드만 있음

전체 표현식을 함수형 인터페이스의 인스턴스

 

 

3.2.2. 함수 디스트립터

추상 메서드 시그너쳐는 람다 표현식의 시그너쳐를 가리킨다.

람다 표현식의 시그너쳐를 서술하는 메서드를 함수 디스크립터

() -> void ( runnable 같은거)

 

3.3 람다활용

 

3.4 함수형 인터페이스 사용

3.4.1 Predicate : () -> boolean

3.4.2 Consumer : (T) -> void

3.4.3 Function: (T) -> (R)

 

제공되는 함수형 인터페이스

함수형 인터페이스 함수 디시크립터 예제
Predicate<T> T -> boolean (List<String> list) -> list.isEmpty()
Consumer<T> T -> void (Apple a) -> System.out.println(a.getWeight)
Function<T> T -> R (String s) -> s.length()
Supplier<T> () -> T () -> new Apple(10)
UnaryOperator<T> T -> T (Integer a) -> a + 1
BiOperator<T> (T, T) -> T  
BiPredicate<L, R> (L, R) -> boolean  
BiConsumer<T, U> (T, U) -> void  
BiFunction<T, U, R> (T, U) -> R (Apple a1, Apple a2) ->
a.getWeight().compareTo(a2.getWeight())

 

CHAPTER 2 동작 파라미터화 코드 전달하기

 

동작 파라미터화 : 어떻게 실행할지 결정하지 않은 코드 블록

코드 블록은 나중에 프로그램에서 호출시 전달

동작이 파라미터화 : 로직, 동작을 파라미터로 전달할 수 있다.

어떤 요소에 어떤 동작을 수행하라고 전달할 수 있음

어떤 동작 다음에 다른 동작을 수행할 수도 있음

어떤 동작 수행에 에러가 발생하면 정해진 다른 어떤 동작을 수행할 수 있음


2.1 변화하는 요구사항에 대응하기

 

하드코딩 : 1st Approach if ("green".equals(apple.getColor()))
input값 전달  : 2nd Approach if (inputColor.equals(apple.getColor()))
조건 추가 if (inputColor.equals(apple.getColor())
if (inputWeight < apple.getWeight())
토글기능 추가 : 3rd Approach if (toggleOn == true && inputColor.equals(apple.getColor())
if (toggleOn == false && inputWeight < apple.getWeight())

요구사항이 추가될때 마다 if else로 하게 되면 조건이 복잡해지고 다양해짐 > 테스트 하기에러 여러움


2.2 동작 파라미터화

 

 

   
public interface WorkerPredicate {
  boolean test(Worker worker);
}
추상화
public class WorkerJobPermanantTypePredicate implements WorkerPredicate {
  public boolean test(Worker worker) {
    return worker.getJobType() == 100;
  }
}
구현
public class WorkerSalaryOver100Predicate implements WorkerPredicate {
  public boolean test(Worker worker) {
    return worker.getSalary() > 100;
  }
}
구현
public static List<Worker> filterWorker(List<Worker> workerList, WorkerPredicate p) {
   List<Worker> resultList = new ArrayList<>();
   for (Worker worker : workerList) {
      if (p.test(worker) {
          resultList.add(worker)
      }
   }
   return resultList;
}
적용
List<Worker> permanentWorkerList =
filterWorker(workerList, new WorkerJobPermamentTypePredicate());

List<Worker> salaryOver100WorkerList = 
flterWorker(workerList, new WokerSalaryOver100Predicate());
추상화로 필터링
4th Approach

유연한 API : 질의,동작,조건,행위,로직을 파라미터로 전달 

 


2.3 복잡한 과정 간소화

과거 이런 방법을 익명 클래스로 해결

List<Worker> permanentWorkerList = 
filterWorker(workerList, new WorkerPredicate() {
  public boolean test(Worker worker) {
     return worker.getJobType() = 100;
  }
});
5th Approach
익명 클래스

람다 표현식

List<Worker> permamentWorkerList =
filterWorker(workerList, (Worker w) -> w.getJobType() == 100);
6th Approach
Lambda expression

리스스 형식 + Generic 으로 일반화

public interface Predicate<T> {
   boolean test(T t);
}
 
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;
}
 
List<Worker> permanentWokerList =
filter(workerList, (Worker w ) -> w.getJobType() == 100);
7th Approach
Generic + Lambda
List<Leave> paidLeaveList = 
filter(leaveList, (Leave l) -> l.getLeaveType() == "PAID");
 

2.4 실전 예제

workerList.sort(
(Worker w1, Woker w2) -> w1.getSalary().compareTo(w2.getSalary())
);
comparatore
Thread t = new Trhead(() -> System.out.println("Runing thread")); runnable
   


2.5 마치며

Generic + Lambda로 간결한 코드를 구현할 수 있다.

 

 

https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html

 

Predicate (Java Platform SE 8 )

Returns a composed predicate that represents a short-circuiting logical AND of this predicate and another. When evaluating the composed predicate, if this predicate is false, then the other predicate is not evaluated. Any exceptions thrown during evaluatio

docs.oracle.com

 

'독서관련 > Modern Java In Action' 카테고리의 다른 글

CHAPTER 4 : 스트림 소개  (0) 2022.06.28
CHAPTER 3 : 람다 표현식  (0) 2022.06.14
CHAPTER 1 자바 8 : New Feature  (0) 2022.06.02
java8 CH16 – CompletableFuture  (0) 2020.10.14
CH11 Optional, CH12 java time date  (0) 2020.10.13

CHAPTER 1 자바 8, 9, 10, 11 : 무슨 일이 일어나고 있는가?

 

1.1 역사의 흐름은 무엇인가?

 

Java 1 : 1997년

Java 5 : 2004년

Java 8 : 2014년

Java release and roadmap

 

자바 버전별 functionality

version feature
1, 2 Thread, lock, GC
5 Thread pool, noi, concurrency, annotation, generic, varargs
7 Diamond op, try resource, Fork/join
8 Default method, method reference,  lambda expression, stream api, completable future, new date api

 

Java 8 가장 큰 특징

스트림 api : 고수준 언어로 질의를 하면 구현은 최적읜 내부 실행

동작(로직)을 코드에 전달 : 메소드 참조와 람다 : 함수형 프로그래밍 개념 차입

인터페이스의 디폴트 메서드

 

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

 

Java가 대중적인 이유 :

다양한 library, 변화에 계속 적응하는 언어, 

 

현대 언어가 구추하고자하는 목표 

병렬성 지원

낮은 boiler plate code

http://www.yes24.com/Product/Goods/12204890

 

자바 8의 변화의 주요 부분

스트림 API : 스트림 처리 = 연속적인 흐름 = 파이프라인 기법

동작 파라메터화 : behavior parameterization : 작동 방식 혹은 로직을 파라메터 입력으로 넣고자 하는 것

병렬성 : 과거 병렬처리 = 프로그램의 동작방식을 변경해야함 : 현재 : parellel=1 > parallel=4 : 결과는 동일함을 보장 = 안전하게 실행

이를 위해서는 공유된 가변 데이터에 접근하는 것이 없어야함 = 순수, 부작용 없는, 상태 없는 ( pure, sife-effect-free, stateless)

과거 : 기존 값을 가공하는데 집중 : 값의 일관성 유지, 객체의 값은 변수 로직이 메소드

현재 : 함수형 프로그래밍, 원하는 결과값만 표현, 수행은 내부의 문제

 


1.3 자바 함수

 

함수 : f(x) = y 함수 = 값 : 자바 언어의 변화 : 메소드가 일급시민화 = 메소드를 값처럼 사용할 수 있다. 메소드를 인자로 넘길수 있다. 

기존자바로는 메소드를 값으로 인식하게 하여 인자에 넘길수가 없었음 : 이급시민

메서드를 인자로 넘기는 문법 : 메소드 레퍼런드 Class::method ex File::isHidden

람다문법 : 함수를 일급값으로 넘여주는 방법

기존에 있던 메소드 : 기명함수 (named) 익명함수 : 람다 (x -> x +1) = (addOne(x))

 

int addOne( x) {

return x + 1

}

Apple::isGreenApple

(Apple a) -> "green".equals(a.getColor())


1.4 스트림

List<Worker> workerList = getWorkerListFromApi();
Map<JobType, List<String>> workerMapByJobTypeAndSalaryByOver100 = new HashMap<>();
for (Worker worker : workerList) {
  if (worker.getSalary() > 100) {
      JobType jobtype = worker.getJobType();
      List<Worker> existWorkerListByJobType = workerMapByJobTypeAndSalayByOver100.get(jobtype);
      if (existWorkerListByJobType == null) {
          existWorkerListByJobType  = new ArrayList<>();
          wokerMapByJobTypeAndSalaryByOver100.put(jobType, existWorkerListByJobType)
      }
      existWokerListByJobType.add(worker);
   }
}
List<Worker> workerList = getWorkerListFromApi();
Map<JobType, List<String>> workerMapByJobTypeAndSalaryByOver100 =
workerList
.stream()
.filter( t -> t.getSalary() > 100)
.collect(groupBy(Worker::getJobType));

stream : list > stream으로 변환

포크 > 파이프라인 > 필터 > 파이프라인 > 조인 : 병렬

Divide and conquer : 분할 정복

전제조건 : 가변 공유가 없는 : 같은 것을 참조하는 게 없는 : 수정을 할수 없는 : immutable


1.5 디폴트 메서드와 자바 모듈

인터페이스 변경을 쉽게 : 인터페이스 변경이 어려운 이유 : 추가는 쉽다. 변경과 삭제가 어렵다. 추가는 정말 쉽나?

상위 인터페이스 추가하면, 하위 구현체에서 모든 abstract method를 구현해야한다.

default 메소드 정의 가능 ( 메서드 바디를 인터페이스에 일부로 포함 가능 )

default 메소드 > 인터페이스에 다중 상속 문제

 

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

 

Optional

Pattern Matching


1.7 마치며

Java는 계속 성장하고 있다. 잘되는 이유 : 다 잘하는 건 아니지만.. 그래서 많은 사람이 사용하지 않을까.

메소드를 함수로 전달 : 메소드 레퍼런스

Steam API : 컬렉션 처리

인터페이스 디폴트 메서드

Optional 로 null 대체, 패턴 매팅

 

Programming Languaga Ranking in 2021

 

https://statisticstimes.com/tech/top-computer-languages.php

 

Top Computer Languages 2021 - StatisticsTimes.com

 

statisticstimes.com

 

https://dzone.com/articles/a-guide-to-java-versions-and-features

 

Guide to Java Versions and Features - DZone Java

In this guide. we will look at the differences between Java distributions and an overview of Java language features, including Java versions 8-13.

dzone.com

 

아래의 글은 라울-게이브리얼 우르마, 마리오 푸스코, 앨런 마이크로프트 저/우정은 역, 『모던 자바 인 액션』,한빛미디어(2019), CH01의 내용을 기반으로 작성하였습니다.

Synchronize & Asynchronize

Sync : blocking call

Async : non-blocking call

Non-blocking : return first, then call back with results when call completed.

 

Java 8 쉬운 병렬처리

Stream.parallel

CompletableFuture

 

Stream Parallel vs CompletableFuture

Stream.parallel

I/O 가 포함되지 않는 계산 중심의 동작을 실행할 때는 스트림 인터페이스가 가장 구현하기 쉬우며 효율적

CompletableFuture

작업이 I/O를 기다리는 작업을 병렬로 실행할 때는 CompletableFuture가 더 많은 유연성을 제공하며 대기/계산의 비율에 적합한 스레드 수를 설정할 수 있다. 특히 스트림의 게으른 특성 때문에 스트림에서 I/O를 언제 처리할지 예측이 어려움

I/O : 파일 RW, DB작업,

 

kwonnam.pe.kr/wiki/java/8/completable_future

 

java:8:completable_future [권남]

 

kwonnam.pe.kr

www.baeldung.com/java-completablefuture

 

Guide To CompletableFuture | Baeldung

Quick and practical guide to Java 8's CompletableFuture.

www.baeldung.com

 

아래의 글은 라울-게이브리얼 우르마, 마리오 푸스코, 앨런 마이크로프트 저/우정은 역, 『모던 자바 인 액션』,한빛미디어(2019), CH01의 내용을 기반으로 작성하였습니다.

optional

Optional > way to express null value in dto

Optional returns stream

Optional.isPresent if else can be replaced with map with orElse

Optional in Optional solved by flatmap

 

Java time date

Express local data time with calendar

 

참조사이트 :

www.baeldung.com/java-optional

 

Guide To Java 8 Optional | Baeldung

Quick and practical guide to Optional in Java 8

www.baeldung.com

 

www.baeldung.com/java-8-date-time-intro

 

Introduction to the Java 8 Date/Time API | Baeldung

In this article we will take a look at the new Java 8 APIs for Date and Time and how much easier it is to construct and manipulate dates and times.

www.baeldung.com

 

아래의 글은 라울-게이브리얼 우르마, 마리오 푸스코, 앨런 마이크로프트 저/우정은 역, 『모던 자바 인 액션』,한빛미디어(2019), CH01의 내용을 기반으로 작성하였습니다.

Fork Join

Divide and conquer

Thread pool

 

Fork

Divide

Sub Branch

Stream Parallel 주의

내부 로직이 병렬성이 될지를 고민, 자료구조, 연산방식

타입 박싱 주의

Limit, findFirst 보다 findAny

소량은 fork join 비용이 더 높음

 

Parallel 성능 – N 1_000_000

Parallel 성능 – N 5 _000_000

Design pattern

Strategy 패턴

Interface execute

Interface validate

Class StringValidate

Class IntegerValidate

 

template 메소드 패턴

observer 메소드 패턴

registerObserver n times

Notify method call once, loop notify n times

Factory chain 패턴

Add successtor

Execute handlerequest both self

and successor

Then execute like chained

팩토리 method 패턴

List wishList = New ArrayList<>();

list.add(“Watch”);

List.add(“Phone”);

Arrays.asList(“Watch”, “Phone”)

Java 9

List.of(“Watch”, “Phone”);

참조사이트 :

blog.naver.com/PostView.nhn?blogId=2feelus&logNo=220732310413

 

Fork Join Framework - ForkJoinPool

ForkJoinPool 정확히는 Fork Join Framework 이라고 불러야 하고, ForkJoinPool은 그것의 대표 클...

blog.naver.com

 

okky.kr/article/345720

 

OKKY | [Java] 쓰레드풀 과 ForkJoinPool

메모리풀/쓰레드풀/캐쉬풀/DB풀  Pool 4총사 중 먼저  쓰레드 풀에 대해서 쉽게 그림으로 배워보아요. 오류나 추가사항이 있으면 댓글로 남겨주시면 소정의  포옹으로 보답을.... 쿨럭 자 시작합�

okky.kr

 

아래의 글은 라울-게이브리얼 우르마, 마리오 푸스코, 앨런 마이크로프트 저/우정은 역, 『모던 자바 인 액션』,한빛미디어(2019), CH01의 내용을 기반으로 작성하였습니다.

Collectors

Collection, collect와 다름

 

참고사이트 :

dzone.com/articles/java-8-streams-api-laziness

 

Java 8 Streams API: Laziness and Performance Optimization - DZone Java

In this post, we will move ahead with the Java 8 Streams API and have a look at the most important property of Java 8 Streams — laziness.

dzone.com

 

아래의 글은 라울-게이브리얼 우르마, 마리오 푸스코, 앨런 마이크로프트 저/우정은 역, 『모던 자바 인 액션』,한빛미디어(2019), CH01의 내용을 기반으로 작성하였습니다.

람다

표현식

(파라메터리스트) ->(화살표) { 바디) }

(String s) -> s.length()

(Apple a) -> a.getWeight() > 150

(int x, int y) -> { System.out.println(“sum=”+(x+y))

() -> 42

(String s1, String s2) -> s1.equals(s2)

 

함수형 인터페이스

추상메소드가 하나면 함수형 인터페이스

@FuntionalInterface

하나인거 보장

객체 생성후 override 없이 람다사용가능

 

함수 descriptor

함수형 인터페이스의 추상메서드의 시그너쳐

람다 표현식을 사용하기 위한 시그너처

표준화 -> 인터페이스

함수형 인터페이스의 시그너쳐의 표준화

타입은 모두 Object만 가능 : primitive type boxing

Predicate<T> – input T, return Boolean : boolean test(T t)

Consumer<T> – input T, return void : void accept(T t)

Function<T, R> - input T, return R : R apply(T t)

 

제공되는 함수형 인터페이스

함수형 인터페이스 함수 디시크립터 예제
Predicate<T> T -> boolean (List<String> list) -> list.isEmpty()
Consumer<T> T -> void (Apple a) -> System.out.println(a.getWeight)
Function<T> T -> R () -> new Apple(10)
Supplier<T> () -> T  
UnaryOperator<T> T -> T  
BiOperator<T> (T, T) -> T  
BiPredicate<L, R> (L, R) -> boolean  
BiConsumer<T, U> (T, U) -> void  
BiFunction<T, U, R> (T, U) -> R (Apple a1, Apple a2) ->
a.getWeight().compareTo(a2.getWeight())

 

메서드레퍼런스, 생성자 레퍼런스

(String s) -> Integer.parseInt(s)

Integer::parseInt

New Apple

Apple::new

 

형식추론

List<Apple> filteredAppleList = filter(appleList, (Apple a) -> a.getWeight() > 10);

List<Apple> filteredAppleList 2 = filter(appleList, a -> a.getWeight() > 10);

스트림, Stream

입출력 : stream

비디오 : 스트리밍

Stream processing : SIMD , 그래픽 병렬처리

SIMD : Single Instruction Multiple Data

리눅스 pipe

Java API : java.util.stream, java.util.function

 

Java 8 : Stream

 

스트림 특징

Collection 데이터 처리의 추상화

스트림 소스 : collection, array, io

Stream pipeline (스트림 연산은 스트림 자신을 반환)

Lazy 연산

Stream요소추가 및 요소 제거 불가

Steam은 한번만 탐색가능

 

참고사이트 :

dzone.com/articles/java-8-streams-api-laziness

 

Java 8 Streams API: Laziness and Performance Optimization - DZone Java

In this post, we will move ahead with the Java 8 Streams API and have a look at the most important property of Java 8 Streams — laziness.

dzone.com

 

아래의 글은 라울-게이브리얼 우르마, 마리오 푸스코, 앨런 마이크로프트 저/우정은 역, 『모던 자바 인 액션』,한빛미디어(2019), CH01, CH02의 내용을 기반으로 작성하였습니다.

 

Java release and roadmap

 

functionality

version feature
1, 2 Thread, lock, GC
5 Thread pool, noi, concurrency, annotation, generic, varargs
7 Diamond op, try resource, Fork/join
8 Default method, method reference,  lambda expression, stream api, completable future, new date api

 

언어의 진화방향

Concurrency -> parallel (stream, map/reduce)

Immutable (pure, side-effect-free, stateless)

Reduce boiler plate code

함수형 프로그래밍

일급함수 메서드와 클래스 자체가 값 값으로 메서드와 클래스 전달

메서드와 람다를 일급시민으로 격상 메서드 레퍼런스, 람다

stream

 

메소드레퍼런드

File::isHidden

 

람다

t -> convert(t)

t -> {return new NewObject(t.getId());}

(File f) -> f.getName().startWith(“prefix”);

 

참조사이트 :

https://dzone.com/articles/a-guide-to-java-versions-and-features

 

Guide to Java Versions and Features - DZone Java

In this guide. we will look at the differences between Java distributions and an overview of Java language features, including Java versions 8-13.

dzone.com

 

+ Recent posts