Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- Generic
- paging
- JQuery
- jQuery값전달
- javascriptcalendar
- namedQuery
- joinfetch
- 자바서블릿
- LIST
- 엔티티직접사용
- JPQL
- values()
- 제너릭
- 프로젝트생성
- 스프링데이터흐름
- 제네릭
- jQuery값전송
- jQueryUI
- fullcalendar
- springflow
- 페치조인
- 대량쿼리
- 페이징
- calendar
- fetchjoin
- jscalendar
- JPA
- javaservlet
- 벌크연산
- Hibernate
Archives
- Today
- Total
가자공부하러!
모던자바인액션(CH1) - 자바8부터 추가된 것들 본문
https://github.com/HyeongJunMin/ModernJava
챕터1
한줄요약 : 자바8에서 함수형 프로그래밍을 도입했고 함수 추가, 스트림 도입 등 변경사항이 있다.
스트림 처리(Stream processing)
한 번에 한 개씩 만들어지는 연속적인 데이터 항목들의 모임
단순히 생각하면 API가 조립 라인처럼 어떤 항목을 연속으로 제공하는 어떤 기능
파이프라인을 만드는데 필요한 많은 메서드를 제공
외부반복과 내부반복의 차이
외부 반복 : for-each 루프 등을 이용해서 각 요소를 반복하며 작업을 수행
내부 반복 : 라이브러리 내부에서 모든 데이터가 처리됨(스트림 API)
동작파라미터화
코드 일부를 API로 전달하는 기능
연산의 동작을 파라미터화할 수 있는 코드를 전달한다는 사상에 기초
아래는 예제 : 메서드를 전달할 수 있다는 사실이 핵심이라고 함
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Apple {
public enum Colors {
GREEN, RED, BLACK
}
private Colors color;
private Integer weight;
public static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p){
List<Apple> resultList = inventory.stream().filter(apple -> p.test(apple)).collect(Collectors.toList());
return resultList;
}
public static boolean isGreenApple(Apple apple) {
return Colors.GREEN.equals(apple.getColor());
}
public static boolean isHeavyApple(Apple apple) {
return apple.getWeight() >= 150;
}
}
@Slf4j
class Ch1MainTest {
List<Apple> inventory = new ArrayList();
@BeforeEach
void setup() {
inventory.add(new Apple(Apple.Colors.RED, 150));
inventory.add(new Apple(Apple.Colors.GREEN, 100));
inventory.add(new Apple(Apple.Colors.BLACK, 50));
}
@Test
void streamTest() {
//코드 넘겨주기 예제
//사과를 녹색사과만 골라내달라고 했다가 150그람 이상 사과만 골라내달라고하면?
List<Apple> apples = Apple.filterApples(inventory, Apple::isGreenApple);
log.debug("apples size : {}", apples.size());
apples.forEach(apple -> log.debug("apple color : {} , weight : {}", apple.getColor(), apple.getWeight()));
apples = Apple.filterApples(inventory, Apple::isHeavyApple);
log.debug("apples size : {}", apples.size());
apples.forEach(apple -> log.debug("apple color : {} , weight : {}", apple.getColor(), apple.getWeight()));
//한 번만 사용할 메서드는 저 위에처럼 할 필요 없이 람다로 작성
apples = Apple
.filterApples(inventory,
a -> a.getWeight() >= 150 || Apple.Colors.GREEN.equals(a.getColor()));
log.debug("apples size : {}", apples.size());
apples.forEach(apple -> log.debug("apple color : {} , weight : {}", apple.getColor(), apple.getWeight()));
}
}
//결과
"C:\Program Files\Java\jdk1.8.0_211\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.1\lib\idea_rt.jar=8964:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.1\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.1\plugins\junit\lib\junit-rt.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_211\jre\lib\rt.jar;C:\workspace\study\modernjava\target\test-classes;C:\workspace\study\modernjava\target\classes;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter-hateoas\2.2.6.RELEASE\spring-boot-starter-hateoas-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\hateoas\spring-hateoas\1.0.4.RELEASE\spring-hateoas-1.0.4.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-aop\5.2.5.RELEASE\spring-aop-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-beans\5.2.5.RELEASE\spring-beans-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-context\5.2.5.RELEASE\spring-context-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\plugin\spring-plugin-core\2.0.0.RELEASE\spring-plugin-core-2.0.0.RELEASE.jar;C:\Users\minhj\.m2\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.2.6.RELEASE\spring-boot-starter-web-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter\2.2.6.RELEASE\spring-boot-starter-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.2.6.RELEASE\spring-boot-starter-logging-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\minhj\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\minhj\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.12.1\log4j-to-slf4j-2.12.1.jar;C:\Users\minhj\.m2\repository\org\apache\logging\log4j\log4j-api\2.12.1\log4j-api-2.12.1.jar;C:\Users\minhj\.m2\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\Users\minhj\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\minhj\.m2\repository\org\yaml\snakeyaml\1.25\snakeyaml-1.25.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.2.6.RELEASE\spring-boot-starter-json-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.10.3\jackson-databind-2.10.3.jar;C:\Users\minhj\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.10.3\jackson-annotations-2.10.3.jar;C:\Users\minhj\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.10.3\jackson-core-2.10.3.jar;C:\Users\minhj\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.10.3\jackson-datatype-jdk8-2.10.3.jar;C:\Users\minhj\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.10.3\jackson-datatype-jsr310-2.10.3.jar;C:\Users\minhj\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.10.3\jackson-module-parameter-names-2.10.3.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.2.6.RELEASE\spring-boot-starter-tomcat-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.33\tomcat-embed-core-9.0.33.jar;C:\Users\minhj\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.33\tomcat-embed-el-9.0.33.jar;C:\Users\minhj\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.33\tomcat-embed-websocket-9.0.33.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter-validation\2.2.6.RELEASE\spring-boot-starter-validation-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;C:\Users\minhj\.m2\repository\org\hibernate\validator\hibernate-validator\6.0.18.Final\hibernate-validator-6.0.18.Final.jar;C:\Users\minhj\.m2\repository\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar;C:\Users\minhj\.m2\repository\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-web\5.2.5.RELEASE\spring-web-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-webmvc\5.2.5.RELEASE\spring-webmvc-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-expression\5.2.5.RELEASE\spring-expression-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-devtools\2.2.6.RELEASE\spring-boot-devtools-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot\2.2.6.RELEASE\spring-boot-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.2.6.RELEASE\spring-boot-autoconfigure-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\projectlombok\lombok\1.18.12\lombok-1.18.12.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-starter-test\2.2.6.RELEASE\spring-boot-starter-test-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-test\2.2.6.RELEASE\spring-boot-test-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\boot\spring-boot-test-autoconfigure\2.2.6.RELEASE\spring-boot-test-autoconfigure-2.2.6.RELEASE.jar;C:\Users\minhj\.m2\repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;C:\Users\minhj\.m2\repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;C:\Users\minhj\.m2\repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;C:\Users\minhj\.m2\repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;C:\Users\minhj\.m2\repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;C:\Users\minhj\.m2\repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;C:\Users\minhj\.m2\repository\org\mockito\mockito-junit-jupiter\3.1.0\mockito-junit-jupiter-3.1.0.jar;C:\Users\minhj\.m2\repository\org\assertj\assertj-core\3.13.2\assertj-core-3.13.2.jar;C:\Users\minhj\.m2\repository\org\hamcrest\hamcrest\2.1\hamcrest-2.1.jar;C:\Users\minhj\.m2\repository\org\mockito\mockito-core\3.1.0\mockito-core-3.1.0.jar;C:\Users\minhj\.m2\repository\net\bytebuddy\byte-buddy\1.10.8\byte-buddy-1.10.8.jar;C:\Users\minhj\.m2\repository\net\bytebuddy\byte-buddy-agent\1.10.8\byte-buddy-agent-1.10.8.jar;C:\Users\minhj\.m2\repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;C:\Users\minhj\.m2\repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;C:\Users\minhj\.m2\repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-core\5.2.5.RELEASE\spring-core-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-jcl\5.2.5.RELEASE\spring-jcl-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\springframework\spring-test\5.2.5.RELEASE\spring-test-5.2.5.RELEASE.jar;C:\Users\minhj\.m2\repository\org\xmlunit\xmlunit-core\2.6.4\xmlunit-core-2.6.4.jar;C:\Users\minhj\.m2\repository\org\junit\jupiter\junit-jupiter\5.6.1\junit-jupiter-5.6.1.jar;C:\Users\minhj\.m2\repository\org\junit\jupiter\junit-jupiter-api\5.5.2\junit-jupiter-api-5.5.2.jar;C:\Users\minhj\.m2\repository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;C:\Users\minhj\.m2\repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;C:\Users\minhj\.m2\repository\org\junit\platform\junit-platform-commons\1.5.2\junit-platform-commons-1.5.2.jar;C:\Users\minhj\.m2\repository\org\junit\jupiter\junit-jupiter-params\5.5.2\junit-jupiter-params-5.5.2.jar;C:\Users\minhj\.m2\repository\org\junit\jupiter\junit-jupiter-engine\5.5.2\junit-jupiter-engine-5.5.2.jar;C:\Users\minhj\.m2\repository\org\junit\platform\junit-platform-engine\1.5.2\junit-platform-engine-1.5.2.jar;C:\Users\minhj\.m2\repository\org\junit\platform\junit-platform-launcher\1.5.2\junit-platform-launcher-1.5.2.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 ch1.Ch1MainTest,streamTest
17:03:39.620 [main] DEBUG ch1.Ch1MainTest - apples size : 1
17:03:39.624 [main] DEBUG ch1.Ch1MainTest - apple color : GREEN , weight : 100
17:03:39.624 [main] DEBUG ch1.Ch1MainTest - apples size : 1
17:03:39.625 [main] DEBUG ch1.Ch1MainTest - apple color : RED , weight : 150
17:03:39.625 [main] DEBUG ch1.Ch1MainTest - apples size : 2
17:03:39.625 [main] DEBUG ch1.Ch1MainTest - apple color : RED , weight : 150
17:03:39.625 [main] DEBUG ch1.Ch1MainTest - apple color : GREEN , weight : 100
Process finished with exit code 0
병렬성과 공유 가변 데이터
자바 스레드 API보다 쉽게 병렬성을 활용할 수 있음
멀티스레딩을 사용하는 주요 패턴 : 필터링, 데이터 추출, 데이터 그룹화
컬렉션을 필터링할 수 있는 가장 빠른방법 : 컬렉션을 스트림으로 바꾸고 병렬로 처리해서 리스트로 복원
@Slf4j
class Ch1MainTest {
List<Apple> inventory = new ArrayList();
@BeforeEach
void setup() {
inventory.add(new Apple(Apple.Colors.RED, 150));
inventory.add(new Apple(Apple.Colors.GREEN, 100));
inventory.add(new Apple(Apple.Colors.BLACK, 50));
}
@Test
void parallelStreamTest() {
//순차 처리 방식
List<Apple> resultList = inventory.stream().filter(a -> a.getWeight() >= 150).collect(Collectors.toList());
//병렬 처리 방식
List<Apple> parallelResultList = inventory.parallelStream().filter(a -> a.getWeight() >= 150).collect(Collectors.toList());
}
}
자바8의 병렬성
1. 라이브러리에서 분할을 처리
- 큰 스트림을 병렬로 처리할 수 있도록 작은 스트림으로 분할
2. 전달된 메서드가 상호작용을 하지 않는다면 가변 공유 객체를 통해 공짜로 병렬성 확보
- 함수형 프로그래밍과 관련있음 : 프로그램이 실행되는 동안 컴포넌트 간 상호작용이 일어나지 않는다
디폴트 메서드와 자바 모듈
외부에서 만들어진 컴포넌트를 이용해 시스템을 구축하는 경향이 있다.
자바9 : 모듈(패키지 모음을 포함) 정의 가능
자바8 : 디폴트 메서드 지원
자바8은 구현 클래스에서 구현하지 않아도 되는 메서드를 인터페이스에 추가할 수 있는 기능을 제공한다.
메서드 바디는 클래스 구현이 아니라 인터페이스의 일부로 포함된다.
그래서 이를 디폴트 메서드라고 부른다.

함수형 프로그래밍
메서드와 람다를 일급값으로 사용
가변 공유 상태가 없는 병렬 실행을 이용해서 효율적이고 안전하게 함수나 메서드 호출
'공부 > Java' 카테고리의 다른 글
Optional 활용 기록 (0) | 2020.04.02 |
---|---|
모던자바인액션(CH2) - 동작 파라미터화 코드 전달 (0) | 2020.03.29 |
Hibernate(13) - 연관관계 매핑 연습 (0) | 2019.12.24 |
Spring Boot 테스트 활용(1) - JUnit 기초 환경설정 (0) | 2019.12.23 |
JUnit test 메소드 실행 순서 설정 (0) | 2019.12.23 |