Java

[Java][Tutorial] 3-1. Collections: Collection, Set, List

noahkim_ 2023. 10. 15. 18:10

1. Introduction

  • 여러 오브젝트를 하나의 단위로 그룹화하는 컨테이너

 

What Is a Collections Framework?

  • Collection을 표현하고 조작하기 위한 통합된 아키텍쳐입니다.

 

Interface
  • 컬렉션을 대표하는 추상 데이터 타입입니다.
  • 다양한 구현체들을 같은 방식으로 처리할 공통의 규약을 정의할 수 있습니다.

 

Implementations
  • 컬렉션 인터페이스의 실제 구현입니다.
  • 재사용 가능한 데이터 구조입니다.

 

Algorithms
  • 컬렉션 인터페이스를 구현한 객체의 메서드입니다. (검색, 정렬)
  • 모든 컬렉션 구현체에서 가지고 있습니다. (다형성)

 

Benefits of the Java Collections Framework

프로그래밍 노력 감소
  • 유용한 데이터 구조와 알고리즘을 제공합니다.
  • plumbing보다 중요한 부분에 집중할 수 있습니다.

 

프로그램의 속도와 품질 향상
  • 고성능 데이터 구조와 알고리즘 제공

 

관련 없는 API 간의 상호 운용성
  • 컬렉션 인터페이스는 API들이 컬렉션을 서로 주고받는 통용언어 역할을 합니다.

 

새로운 API를 학습하고 사용하는 노력 감소
  • 표준 컬렉션 인터페이스의 도입으로 각 API를 일일이 학습할 필요가 없어졌습니다.
  • 컬렉션을 기반으로 한 API를 생성할 때마다 기존의 것을 다시 만들 필요가 없습니다.

 

재사용성
  • 표준 컬렉션 인터페이스를 준수하는 새로운 데이터 구조나 알고리즘은 본질적으로 재사용 가능합니다.

 

2. Interfaces

Java Collections Framework의 기반이 되는 인터페이스들
  • 상속구조를 가집니다.
  • 제네릭 타입을 사용합니다.
    • 컬렉션 내의 객체 타입을 명시적으로 지정할 수 있게 해줍니다.
  • Map은 java.util의 인터페이스며 Collection 인터페이스에 속하지 않습니다.

 

The Collection Interface

  • Collection 인터페이스는 객체의 그룹, 즉 '요소'들의 그룹을 나타냅니다.
  • 최대한 일반성을 갖도록 설계되었으며, 다양한 종류의 컬렉션 구현체와 상호 작용할 수 있습니다.

 

Key Features

기본연산
  • size(): 컬렉션의 크기를 반환
  • isEmpty(): 컬렉션이 비어 있는지 확인
  • contains(Object element): 특정 요소가 컬렉션에 있는지 확인
  • add(E element), remove(Object element): 요소를 추가하거나 제거
  • iterator(): 컬렉션을 순회하기 위한 Iterator를 반환

 

전체 컬렉션에 대한 연산
  • containsAll(Collection<?> c): 한 컬렉션이 다른 컬렉션의 모든 요소를 포함하는지 확인
  • addAll(Collection<? extends E> c): 한 컬렉션의 모든 요소를 다른 컬렉션에 추가
  • removeAll(Collection<?> c): 한 컬렉션에서 다른 컬렉션의 모든 요소를 제거
  • retainAll(Collection<?> c): 한 컬렉션에서 다른 컬렉션에 포함되지 않은 모든 요소를 제거
  • clear(): 컬렉션의 모든 요소를 제거

 

배열 연산
  • toArray(): 컬렉션의 요소를 배열로 변환

 

스트림 연산
  • stream(): 순차 스트림 생성
  • parallelStream(): 병렬 스트림 생성

 

집계 연산
  • 스트림과 람다를 사용하여 컬렉션을 효과적으로 순회하고 데이터를 처리합니다.
String joined = elements.stream()
    .map(Object::toString)
    .collect(Collectors.joining(", "));

int total = employees.stream()
    .collect(Collectors.summingInt(Employee::getSalary)));

 

for-each Construct
  • 간단한 for 루프를 사용하여 컬렉션을 순회합니다.
myShapesCollection.stream()
    .filter(e -> e.getColor() == Color.RED)
    .forEach(e -> System.out.println(e.getName()));

 

