2. Java 8 을 눈여겨 봐야 하는 이유
1) 스트림 API : 병렬 연산을 지원하는 스트림이라는 새로운 API
• 스트림이란 한번에 한개씩 만들어지는 연속적인 데이터 항목들의 모임.
쉽게..;;스트림(Stream)은 자바 8부터 추가된 컬렉션(배열 포함)의 저장 요소를 하
나씩 참조해서 람다식(functional-style)으로 처리할 수 있도록 해주는 반복자입니다.
반복자 스트림
자바 7 이전까지는 List<String> 컬렉션에서 요소를 순차적으로 처리하기 위해 Iterator 반복
자를 다음과 같이 사용해왔습니다. ( 1장만 보다가도 스트림을 파야되게 생김 ...여기까지... 디
자인 패턴 1장의 Iterator패턴이 뭔가 연결되는것 같...)
• 예) unix에서 stdin으로 파일을 읽고 stdout으로 파일을 출력하는 형태
• cat file1 file2 | tr “[A-Z]” | sort | tail -3
• 스트림 파이프라인을 이용해서 입력부분을 여러 CPU 코어에 쉽게 할당할 수 있다. (즉
Thread Safe한 병렬성을 얻을 수 있다는 의미) 이렇다고 한다. 다음.
2
3. Java 8 을 눈여겨 봐야 하는 이유
2) 동작 파라미터화로 메서드에 코드 전달 (람다와 메서드 레퍼런스)
• 프로그래밍 언어의 핵심은 값을 바꾸는 것이 아닌가..? (다양한 제어와 조작을 통해서
)
• 그리고 전통적인 프로그래밍 언어(대표적인 Java)에서는 이 값을 일급(first-class) 또
는 시민이라 불렀다.
• 클래스, 메소드등은 이급 자바 시민이었다.
• 프로그램을 실행하는 동안 전달 할 수 있는 값은 일급 값 밖에 불가능했다. (즉 클래스,
메소드는 전달이 불가능 했다 )
• 그렇다면 클래스나 메소드를 일급값처럼 전달 할 수 있으면 어떨까? ( SmallTalk,
Javascript 같은 언어 처럼 )
- 이렇다고 한다. 책보고 다시 정리
3
4. Java 8 을 눈여겨 봐야 하는 이유
3) 인터페이스의 디폴트 메서드
• 더 쉽게 변화할 수 있는 인터페이스를 만들 수 있도록 디폴트 메서드라는 기능
을 추가 했다.
• 기본적으로 인터페이스는 메서드 바디를 가질 수 없지만, default 키워드를 사
용하면 인터페이스에 새로운 메서드 구현체를 추가할 수 있다.
4) Optional 클래스 제공
• NullPointer 예외를 피할 수 있도록 도와주는 클래스 / grep”cmd창
4
5. 동작 파라미터화 코드 전달하기
• 본격적으로 처음 부터 알아가보자.
• 동작 파라미터화 ( behavior parameterization) 를 이용하면 자주 바뀌는 고객의 요구사항에도 효과적으로 대응 할 수 있다.
• 이런 ‘동작 파라미터화’ 는 아직 어떻게 실행할 것인지 결정하지 않는 코드 블록 을 의미한다.
• 다음 예제는 고객이 사과 재고 중에서 초록 사과만 걸러내길 바라는 요구사항을 반영한 코드이다.
• 고객이 만약에 다른 색도 걸러내고 싶어 한다면?! ... 파라미터를 하나 더 추가....( , String color )
public static List filterGreenApples(List inventory){
List result = new ArrayList<>();
for(Apple apple: inventory){
if("green".equals(apple.getColor())){
result.add(apple);
}
}
return result;
}
- 하지만 여기다가 무게를 가지고 걸러내는것도 원한다면... 비슷한 로직의 메소드에 무게를 체크하는 조건으로만 바꿔서
쓸것.
5
6. 동작 파라미터화 코드 전달하기
public static List filterAppes(List inventory, String color, int weight, boolean flag){
List result = new ArrayList<>();
for(Apple apple: inventory){
if((flag && apple.getColor().equals(color)) ||
(!flag && apple.getWeight() > weight)) {
result.add(apple);
}
}
return result;
}
• 위처럼 속성 모두를 파라미터에 때려넣은 힘든 메소드가 탄생.
6
7. 이제 그럴수 없지!
• Java8을 배우게된 우리는 기존과는 다르게 Predicate를 도입하겠다는 생각을 하도록 한다.
( Predicate: 하나의 매개변수를 주고 boolean형을 반환하는 인터페이스를 구현해줄 수 있다. 인터페이스 구현 !!!!!!! )
8. 동작 파라미터화 코드 전달하기
interface ApplePredicate{
public boolean test(Apple a); // test 메소드에 원하는 조건을 파라미터로 주면 boolean으로 값을 뱉는다.
}
static class AppleWeightPredicate implements ApplePredicate{ //ApplePredicate 를 상속
public boolean test(Apple apple){
return apple.getWeight() > 150; //무게를 가지고 걸러낸다.
}
}
static class AppleColorPredicate implements ApplePredicate{
public boolean test(Apple apple){
return “green".equals(apple.getColor()); // 초록색 사과
}
}
static class AppleRedAndHeavyPredicate implements ApplePredicate{
public boolean test(Apple apple){
return "red".equals(apple.getColor())
&& apple.getWeight() > 150; // 빨간사과에 무게가 150보다 무거운 사과
}
}
8
9. 동작 파라미터화 코드 전달하기
• 추상적 조건 필터링 - Predicate 인터페이스를 설계하면서 다음과 같은 코드로 필터링이 가능해졌다.
public static List filterApples(List inventory, ApplePredicate p){
List result = new ArrayList<>();
for(Apple apple : inventory){
if(p.test(apple)){
result.add(apple);
}
}
return result;
}
• 하지만 새로운 새로운 조건을 만들기 위해서는 기존 Predicate를 Copy & Paste 해서 구현해야한다.
• 물론 파라미터를 Predicate 타입으로 통일화 했지만, 여전히 조건이 추가될 때 마다 새로운 인터페이스
를 구현해야하는 문제가 남아있다.
9
10. 동작 파라미터화 코드 전달하기
• 익명 클래스 사용..?
filterApples(inventory, new ApplePredicate() {
public boolean test(Apple apple) {
return "red".equals(apple.getColor());
}
});
• 위에 코드에서 핵심은 “red” Apple을 찾아내는 것인데, 익명클래스를 구현하면서 코드가 길어졌다.
• 뭐... 길어진거겠지... 일단 이것도 길다고하니 Java8의 신세계를 경험해 볼까.
10
11. 동작 파라미터화 코드 전달하기
• 람다 표현식 사용..?
filterApples(inventory, (Apple apple) -> “red".equals(apple.getColor());
• 람다 표현식으로 인해 코드가 매우 간결해졌고, 핵심로직이 잘 드러나 보인다. 어어어엄청 간결해보인
다.
• ‘ -> ‘ 화살표 : 포인터를 통해 구조체에 접근하기 위해 사용되는 연산자가 등장. 여기서는 그냥 가리키기
위한 수단이 겠지.
11
12. 동작 파라미터화 코드 전달하기
public interface Predicate {
boolean test(T t);
}
public static List filter(List list, Predicate p) {
List result = new ArrayList<>();
for(T e : list) {
if(p.test(e)) {
result.add(e);
}
}
return result;
}
List redApples = filter(inventory, (Apple apple) -> "red".equals(apple.getColor());
List heavyOranges = filter(inventory, (Orange orange) -> orange.getWeight() > 500);
12
• 이제는 어떠한 타입이든(T) 다양한 조건으로 (람다) 과일을 필터링 할 수 있게 되었다.........
13. 동작 파라미터화 코드 전달하기
• 정리
• 동작 파라미터화란 ?
= 메서드 내부적으로 다양한 동작을 수행할 수 있도록 코드를 메서드 인수로 전달하는 것을
말한다.
• 동작 파라미터화를 이용하면 ?
= 변화하는 요구사항에 좀더 유연하게 대응할 수 있고, 결국 엔지니어링 비용을 줄일 수 있다.
• 코드 전달 기법을 이용하면 ?
= 동작을 메서드의 인수로 전달 할 수 있는데, 자바8 이전에는 코드를 지저분하게 구현해야
했지만, 자바8부터는 인터페이스를 상속받아 여러 클래스를 구현해야 하는 수고를 없애고,
람다표현을 사용해 코드를 직접 파라미터화 할 수 있다.
13