본문 바로가기

복습

[Java 복습] 컬렉션 유틸

목차

  • 컬렉션 유틸 - 정렬
  • 컬렉션 생성
  • 불변 컬렉션 가변 컬렉션 전환
  • 멀티 스레드 동기화

 

컬렉션 유틸

 

컬렉션을 편리하게 다룰 수 있는 다양한 기능을 알아보자.

 

정렬

public class CollectionsSortMain {

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        Integer max = Collections.max(list);
        Integer min = Collections.min(list);

        System.out.println("max = " + max);
        System.out.println("min = " + min);

        System.out.println("list = " + list);
        Collections.shuffle(list);
        System.out.println("shuffleList = " + list);

        Collections.sort(list);
        System.out.println("list = " + list);

        Collections.reverse(list);
        System.out.println("list = " + list);
    }
}
max = 5
min = 1
list = [1, 2, 3, 4, 5]
shuffle list = [2, 4, 1, 5, 3] //랜덤
sort list = [1, 2, 3, 4, 5]
reverse list = [5, 4, 3, 2, 1]

 

 

Collections 정렬 관련 메서드


max : 정렬 기준으로 최대 값을 찾아서 반환한다.
min : 정렬 기준으로 최소 값을 찾아서 반환한다.
shuffle : 컬렉션을 랜덤하게 섞는다.
sort : 정렬 기준으로 컬렉션을 정렬한다.
reverse : 정렬 기준의 반대로 컬렉션을 정렬한다.

 

 

 

편리한 컬렉션 생성

public class OfMain {

    public static void main(String[] args) {

        // 편리한 불변 컬렉션 생성
        List<Integer> list = List.of(1, 2, 3);
        Set<Integer> set = Set.of(1, 2, 3);
        Map<Integer, String> map = Map.of(1, "one", 2, "two");

        System.out.println("list = " + list);
        System.out.println("set = " + set);
        System.out.println("map = " + map);
        System.out.println("list class() = " + list.getClass());

        // UnsupportedOperationException 예외 발생
        // list.add(1);
    }
}
list = [1, 2, 3]
set = [1, 2, 3]
map = {1=one, 2=two}
list class = class java.util.ImmutableCollections$ListN
  • List.of(...) : 를 사용하면 컬렉션을 편리하게 생성할 수 있다. 단 이때는 가변이 아니라 불변 컬렉션이 생성된다.
  • List , Set , Map 모두 of() 메서드를 지원한다.
  • 불변 컬렉션은 변경할 수 없다. 변경 메서드를 호출하면 UnsupportedOperationException 예외가 발생한다.

 

 

불변 컬렉션과 가변 컬렉션 전환

public class ImmutableMain {

    public static void main(String[] args) {
        // 불변 리스트 생성
        List<Integer> list = List.of(1, 2, 3);

        // 가변 리스트
        ArrayList<Integer> mutableList = new ArrayList<>(list);
        mutableList.add(4);
        System.out.println("mutableList = " + mutableList);
        System.out.println("mutableList class() = " + mutableList.getClass());

        // 다시 블변
        List<Integer> unmodifiableList = Collections.unmodifiableList(mutableList);
        System.out.println("unmodifiableList class() = " + unmodifiableList.getClass());

        // UnsupportedOperationException
        // unmodifiableList.add(3);
    }
}
mutableList = [1, 2, 3, 4]
mutableList class() = class java.util.ArrayList
unmodifiableList class() = class java.util.Collections$UnmodifiableRandomAccessList
  • 불변 리스트를 가변 리스트로 전환하려면 new ArrayList<>() 를 사용하면 된다.
  • 가변 리스트를 불변 리스트로 전환하려면 Collections.unmodifiableList() 를 사용하면 된다.
  • 물론 다양한 unmodifiableXxx() 가 존재한다.

 

 

public class EmptyListMain {

    public static void main(String[] args) {
        // 빈 가변 리스트 생성
        List<Integer> list1 = new ArrayList<>();
        List<Integer> list2 = new ArrayList<>();

        // 빈 불변 리스트 생성
        List<Integer> list3 = Collections.emptyList(); // 자바 5
        List<Integer> list4 = List.of(); // 자바 9

        System.out.println("list3 = " + list3.getClass());
        System.out.println("list4 = " + list4.getClass());
    }
}
list3 = class java.util.Collections$EmptyList
list4 = class java.util.ImmutableCollections$ListN
  • 빈 가변 리스트는 원하는 컬렉션의 구현체를 직접 생성하면 된다.
  • 빈 불변 리스트는 2가지 생성 방법이 있다.

Collections.emptyList( ) : 자바5부터 제공되는 기능이다.
List.of( ) : 자바9부터 제공되는 최신 기능이다.
List.of( ) 가 더 간결하고, List.of(1,2,3) 도 불변이기 때문에 사용법에 일관성이 있다. 

자바 9 이상을 사용한다면 이 기능을 권장한다.

 

 

 

멀티스레드 동기화

public class SyncMain {

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);

        System.out.println("list class = " + list.getClass());
        List<Integer> synchronizedList = Collections.synchronizedList(list);
        System.out.println("synchronizedList class() = " + synchronizedList.getClass());
    }
}
list class = class java.util.ArrayList
synchronizedList class() = class java.util.Collections$SynchronizedRandomAccessList

 

Collections.synchronizedList 를 사용하면 일반 리스트를 멀티스레드 상황에서 동기화 문제가 발생하지 않는 

안전한 리스트로 만들 수 있다. 동기화 작업으로 인해 일반 리스트보다 성능은 더 느리다.