Iterators
  • Iterator 객체를 사용하여 컬렉션을 순회하고, 선택적으로 요소를 제거할 수 있습니다.
static void filter(Collection<?> c) {
    for (Iterator<?> it = c.iterator(); it.hasNext(); )
        if (!cond(it.next())) it.remove();            
}

 

The Set Interface

  • Set은 중복된 요소를 포함할 수 없는 Collection입니다.
    • 수학적인 집합을 모델링합니다.
  • Set 인터페이스는 Collection에서 상속받은 메서드만 포함합니다.

 

구현체

HashSet
  • 해시 테이블에 요소를 저장합니다.
  • 가장 빠른 성능을 제공하지만 요소의 순서에 대한 보장이 없습니다.

 

TreeSet
  • 레드-블랙 트리에 요소를 저장합니다.
  • 요소를 값에 따라 정렬합니다.
  • HashSet보다 느립니다.

 

LinkedHashSet
  • 요소의 삽입 순서를 유지합니다.
  • 해시 테이블과 연결 리스트로 구현됩니다.

 

Key Features

기본연산
  • size(): Set의 요소 수를 반환합니다.
  • isEmpty(): Set이 비어 있으면 true를 반환합니다.
  • add(): 요소를 추가합니다.
  • remove(): 요소를 제거합니다.
  • iterator(): Set의 반복자를 반환합니다.

 

대량 연산
  • containsAll(), addAll(), retainAll(), removeAll()과 같은 메서드를 사용합니다.
  • 두 Set 간의 수학적 연산(합집합, 교집합, 차집합 등)을 수행할 수 있습니다.

 

Array 연산
  • Collection 인터페이스에서 설명된 연산을 그대로 사용합니다.

 

The List Interface

  • List는 순서대로 정렬된 컬렉션(또는 시퀀스)입니다.
    • 중복된 요소를 포함할 수 있습니다.
  • Collection에서 상속받은 연산 외에도, positional access, search, iteration, 그리고 range-view 등의 연산들을 포함합니다.

 

구현체

ArrayList
  • 동적 배열을 사용하여 요소를 저장합니다.
  • 인덱스 요소로 접근할 때 유용합니다.

 

LinkedList
  • 이중 연결 리스트를 사용하여 요소를 저장합니다.
  • 데이터 추가/제거가 많을 때 유용합니다.

 

Key Features

Positional Access
  • 요소의 숫자 위치를 기반으로 요소를 조작합니다.
  • get, set, add, addAll, remove 등의 메서드가 있습니다.

 

Search
  • 리스트 내에서 특정 객체를 검색하고 그 객체의 숫자 위치를 반환합니다.
  • indexOf 및 lastIndexOf 메서드를 포함합니다.

 

Collection 연산
  • Collection에서 상속받은 연산들은 대부분 예상대로 작동합니다.
  • add와 addAll 연산은 항상 새 요소를 리스트의 끝에 추가합니다.

 

Algorithms
  • Collections 클래스에는 List에 특화된 다양한 알고리즘이 있습니다.
  • sort, shuffle, reverse, rotate, swap, replaceAll, fill, copy, binarySearch 등의 알고리즘이 있습니다.

 

Range-View Operation (subList)
  • subList() 연산입니다.
  • 리스트의 특정 부분만을 보여주는 뷰를 반환합니다.
  • 반환된 List는 원래의 List에 의해 백업되므로 한 쪽에서의 변경이 다른 쪽에도 반영됩니다.
    • subList 메서드를 통해 얻은 부분 리스트가 원본 리스트의 요소를 가지고 있습니다.

 

Iterators
  • 기본 Iterator와 함께, 양방향 순회를 할 수 있는 ListIterator도 제공합니다.
    • List의 순차적 특성을 활용한 Iterator의 확장입니다.
    • listIterator 메서드를 통해 이 기능을 제공합니다.
public class ListIteratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");

        ListIterator<String> listIterator = list.listIterator();

        // 순방향 순회
        while(listIterator.hasNext()) {
            System.out.println(listIterator.next());
        }

        // 역방향 순회
        while(listIterator.hasPrevious()) {
            System.out.println(listIterator.previous());
        }
    }
}

 

 

 

출처