Search
Duplicate
📒

[Java Study] 11-x. Collection API 개선( List, Set, Map )

상태
미진행
수업
Java Study
주제
Collection
4 more properties
참고

컬렉션 팩토리

NOTE
Java 9부터 작은 크기의 Collection 객체를 쉽게 만들 수 있는 방법을 제공한다!
List<String> friends = new ArrayList<>(); friends.add("Raphael"); friends.add("Olivia"); friends.add("Thibaut");
Java
복사
기존 방식은 상당히 번거로움
List<String> friends2 = Arrays.asList("Raphael", "Olivia"); friends2.set(0, "Rechard"); // friends2.add("Thibaut"); -> 에러 (내부적으로 고정된 크기이기 때문)
Java
복사
asList로 편하게 작성가능! (하지만 크기가 고정되므로 추가나 수정불가)
수정시 예외(Unsupported OperationException)가 발생한다
하지만 위의 방식은 List만 지원하므로 크게 권장하지 않음.

리스트 팩토리 ( List.of )

NOTE
List<String> friends = List.of("Raphael", "Olivia","Thibaut");
Java
복사
크기는 여전히 고정이라 수정불가

집합 팩토리( Set.of )

NOTE
Set<String> friends = Set.of("Raphael", "Olivia","Thibaut");
Java
복사
Set.of

맵 팩토리 ( Map.of, Map.ofEntries )

NOTE
Map<String, Integer> ageOfFriends = Map.of("Raphael", 30, "Olivia", 25, "Thibaut", 26);
Java
복사
Map.of ⇒ 팩토리 메서드에 키와 값을 번갈아 제공하여 생성
Map<String, Integer> ageOfFrieds = Map.ofEntries( entry("Raphael", 30), entry("Olivia", 25), entry("Thibaut", 26));
Java
복사
크기가 10 이상인 경우는 Map.Entries를 사용하는걸 권장

List와 Set 처리

NOTE
자바 8에서는 List, Set 인터페이스에 다음과 같은 메서드를 추가했다!
removeIf
프레디케이트를 만족하는 요소 제거
replaceAll
UnaryOperator 함수를 사용해서 요소를 바꾼다
sort
리스트 정렬

기존의 for-each 문제점

NOTE
for-each 루푸는 Iterator 객체를 사용하므로, 루프중 수정할 변경이 불가능하다!
ConcurrentModificationException을 일으킨다
위의 코드는 2개의 개별 객체가 컬렉션을 관리한다는 사실을 주목하자
Iterator 객체
next(), hasNext()를 이용해 소스를 질의한다.
Collection 객체 자체
remove()를 호출해 요소를 삭제한다.
결과적으로 반복자의 상태는 컬렉션의 상태와 서로 동기화 되지 않는다.
Collection은 지우는데, Iterator는 그대로 이기 때문
for(Iterator<Transaction> iterator = transactions.iterator(); iterator.hasNext();){ Transaction transaction = iterator.next(); if(transaction.getYear() == 2012){ iterator.remove(); } }
Java
복사
위 코드처럼 Collection이 아닌, iterator를 통해서 하나의 객체로만 관리하게한다. (현재 로직은 거래가 2012년도인건 제외하는 로직)
이러한 코드를 단축시켜주는 함수가 removeIf이다!

removeIf( 조건제거 )

NOTE
transactions.removeIf(i -> i.getYear() == 2012);
Java
복사
단 한줄로 위의 for-each코드를 고쳤

replaceAll( 각 요소 변경 )

NOTE
intList.replaceAll(i -> i*i);
Java
복사
람다 반환값이 기존 타입과 일치해야해서 1~100의 정수를가진 리스트로 테스트함

sort( 정렬 )

NOTE
intList.sort(Comparator.naturalOrder()); intList.sort(Comparator.reverseOrder());
Java
복사
정렬/역정렬

맵 처리

forEach, sorted, getOutDefault

NOTE
ageOfFriends.forEach((key, value) -> System.out.println("key = " + key + "value=" + value ));
Java
복사
forEach를 활용해서 key, value를 쉽게 꺼낼 수 있음
ageOfFriends.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) .sorted(Map.Entry.comparingByValue()) .forEachOrdered(System.out::println);
Java
복사
key나 value를 통한 정렬
ageOfFriends.getOrDefault("이름", 0);
Java
복사
이름이 있다면 value값인 나이가, 없다면 0이 나온다

계산 패턴( compute, computeIfAbsent, computeIfPresent )

NOTE
// 제공된 키로 새로운 값을 계산하고 저장한다. ageOfFriends.compute("Raphael", (name, value) -> 35); // 제공된 키의 값이 없다면 새로운 값을 저장한다. ageOfFriends.computeIfAbsent("noName", name -> 15); // 제공된 키의 값이 있다면 새로운 값을 저장한다. ageOfFriends.computeIfPresent("Olivia", (name, key) -> 50);
Java
복사
맵에 키가 존재하는지 여부에 따라 동작을 수행하고자 할 떄에 사용하는 연산들이다.

삭제 패턴( remove )

NOTE
ageOfFriends.remove("Raphael", 35);
Java
복사
key, value가 모두 있는값인 경우 제거한다.

교체 패턴 ( replaceAll )

NOTE
ageOfFriends.replaceAll((key, value) -> value + 5);
Java
복사
모든 항목에 대해서 key,value를 통한 함수실행

합침 ( putAll )

NOTE
Map<String, String> family = Map.ofEntries( entry("Teo", "Star Wars"), entry("Cristina", "James Bond")); Map<String, String> friends = Map.ofEntries( entry("Raphael", "Star wars")); Map<String, String> everyone = new HashMap<>(family); everyone.putAll(friends);
Java
복사
2개의 맵을 합친다

개선된 ConcurrentHashMap

NOTE
ConcrueentHashMap 클래스는 동시성 친화적이며 최신 기술을 반영한 HashMap이다.
내부 자료구조의 특정 부분만 잠궈 동시 추가, 갱신 작업을 허용한다.
동기화된 HashTable 버전에 비해 읽기/쓰기 연산 성능이 월등하다.