[Java] 컬렉션 (Collection)

✨New Wisdom✨·2020년 12월 10일
1

📕 Java 📕

목록 보기
7/24
post-thumbnail

이 노트는 "윤성우의 열혈 java 프로그래밍" 책을 공부하면서
내가 이해한대로 다시 정리하면서 작성되었다.

컬렉션 프레임워크

프레임워크란

프레임워크는 여러 분야에서 상이한 개념으로 쓰이지만
"잘 정의된 구조 또는 골격"이라는 공통된 의미를 가지고 있다.
따라서 자바에서의 프레임워크는 "잘 정의된 구조의 클래스들"이다.

컬렉션 의미와 자료구조

자료구조에서 정형화하고 있는 데이터의 저장 방식

  • 리스트
  • 스택
  • 트리
  • 해쉬

이 자료구조들을 대상으로 하는 간단한 알고리즘 몇 가지

  • 버블 정렬
  • 퀵 정렬
  • 이진 탐색

컬렉션 프레임워크란

자료구조와 알고리즘을 제네릭 기반의 클래스와 메소드로 미리 구현해 놓은 결과물.
자료구조를 몰라고 트리 기반으로 데이터 저장 가능하고,
알고리즘을 몰라도 이진 탐색이 가능하다.

컬렉션 프레임워크의 기본 골격

List<E> 인터페이스를 구현하는 컬렉션 클래스들

공통적인 특성

  • 인스턴스의 저장 순서를 유지한다.
  • 동일한 인스턴스의 중복 저장을 허용한다.

ArrayList<E> 클래스

import java.util.List;
import java.util.ArrayList;

class ArrayListCollection {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        
        // 인스턴스의 저장
        list.add("Toy");
        list.add("Box");
        list.add("Robot");
	
        for(int i = 0; i < list.size(); i++)
            System.out.print(list.get(i) + '\t'); // 원하는 위치 인스턴스 참조 가능
        System.out.println();
		
        // 인스턴스 값을 인자로 인스턴스 삭제
        list.remove(0); 
   
        for(int i = 0; i < list.size(); i++)
            System.out.print(list.get(i) + '\t');
        System.out.println();
    }
}

컬렉션 인스턴스를 사용하면 배열의 길이를 신경쓰지 않아도 된다.
ArrayList<E> 인스턴스는 내부적으로 배열을 생성해서 인스턴스를 저장하는데 필요하면 그 배열의 길이를 스스로 늘리기 때문이다.
저장되야 할 인스턴스 수가 대략 계산이 되면 생성자를 통해 적당한 길이의 배열을 미리 만들어 둔다.

LinkedList<E> 클래스

연결 리스트라는 자료구조를 기반으로 디자인된 클래스이다.
저장 공간을 열차 칸 추가하듯이 늘리기 때문에 인스턴스의 저장 공간을 미리 마련해 둘 필요가 없다.

import java.util.List;
import java.util.LinkedList;

class LinkedListCollection {
    public static void main(String[] args) {
        List<String> list = new LinkedList<>();
        
        list.add("Toy");
        list.add("Box");
        list.add("Robot");
	
        for(int i = 0; i < list.size(); i++)
            System.out.print(list.get(i) + '\t');
        System.out.println();
		
        list.remove(0);
   
        for(int i = 0; i < list.size(); i++)
            System.out.print(list.get(i) + '\t');
        System.out.println();
    }
}
  • 달라진 점은 List<String> list = new LinkedList<>(); 뿐이다.

ArrayList<E> VS LinkedList<E>

ArrayList<E>의 장점

  • 저장된 인스턴스의 참조가 빠르다.

ArrayList<E>의 단점

  • 저장 공간을 늘리는 과정에서 시간이 비교적 많이 소요된다.
  • 인스턴스의 삭제 과정에서 많은 연산이 필요할 수 있다.

배열 중간에 위치한 인스턴스를 삭제하면, 삭제 위치를 비워 두지 않기 위해 그 뒤에 지정되어 있는 인스턴스들을 한 칸씩 앞으로 이동한다.

LinkedList<E> 의 장점

  • 저장 공간을 늘리는 과정이 간단하다.
  • 저장된 인스턴스의 삭제 과정이 단순하다.

LinkedList<E> 의 단점

  • 저장된 인스턴스의 참조 과정이 배열에 비해 복잡하다.

참조할 때 맨 앞이나 맨 뒤에서 부터 하나씩 건너가야 하는 구조이기 때문이다.

저장된 인스턴스의 순차적 접근 방법

enhanced for 문 사용

for(String s : list)
            System.out.print(s + '\t');
        System.out.println();

반복자(iterator) 사용

반복자는 저장된 인스턴스들을 순차적으로 참조할 때 사용하는 인스턴스로 일종의 지팡이다.

List<String> list = new LinkedList<>();
...
Iterator<String> itr = list.iterator(); // 반복자 획득, itr이 지팡이를 참조한다.
...

iterator의 메소드

  • next() : 다음 인스턴스의 참조 값을 반환
  • hasNext() : next 메소드 호출 시 참조 값 반환 가능 여부 확인
  • remove() : next 메소드 호출을 통해 반환했던 인스턴스 삭제

반복자는 next를 호출할 때마다 다음 인스턴스의 참조값을 차례로 반환한다.
더 이상 반환할 대상이 없을 때 NoSuchElementException 예외를 발생시킨다.

컬렉션 변환

배열과 ArrayList<E>는 특성이 유사하지만 배열보다 ArrayList<E>가 대부분의 경우 더 좋다.
왜냐하면?

  • 인스턴스의 지정과 삭제가 용이하다.
  • 반복자를 쓸 수 있다.

일단 List<E> 인터페이스 까지 정리 ✍️


+

Collections.unmodifiableList

도움이 되었던 블로그

[Java] Unmodifiable Collection vs Immutable 차이점

이게 뭐야?

참고 문서
Collections 클래스의 unmodifiableList() 메소드는 지정된 목록의 수정이 불가능한 보기를 리턴하는데 사용된다.
이 메소드는 사용자에게 내부 목록에 대한 읽기 전용 액세스 권한을 제공할 수 있다.
만약 수정하려는 메소드(add(), set() 등)을 사용하면 UnsupportedOperationException 에러를 발생시킨다.

우테코 3차 미션의 코드 일부

이번 미션을 받고 샘플 코드에서 이 메소드가 나와서 어떤 메소드인지 공부하고자 정리해봤는데,
왜 이 메소드를 사용하라는지 알 것 같다!

public class StationRepository {
    private static final List<Station> stations = new ArrayList<>();

    public static List<Station> stations() {
        return Collections.unmodifiableList(stations);
    }

    public static void addStation(Station station) {
        stations.add(station);
    }

    public static boolean deleteStation(String name) {
        return stations.removeIf(station -> Objects.equals(station.getName(), name));
    }
}

존재하는 Station 클래스에 대해 StationRepository의 stations 메소드는 station의 리스트를 읽기 전용으로 반환하여 줘야 하기 때문에 Collections.unmodifiableList를 쓴 것으로 보인다.

  • Collections.emptyList()
  • enum 클래스
  • toString을 override하기
profile
🚛 블로그 이사합니다 https://newwisdom.tistory.com/

0개의 댓글