반응형
자바 8에서 추가한 기본(default) 메소드로 인한 API 변화
Iterable의 기본 메소드
- forEach()
- spliterator()
Collection의 기본 메소드
- stream() / parallelStream()
- removeIf(Predicate)
- spliterator()
Comparator의 기본 메소드 및 스태틱 메소드
- reversed()
- thenComparing()
- static reverseOrder() / naturalOrder()
- static nullsFirst() / nullsLast()
- static comparing()
인터페이스 변경사항 활용 예제
public class Main {
/**
* 맵 key name의 값을 대문자로 변환한다.
* @param map
* @return
*/
public static String getMapNameToUpperCase(Map<String, Object> map){
return map.get("name").toString().toUpperCase();
}
/**
* 맵 생성 시간을 비교한다. 큰 값이 우선 출력
* @param map1
* @param map2
* @return
*/
public static int mapCreateTimeCompare(Map map1, Map map2) {
return Integer.parseInt(map2.get("createTime").toString())-Integer.parseInt(map1.get("createTime").toString());
}
public static void main(String[] args){
/* forEach(), spliterator() */
List<Map<String, Object>> name = new ArrayList<>();
name.add(Map.of("name", "history", "createTime", (int)System.currentTimeMillis()));
name.add(Map.of("name", "devdev", "createTime", (int)System.currentTimeMillis()+1));
name.add(Map.of("name", "appleapple", "createTime", (int)System.currentTimeMillis()+2));
name.add(Map.of("name", "apple", "createTime", (int)System.currentTimeMillis()+3));
name.add(Map.of("name", "HooHoo", "createTime", (int)System.currentTimeMillis()+4));
name.add(Map.of("name", "HooHoo", "createTime", (int)System.currentTimeMillis()+5));
name.add(Map.of("name", "HooHoo", "createTime", (int)System.currentTimeMillis()+6));
name.add(Map.of("name", "barbar", "createTime", (int)System.currentTimeMillis()+7));
name.forEach(System.out::println);
System.out.println("###############");
//쪼갤 수 있는 기능을 가진 Iterator. 기본적으로는 Iterator와 같다
Spliterator<Map<String, Object>> originSpliterator = name.spliterator();
Spliterator<Map<String, Object>> spliterator = name.spliterator();
//쪼개는 기능. 원래 spliterator에서 가지고 있던 엘리먼트를 반으로 쪼개서 기존 spliterator에 넣어주고 나머지 반의 엘리먼트는 spliterator1에 넣어준다. 엘리먼트의 순서가 중요하지 않을 때 사용(병렬 처리).
Spliterator<Map<String, Object>> spliterator1 = spliterator.trySplit();
//hasNext() 대신 tryAdvance 사용. 다음 것이 있으면 true, 없으면 false 반환
System.out.println("===originSpliterator(spliterator 반으로 나누기 전의 원본)===");
while (originSpliterator.tryAdvance(System.out::println));
System.out.println("###############");
System.out.println("===spliterator===");
while (spliterator.tryAdvance(System.out::println));
System.out.println("===spliterator1===");
while (spliterator1.tryAdvance(System.out::println));
System.out.println("###############");
/* //forEach(), spliterator() */
/* stream() */
long count = name.stream().map(Main::getMapNameToUpperCase)
.filter(s -> s.startsWith("H"))
.count();
System.out.println(count);
System.out.println("###############");
/* //stream() */
/* removeIf() */
//조건을 만족하는 엘리먼트 삭제처리
name.removeIf((s) -> s.get("name").toString().startsWith("d"));
name.forEach(System.out::println);
System.out.println("###############");
/* //removeIf() */
/* reversed(), thenComparing() */
//문자순으로 정렬
Comparator<Map<String, Object>> compareToIgnoreCase = (map1, map2) -> map1.get("name").toString().compareToIgnoreCase(map2.get("name").toString());
name.sort(compareToIgnoreCase);
System.out.println("===compareToIgnoreCase===");
name.forEach(System.out::println);
//문자역순으로 정렬
name.sort(compareToIgnoreCase.reversed());
System.out.println("===compareToIgnoreCase.reversed()===");
name.forEach(System.out::println);
//문자역순으로 정렬 후 추가적인 비교가 더 필요한 경우에 사용. 정렬 결과 중 같은 값에 대해서 정렬 수행
//문자역순으로 정렬 후, 같은 값이 있다면 나중에 생성된 것이 우선적으로 표시되도록 정렬
name.sort(compareToIgnoreCase.reversed().thenComparing(Main::mapCreateTimeCompare));
System.out.println("===compareToIgnoreCase.reversed().thenComparingInt(Main::mapCreateTimeCompare)===");
name.forEach(System.out::println);
/* //reversed(), thenComparing() */
}
}
자바8 인터페이스 구조 변화
- 인터페이스에서 기본적으로 메소드를 제공할 수 없던 자바8 이전의 버전에서는 인터페이스에 선언된 추상메소드를 모두 구현해야 했기 때문에 필요한 메소드만 사용할 수 있도록 하기 위해서 별도로 추상 클래스를 중간에 두어 메소드의 기본 동작에 대해 정의하고 사용자가 필요하다면 원하는 추상 메소드를 재정의하여 사용할 수 있도록 처리하였다.
- 다만 이 방식은 클래스의 상속이 인터페이스에 의존되는 문제가 있다. 따라서 인터페이스를 사용하면 다른 원하는 클래스를 상속 받지 못하는 현상이 일어난다.
- 자바8의 등장으로 라이브러리 구조가 변경되었다. 인터페이스의 default 키워드를 통해서 인터페이스에서 메소드의 기본 동작을 정의할 수 있기 때문에 별도의 추상클래스가 없어도 사용자는 필요한 추상메소드만 구현해서 사용하거나 기존에 정의된 인터페이스의 default 메소드 재정의를 통해서 원하는 동작을 수행할 수 있도록 할 수 있다.
- 자바8 이전 방식에서 발생했던 인터페이스에 의존적인 문제에서 벗어나 원하는 클래스의 상속이 가능해졌다.(비침투성)
[참고자료]
반응형
'Java > 기본' 카테고리의 다른 글
자바 스트림(Java Stream) API - 2 (스트림 API 활용) (0) | 2021.06.27 |
---|---|
자바 스트림(Java Stream) API - 1 (스트림 개념 소개) (0) | 2021.06.26 |
자바 인터페이스(Java Interface) 변화 - 1 (기본 메소드, 스태틱 메소드) (0) | 2021.06.22 |
자바 람다(Java Lambda) - 4 (메소드 레퍼런스) (0) | 2021.06.20 |
자바 람다(Java Lambda) - 3 (람다 표현식 사용 조건) (0) | 2021.06.17 |