Java 8 - 2. 인터페이스의 변화
1. 인터페이스 기본 메소드와 스태틱 메소드
- 기본 메소드 (Default Methods)
-
인터페이스에 메소드 선언이 아니라 구현체를 제공하는 방법
-
해당 인터페이스를 구현한 클래스를 깨트리지 않고 새 기능을 추가할 수 있다.
-
기본 메소드는 구현체가 모르게 추가된 기능으로 그만큼 리스크가 있다.
-
컴파일 에러는 아니지만 구현체에 따라 런타임 에러가 발생할 수 있다.
-
반드시 문서화 할 것. (@implSpec 자바독 태그 사용)
-
-
Object가 제공하는 기능 (equals, hasCode)는 기본 메소드로 제공할 수 없다.
-
구현체가 재정의해야 한다.
-
-
본인이 수정할 수 있는 인터페이스에만 기본 메소드를 제공할 수 있다.
-
인터페이스를 상속받는 인터페이스에서 다시 추상 메소드로 변경할 수 있다.
-
인터페이스 구현체가 재정의 할 수도 있다.
-
- 스태틱 메소드
-
해당 타입 관련 헬퍼 또는 유틸리티 메소드를 제공할 때 인터페이스에 스태틱 메소드를 제공할 수 있다.
-
2. 자바 8 API의 기본 메소드와 스태틱 메소드
- Iterable의 기본 메소드
-
forEach()
-
spliterator()
-
forEach() : 각각의 요소들을 매개변수 삼아 동작한다. 밑의 예제에선 주석처리된 부분과 동일한 기능을 한다.
import java.util.ArrayList;
import java.util.List;
public class Practice {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("kim");
names.add("lee");
names.add( "park");
names.add( "jang");
names.forEach(System.out::println);
// for (String name : names) {
// System.out.println(name)
// }
}
}
실행결과
kim
lee
park
jang
spliterator() : 각 요소를 쪼갠다. 여러 번 사용시 해당 회수만큼의 덩어리로 나눈다. 순서는 좀 섞이는 듯하므로 주의해야 할 것 같다.
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
public class Practice {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("kim");
names.add("lee");
names.add( "park");
names.add( "jang");
Spliterator<String> spliterator = names.spliterator();
while (spliterator.tryAdvance(System.out::println));
}
}
실행결과
kim
lee
park
jang
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
public class Practice {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("kim");
names.add("lee");
names.add( "park");
names.add( "jang");
Spliterator<String> spliterator = names.spliterator();
Spliterator<String> spliterator1 = spliterator.trySplit();
Spliterator<String> spliterator2 = spliterator1.trySplit();
while (spliterator.tryAdvance(System.out::println));
System.out.println("============");
while (spliterator1.tryAdvance(System.out::println));
System.out.println("============");
while (spliterator2.tryAdvance(System.out::println));
}
}
실행결과
park
jang
============
lee
============
kim
- Collection의 기본 메소드
-
stream() / parallelStream()
-
removeIf(Predicate)
-
spliterator()
-
stream() / parallelStream() : 요소들을 stream으로 만들어 어떤 처리를 할 수 있는 기능을 만듦. 다양하게 사용되고 자주 사용되므로 따로 다룬다.
removeIf(Predicate) : Predicate에 해당하는 요소를 뺀다.
import java.util.ArrayList;
import java.util.List;
public class Practice {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("kim");
names.add("lee");
names.add("park");
names.add("jang");
names.removeIf(s -> s.startsWith("l"));
names.forEach(System.out::println);
}
}
실행결과
kim
park
jang
- Comparator의 기본 메소드 및 스태틱 메소드
-
reversed()
-
thenComparing()
-
static reverseOrder() / naturalOrder()
-
static nullsFirst() / nullsLast()
-
static comparing()
-
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Practice {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("kim");
names.add("lee");
names.add("park");
names.add("jang");
names.sort(String::compareToIgnoreCase);
names.forEach(System.out::println);
System.out.println("=========");
Comparator<String> compareToIgnoreCase = String::compareToIgnoreCase;
names.sort(compareToIgnoreCase.reversed());
names.forEach(System.out::println);
}
}
실행결과