본문 바로가기
자바

[Java] 컬렉션 프레임워크(Collection Framework)

by 책 읽는 개발자_테드 2021. 9. 5.
반응형

컬렉션 프레임워크란?

·  자바에서 다수의 데이터를 효과적으로 처리하는 표준화된 방법을 제공하는 클래스 및 인터페이스 집합

Collection: 다수의 데이터 / Framework: 표준화된 프로그래밍 방식

 

·  컬렉션 프레임워크의 핵심 인터페이스

0. 다수의 데이터를 처리할 때 공통적으로 사용되는 메소드 정의: Collection

1. 순서가 있는 목록형: List

2. 순서가 중요하지 않은 셋형: Set

3. 먼저 들어온 것이 먼저 나가는 큐형: Queue

4. 키-값으로 저장되는 맵형: Map

http://tcpschool.com/java/java_collectionFramework_concept

 

컬렉션 인터페이스와 구현 클래스

Collection

public interface Collection<E> extends Iterable<E>

·  List, Set, Queue의 조상 인터페이스

·  Iterable<E> 인터페이스를 상속

    - Iterable 인터페이스에 선언되어 있는 메소드는 Iterator() 메소드 하나, 이 메소드는 Iterator 인터페이스를 리턴

    - Iterator 인터페이스에는 추가 데이터가 있는지 확인하는 hasNext(), 현재 위치를 다음 요소로 넘기고 그 값을 리턴하는 next(), 데이터를 삭제하는 remove() 메소드 존재

·  Iterable 인터페이스 확장의 의미: Iterator 인터페이스를 사용하여 데이터를 순차적으로 가져올 수 있음

·  정의되어 있는 메서드 정보: https://docs.oracle.com/javase/9/docs/api/java/util/Collection.html

·  해당 인터페이스를 구현한 클래스는 향상된 for문(Enhanced For Loop) 사용 가능 

    - for(타입이름 임시변수명 : 반복대상객체)

 

 Collection 인터페이스에 선언된 메소드

리턴 타입 메소드 이름 및 매개 변수 설명
boolean add(E e) · 요소를 추가
boolean addAll(collection) · 매개 변수로 넘어온 컬렉션의 모든 요소 추가
void clear() · 컬렉션에 있는 모든 요소 데이터 제거
boolean contains(Object) · 매개 변수로 넘어온 객체가 해당 컬렉션에 있는지 확인
· 동일한 값이 있으면 true 리턴
boolean containsAll(Collection) · 매개 변수로 넘어온 객체들이 해당 컬렉션에 있는지 확인
· 매개 변수로 넘어온 컬렉션에 있는 요소들과 동일한 값들이 모두 있으면 true 리턴
boolean equals(Object) · 매개 변수로 넘어온 객체와 같은 객체인지 확인
int hashCode() · 해시 코드값을 리턴
boolean isEmpty() · 컬렉션이 비어있는지 확인
· 비어있으면 true 리턴
Iterator iterator() · 데이터를 한 건씩 처리하기 위한 Iterator 객체 리턴
boolean remove(Object) · 매개 변수와 동일한 객체를 삭제
boolean removeAll(Collection) · 매개 변수로 넘어온 객체들을 해당 컬렉션에서 삭제
boolean retainAll(Collection) · 매개 변수로 넘어온 객체들만을 컬렉션에 남김
int size() · 요소의 개수를 리턴
Object[] toArray() · 컬렉션에 있는 데이터들을 배열로 복사
<T> T[] toArray(T[]) · 컬렉션에 있는 데이터들을 지정한 타입의 배열로 복사

 

List

· 중복을 허용하면서 저장순서가 유지되는 컬렉션을 구현하는데 사용

정의되어 있는 메서드 정보 -> https://docs.oracle.com/javase/9/docs/api/java/util/List.html  

 

· 구현체: ArrayList, LinkedList, Stack, Vector 등

List의 상속계층도 https://url.kr/ov4bn8

 

ArrayList

· 확장 가능한 배열

· Vector와 사용법과 기능이 거의 동일. 단, Vector는 Thread safe, ArrayList는 Thread safe x

· ArrayList는 동시에 여러 개의 스레드가 접근 가능하고, Vector는 한 개의 스레드만 접근 가능 

&amp;amp;amp;nbsp; https://media.geeksforgeeks.org/wp-content/uploads/ArrayList-vs-Vector-Java.png

 

·  ArrayList의 상속 구조 (Object - AbstractCollection - AbstractList 순으로 확장)

https://programming.vip/docs/5ce22bde069e7.html

 

ArrayList가 구현한 인터페이스

인터페이스 용도
Serializable 원격으로 객체를 전송하거나, 파일에 저장할 수 있음을 지정 
Cloneable Object 클래스의 clone() 메소드가 제대로 수행될 수 있음을 지정 (복제가 가능한 객체)
Iterable<E> 객체가 "foreach" 문장을 사용할 수 있음을 지정
Collection<E> 여러 개의 객체를 하나의 객체에 담아 처리할 때의 메소드 지정
List<E> 목록형 데이터를 처리하는 것과 관련된 메소드 지정
RandomAccess 랜덤으로 접근하는 알고리즘이 적용된다는 것을 지정 (목록형 데이터 보다 빠르게 접근)

ArrayList의 생성자

생성자 설명
ArrayList() 객체를  저장할 공간이 10개인 ArrayList 생성
ArrayList(Collection<? extends E> c) 매개 변수로 넘어온 컬렉션 객체가 저장되어 있는 ArrayList 생성
ArrayList(int initialCapacity) 매개 변수로 넘어온 initialCapacity 개수만큼의 저장 공간을 갖는 ArrayList 생성

· 데이터의 크기가 예측 가능하다면 예측 가능한 초기 크기를 지정하자. 매개 변수를 넣지 않으면 초기 크기는 10이다. 10개 이상의 데이터가 들어가면 크기를 늘리는 작업이 자동으로 수행되고, 이는 애플리케이션 성능에 영향을 준다. 

 

·  ArrayList는 Thread safe하지 않으므로 여러 쓰레드에서 덤벼도 안전하게 만들려면 다음과 같이 객체를 생성

List list = Collections.synchronizedList(new ArrayList<>());

 

ArrayList에 선언된 메소드 - 데이터 추가

리턴 타입 메소드 이름 및 매개 변수 설명
boolean add(E e) · 매개 변수로 넘어온 데이터를 가장 끝에 저장
· 데이터 추가 성공 여부를 boolean 타입으로 리턴
void add(int index, E e) · 매개 변수로 넘어온 데이터를 지정된 index 위치에 저장
· 위치를 잘못 지정하면 IndexOutOfBoundsException 발생
boolean allAll(Collection<? extends E> c) · 매개 변수로 넘어온 컬렉션 데이터를 가장 끝에 저장 
boolean allAll(int index, Collection <? extends E>c) · 매개 변수로 넘어온 컬렉션 데이터를 index에 지정된 위치부터 저장 

· Collection을 매개 변수로 제공하는 메서드, 생성자가 존재하는 이유: ArrayList, Set, Queue 등 다양한 클래스를 사용하여 데이터를 담을 수 있기 때문이다.

 

참고지식 - Deep copy, Shallow copy

        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>(list1); //Deep copy
        list2 = list1; //Shallow Copy

· Deep copy: 원본 객체의 모든 값을 복사하여 다른 객체에 할당, 복제된 객체에 있는 값을 변경해도 원본에 영향 x

· Shallow copy: 원본 객체의 주소 값만을 다른 객체에 할당, 복제된 객체에 있는 값을 변경하면 원본에 영향 ㅇ 

 

ArrayList 선언된 메소드 - 데이터 가져오기

리턴 타입 메소드 이름 및 매개 변수 설명
int size() ArrayList 객체에 들어가 있는 데이터 개수 리턴
E get(int index) 매개 변수에 지정한 위치에 있는 데이터 리턴
int indexOf(Object o) 매개 변수로 넘어온 객체와 동일한 첫 번째 데이터 위치를 리턴
int lastIndexOf(Object o) 매개 변수로 넘어온 객체와 동일한 마지막 마지막 데이터 위치 리턴

· 주의! : 배열.length는 배열의 저장 공간 개수를 의미, size() 메소드의 결과는 ArrayList에 들어가 있는 데이터 개수를 의미

 

ArrayList 선언된 메소드 - 배열로 변환

리턴 타입 메소드 이름 및 매개 변수 설명
Object[] toArray() ArrayList 객체에 있는 값들을 Object[] 타입의 배열로 변환
<T> T[] toArray(T[] a) ArrayList 객체에 있는 값들을 매개 변수로 넘어온 T 타입의 배열로 변환

예시

        List<String> list1 = new ArrayList<>();
        list1.add("A");
        list1.add("B");
        list1.add("C");
        String[] strList = list1.toArray(new String[0]);
        for (String str: strList)
            System.out.println(str);

결과

ArrayList 선언된 메소드 - 데이터 삭제

리턴 타입 메소드 이름 및 매개 변수 설명
void clear() 모든 데이터 삭제
E remove(int index) 매개 변수에서 지정한 위치에 있는 데이터를 삭제하고, 삭제한 데이터를 리턴
boolean remove(Object o) 매개 변수에 넘어온 객체와 동일한 첫 번째 데이터 삭제
boolean removeAll(Collection<?> c) 매개 변수로 넘어온 컬렉션 객체에 있는 데이터와 동일한 모든 데이터를 삭제

ArrayList 선언된 메소드 - 데이터 수정

리턴 타입 메소드 이름 및 매개 변수 설명
E set(int index, E element) · 지정한 위치(index)에 있는 데이터를 두 번째 매개 변수로 넘긴 값으로 변경 후 해당 위치에 있던 데이터 리턴

기타메소드

리턴 타입 메소드 이름 및 매개 변수 설명
void trimToSize 객체 공간 크기를 데이터의 개수만큼으로 변경

· 객체를 원격으로 전송하거나 파일로 저장할 때 호출하면, 데이터의 크기를 줄일 수 있음

 

List와 ArrayList 선언의 차이

 

List<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();

 

위의 list1 변수처럼 ArrayList가 아닌 List로 선언된 변수는 다음과 같이 필요에 따라 다른 리스트 클래스를 쓸 수 있는 구현상의 유연성을 제공한다. (즉, 대체할 수 있다)

 

List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list1 = new LinkedList<Integer>();

 

타입의 생략

JDK 1.7 이상부터는 인스턴스 생성시 타입을 추정할 수 있는 경우 타입을 생략할 수 있다.

 

List<Integer> list1 = new ArrayList<>();

 

Stack

·  Stack 클래스는 Vector 클래스를 확장

·  후입선출(LIFO, Last In First Out)을 지원하기 위해 필요

·  Stack보다 성능이 좋은 ArrayDeque라는 클래스도 존재

·  Stack은 Thread safe, ArrayDeque는 x

·  사용예시 - 프로그래밍 언어에서 메소드가 호출된 순서를 기억하는 장소

·  Stack 상속 구조 

https://eskeptor.tistory.com/97

· 구현한 인터페이스는 ArrayList와 동일 (Serializable, Cloneable, Iiterable<E>, Collection<E>, List<E>, RandomAccess) 

 

Stack의 생성자

생성자 설명
Stack() 아무 데이터도 없는 Stack 객체 생성

Stack에 선언된 메소드

리턴 타입 메소드 이름 및 매개 변수 설명
boolean empty() 객체가 비어있는지 확인
E peek() 객체의 가장 위에 있는 데이터 반환
E pop() 객체의 가장 위에 있는 데이터를 지우고, 반환
E push(E item) 매개 변수로 넘어온 데이터를 가장 위에 저장
int search(Object c) 매개 변수로 넘어온 데이터의 위치를 반환

 

Set

· 중복을 허용하지 않고, 저장순서가 유지되지 않는 컬렉션 클래스를 구현

· 주된 용도: 중복되는 것을 방지하고, 원하는 값이 포함되어 있는지 확인

· 정의되어 있는 메서드 정보: https://docs.oracle.com/javase/9/docs/api/java/util/Set.html  

· Set 구현체

- HashSet: 순서가 전혀 필요 없는 데이터를 해시 테이블에 저장. 정렬 작업 x. Set 중에 가장 좋은 성능.

- TreeSet: 저장된 데이터의 값에 따라 정렬되는 셋. red-black 트리 타입으로 값  저장. HashSet보다 느린 성능.

- LinkedHashSet: 연결된 목록 타입으로 구현된 해시 테이블에 데이터 저장. 저장된 순서에 따라 값이 정렬. 셋 중 성능이 가장 느림.

 

https://url.kr/kism5x

 

HashSet

·  HashSet 상속 구조 

· AbstractSet 클래스에 구현되어 있는 메소드: equals, hashcode, removeAll

 

HashSet이 구현한 인터페이스

인터페이스 용도
Serializable 원격으로 객체를 전송하거나, 파일에 저장할 수 있음을 지정 
Cloneable Object 클래스의 clone() 메소드가 제대로 수행될 수 있음을 지정 (복제가 가능한 객체)
Iterable<E> 객체가 "foreach" 문장을 사용할 수 있음을 지정
Collection<E> 여러 개의 객체를 하나의 객체에 담아 처리할 때의 메소드 지정
Set<E> 셋 데이터를 처리하는 것과 관련된 메소드 지정

· Set은 순서가 없으므로 List 처럼 순서가 매개 변수로 넘어가는 메소드(get)나 수행 결과가 데이터의 위치와 관련된 메소드(indexOf)가 존재하지 않는다.

 

HashSet의 생성자

생성자 설명
HashSet() 데이터를 저장할 수 있는 16개의 공간과 0.75의 로드 팩터를 갖는 객체 생성
HashSet(Collection<? extends E> c) 매개 변수로 받은 컬렉션 객체의 데이터를 HashSet에 저장
HashSet(int initialCapacity) 매개 변수로 받은 개수만큼의 데이터 저장 공간과 0.75의 로드 팩터를 갖는 객체 생성
HashSet(int initialCapacity, float loadFactor) 첫 매개 변수로 받은 개수만큼의 데이터 저장 공간과 두 번째 매개 변수로 받은 만큼의 로드 팩터를 갖는 객체 생성

· 로드팩터: 데이터 개수 / 저장 공간

· 데이터의 개수가 증가하여 로드 팩터보다 커지면, 저장 공간의 크기는 증가되고 해시 재정리 작업이 필요

     - 내부에 갖고 있는 자료 구조를 다시 생성하는 단계를 거치므로 성능에 영향

·  로그 팩터가 클수록 공간은 넉넉해지지만, 데이터를 찾는 시간은 증가

 

HashSet에 선언된 메소드

리턴 타입 메소드 이름 및 매개 변수 설명
boolean add(E e) 데이터 추가
void clear() 모든 데이터 삭제
Object clone() HashSet 객체를 복제 (담겨 있는 데이터들은 복제x)
boolean contains(Object c) 지정한 객체가 존재하는지 확인
boolean isEmpty() 데이터가 있는지 확인
Iterator<E> iterator() 데이터를 꺼내기 위한 Iterator 객체 리턴
boolean remove(Object o) 매개 변수로 넘어온 객체를 삭제
int size() 데이터 개수 리턴

· HashSet에 저장되어 있는 값을 꺼래는 방법: for문, Iterator 객체 얻기

 

Queue

· 먼저 들어온 데이터를 먼저 처리해주는FIFO(First In First Out) 기능을 지원하기 위해 필요한 인터페이스

· 여러 쓰레드에서 들어오는 작업을 순차적으로 처리할 때 많이 사용 ex) 웹서버에서 사용자들의 요청을 들어온 순서대로 처리

 

LinkedList

· 리스트 구조의 데이터가 지속적으로 삭제되고, 추가될 경우 메모리 공간 측면에서 유리함 

   - ArrayList, Vector는 각 위치가 정해져 있어서 값을 삭제하면, 그 뒤에 있는 값들을 하나씩 앞으로 위치를 이동해야

     제대로 된 위치의 값을 갖는다.

   - 반면에 LinkedList는 중간에 있는 데이터를 삭제하면, 지운 데이터의 앞에 있는 데이터와 뒤에 데이터를 연결하면 그만이다.

      즉, 위치를 맞추기 위해 값을 이동하는 단계가 필요 없다.

·  List, Queue, Deque 인터페이스를 구현

·  LinkedList 상속 구조

https://www.benchresources.net/linkedlist-class-in-java/

 

LinkedList가 구현한 인터페이스

인터페이스 용도
Serializable 원격으로 객체를 전송하거나, 파일에 저장할 수 있음을 지정 
Cloneable Object 클래스의 clone() 메소드가 제대로 수행될 수 있음을 지정 (복제가 가능한 객체)
Iterable<E> 객체가 "foreach" 문장을 사용할 수 있음을 지정
Collection<E> 여러 개의 객체를 하나의 객체에 담아 처리할 때의 메소드 지정
Deque<E> · 맨 앞과 맨 뒤의 값을 용이하게 처리하는 큐와 관련된 메소드 지정
· Double Ended Queue의 약자 
List<E> 목록형 데이터를 처리하는 것과 관련된 메소드 지정
Set<E> 셋 데이터를 처리하는 것과 관련된 메소드 지정

LinkedList의 생성자

생성자 설명
LinkedList() 비어 있는 LinkedList 객체 생성
LinkedList(Collection<? extends E> c) 매개 변수로 받은 컬렉션 객체의 데이터를 LinkedList에 저장

·  일반적인 배열 타입의 클래스와 다르게 생성자로 객체를 생성할 때 크기를 지정하지 않음

     - 각 데이터들이 앞 뒤로 연결되는 구조이므로, 미리 공간을 만들어 놓을 필요가 없음 

 

LinkedList에 선언된 메소드 - 데이터 추가

리턴 타입 메소드 이름 및 매개 변수 설명
void addFirst(Object) LinkedList 객체의 가장 앞에 데이터 추가
boolean offerFirst(Object)
void push(Object)
boolean add(Object) LinkedList 객체의 가장 뒤에 데이터 추가
void addLast(Object)
boolean offer(Object)
boolean offerLast(Object)
void add(int, Object) LinkedList 객체의 특정 위치에 데이터 추가
Object set(int, Object) LinkedList 객체의 특정 위치에 있는 데이터 수정, 기존에 있는 데이터 반환
boolean addAll(Collection) 매개 변수로 넘긴 컬렉션의 데이터를 추가
boolean addAll(int, Collection) 매개 변수로 넘긴 컬렉션의 데이터를 지정된 위치에 추가

· 중복된 기능을 수행하는 메소드가 많다. 메소드를 혼용하면 가독성이 떨어지므로 한가지만 선정하여 사용하는 것으 권장하며, add가 붙은 메소드를 사용하는 것이 오해의 소지가 가장 적다.

 

LinkedList에 선언된 메소드 - 데이터 꺼내기

리턴 타입 메소드 이름 및 매개 변수 설명
Object getFirst() LinkedList 객체의 맨 앞에 있는 데이터 리턴
Object peekFirst()
Object peek()
Object element() LinkedList 객체의 맨 뒤에 있는 데이터 리턴
Object getLast()
Object peekLast() LinkedList 객체의 지정한 위치에 있는 데이터 리턴
Object get(int)

LinkeList에 선언된 메소드 - 포함된 객체 확인

리턴 타입 메소드 이름 및 매개 변수 설명
boolean contains(Object) 매개 변수로 넘긴 데이터가 있으면 true 리턴
int indexOf(Object) 매개 변수로 넘긴 데이터의 위치를 앞에서부터 검색하여 리턴, 없을 경우 -1 리턴
int lastIndexOf(Object) 매개 변수로 넘긴 데이터의 위치를 끝에서부터 검색하여 리턴, 없을 경우 -1 리턴

LinkedList에 선언된 메소드 - 데이터 삭제 (대부분 데이터 삭제 후 리턴)

리턴 타입 메소드 이름 및 매개 변수 설명
Object remove() LinkedList 객체의 맨 앞에 있는 데이터를 삭제하고 리턴
Object removeFirst()
Object poll()
Object pollFirst()
Object pollLast() LinkedList 객체의 맨 뒤에 있는 데이터를 삭제하고 리턴
Object removeLast()
Object remove(int) 매개 변수에 지정된 위치에 있는 데이터를 삭제하고 리턴
boolean remove(Object) 매개 변수로 넘겨진 객체와 동일한 데이터 중 앞에서부터 가장 처음 발견된 데이터 삭제
boolean removeFirstOccurrence(Object)
boolean removeLastOccurrence(Object) 매개 변수로 넘겨진 객체와 동일한 데이터 중 끝에서부터 가장 처음 발견된 데이터 삭제

· 맨 앞에 있는 데이터를 삭제하는 메소드들은 removeFirst(), 맨 뒤에 있는 데이터를 삭제하는 메소드들은 removeLast() 메소드를 내부적으로 호출한다. 혼동을 피하려면 remove가 붙은 메소드를 사용할 것을 권장한다.

 

LinkedList에 선언된 메소드 - iterator 객체를 반환 (LinkedList 객체를 하나씩 검색하기 위한)

리턴 타입 메소드 이름 및 매개 변수 설명
ListIterator listIterator(int) 매개 변수에 지정된 위치부터 데이터를 검색하기 위한 ListIterator 객체 리턴
Iterator descendingIterator() LinkedList의 데이터를 끝에서부터 검색하기 위한 Iterator 객체를 리턴

· ListIterator는 Iterator 인터페이스가 다음 데이터만 검색할 수 있다는 단점을 보완하여, 이전 데이터도 검색할 수 있다.

 

 Map

· 키(key)와 값(value)을 하나의 쌍으로 묶어서 저장하는 자료구조

· 키는 중복되지 않고, 해당 맵에서 고유함

· 값 없이 키만 저장 가능

· Map에 저장된 모든 value객체를 반환하는 values()는 반환타입이 Collection (값은 중복을 허용하므로)

· Map에 저장된 모든 key객체를 반환하는 keySet()는 반환타입이 Set (키는 중복을 허용하지 않으므로)

· 구현체: HahMap, TreeMap, LinkedHashMap, Hashtable, Properties

 

Map 인터페이스에 선언된 메소드

리턴 타입 메소드 이름 및 매개 변수 설명
V put(K key, V value) 첫 번째 매개 변수로 키를, 두 번째 매개 변수로 값을 갖는 데이터 저장
void putAll(Map<? extends K, ? extends V> m) 매개 변수로 넘어온 Map의 모든 데이터를 저장
V get(Object key) 매개 변수로 넘어온 키에 해당하는 값을 반환
V remove(Object key) 매개 변수로 넘어온 키에 해당하는 값을 반환하고, 해당 키와 값은 Map에서 삭제
Set<K> keySet() 키의 목록을 Set 타입으로 리턴
Collection<V> values() 값의 목록을 Collection 타입으로 리턴
Set<Map.entry<K,V>> entrySet() Map 안에 Entry라는 타입의 Set을 리턴
int  size() Map의 크기를 리턴
void clear() Map의 모든 내용 삭제

· 존재하지 않는 키로 get()을 할 경우 null을 리턴

 

Hashtable

· JDK 1.0부터 만들어져 사용된 클래스로 JDK 1.2에 추가된 Map 인터페이스에 맞추어 보완됨

· 따라서, Map 인터페이스를 구현했지만 일반적인 Map 인터페이스를 구현한 클래스들과 다름

     - Enumeration 객체를 통해서 데이터 처리. Map은 컬렉션 뷰를 사용.

     - 키-값 쌍으로 데이터 순환 처리 불가능(키, 값은 가능). Map은 키, 값, 키-값 쌍으로 데이터 순환처리 가능. 

     - 이터레이션을 처리하는 도중에 데이터를 삭제하는 안전한 방법 제공 x. Map은 제공.

· HashMap과 Hashtable 클래스의 차이

기능 HashMap Hashtable
키나 값에 null 저장 가능 여부 가능 불가능
멀티 쓰레드 안전 여부 불가능 가능

 

HashMap

·  HashMap 상속 구조

https://www.javatpoint.com/java-hashmap

HashMap 클래스가 구현한 인터페이스

인터페이스 용도
Serializable 원격으로 객체를 전송하거나, 파일에 저장할 수 있음을 지정
Cloneable · Object 클래스의 clone() 메소드가 제대로 제대로 수행될 수 있음을 지정
· 즉, 복제 가능한 객체임을 의미
Map<E> 맵의 기본 메소드 지정

HashMap의 생성자

생성자 설명
HashMap() 16개의 저장 공간을 갖는 HashMap 객체 생성
HashMap(int initialCapacity) 매개 변수만큼의 저장 공간을 갖는 HashMap 객체 생성
HashMap(Int initialCapacity, float loadFactor) 저장 공간(initialCapacity)과 로드팩터(loadFactor)를 지정한 HashMap 객체 생성
HashMap(Map<? extends K, ? extends V> m) 매개 변수로 넘어온 Map을 구현한 객체의 데이터를 갖는 HashMap 객체 생성

· 담을 데이터의 개수가 많은 경우 초기 크기 지정을 권장

· HashMap의 키는 기본 자료형, 참조 자료형 모두 가능

· 주의사항: 직접 어떤 클래스를 만들어 그 클래스를 키로 사용할 경우 Object 클래스의 hashCode(), equals() 메소드를 잘 구현해야함

     - HashMap에 객체가 들어가면 hashCode() 메소드의 결과 값에 따른 버켓이라는 목록 형태의 바구니가 생성

     - 서로 다른 키가 저장되었을 때 hashCode 메소드의 결과가 동일하다면, 이 버켓에 여러 개의 값이 들어갈 수 있음

     - get() 메소드가 호출되면 hashCode()의 결과를 확인하고, 버켓에 들어간 목록에 데이터가 여러 개일 경우 equals() 메소드를 호출하여 동일한 값을 찾음

     - 따라서 키가 되는 객체를 직접 작성할 경우 개발툴에서 제공하는 hashcode(), equals() 자동 생성 기능을 사용할 것

     - 세부사항:https://d2.naver.com/helloworld/831311

 

HashMap 객체의 값을 확인하는 방법

· HashMap의 어떤 키가 있는지 확인하려면, 리턴타입이 Set인 keySet 메소드를 사용한다. 이때, Set의 제네릭 타입의 키의 제네릭 타입과 동일하게 지정한다.

        HashMap<String, String> map = new HashMap<>();
        map.put("A","a");
        map.put("B","b");
        Set<String> keySet = map.keySet();
        for (String key: keySet){
            System.out.println(key);
        }

· HashMap 객체에 담겨있는 값만 필요할 경우, 리턴타입이 Collection인 values() 메소드를 사용한다.

        HashMap<String, String> map = new HashMap<>();
        map.put("A","a");
        map.put("B","b");
        Collection<String> values = map.values();
        for (String value: values){
            System.out.println(value);
        }

· 키와 값이 모두 필요할 때 entrySet() 메소드로 Map에 선언된 Entry 타입 객체를 리턴할 수 있다. Entry는 단 하나의 키와 값만이 저장된다.

        HashMap<String, String> map = new HashMap<>();
        map.put("A","a");
        map.put("B","b");
        Set<Map.Entry<String,String>> entries = map.entrySet();
        for (Map.Entry<String,String> entry : entries)
            System.out.println(entry.getKey() + entry.getValue());

 

TreeMap

· SortedMap이라는 인터페이스를 구현하여 저장되는 키를 정렬함

· 문자열 기준으로 정렬되는 기본 순서는 "숫자 > 알파벳 대문자 > 알파벳 소문자 > 한글"

        Map<String, String> map = new TreeMap<>();
        map.put("A","a");
        map.put("a","b");
        map.put("가","c");
        map.put("1","d");
        Set<Map.Entry<String,String>> entries = map.entrySet();
        for (Map.Entry<String,String> entry : entries)
            System.out.println(entry.getKey() + entry.getValue());

실행 결과

· 키가 정렬되기 때문에 매우 많은 데이터를 TreeMap을 이용하여 처리하면 HashMap보다 느리다.

 

Properties

· Hashtable을 확장한 클래스

· 자바에서 시스템 속성을 제공할 때 사용

 

예시 - 시스템 속성 출력

    Properties prop = System.getProperties();
    Set<Object> keySet = prop.keySet();
    for (Object obj:keySet)
        System.out.println(obj+"="+prop.get(obj));

결과

 

Properties 클래스에 선언된 메소드

· Properties 클래스는 시스템 속성을 다루기 위한 다양한 메소드 제공

리턴 타입 메소드 이름 및 매개 변수 설명
void load(InputStream inStream) 파일에서 속성을 읽음
void load(Reader reader)
void loadFromXML(InputStream in) XML로 되어 있는 속성을 읽음
void store(OutputStream out, String comments) 파일에 속성을 저장
void store(Writer writer, String comments)
void storeToXML(OutputStream os, String comment) XML로 구성되는 속성 파일을 생성
void storeToXML(OutputStream os, String comment, String encoding)

 

 

Iterator, ListIterator, Enumeration

Iterator, ListIterator, Enumeration은 모두 컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스이다. Enumeration은 Iteration의 구버젼이며, ListIterator는 Iterator의 기능을 향상시킨 것이다.

 

Iterator

 컬렉션 프레임워크에서는 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화하였다. 컬렉션에 저장된 각 요소에 접근하는 기능을 가진 Iterator인터페이스를 정의하고, Collection 인터페이스에는 'Iterator(Iterator를 구현한 클래스의 인스턴스)'를 반환하는 iterator()를 정의하고 있다.

 

 Iterator()는 Collection인터페이스에 정의된 메서드이므로 Collection인터페이스의 자손인 List와 Set에도 포함되어 있다. 그래서 List나 Set인터페이스를 구현하는 컬렉션은 iterator()가 컬렉션의 특징에 알맞게 작성되어 있다. 

 

메서드 설명
boolean hasNext() 읽어 올 요소가 남아있는지 확인한다. 있으면 true, 없으면 false를 반환한다.
Object next() 다음 요소를 읽어 온다. next()를 호출하기 전에 hasNext()를 호출해서 읽어 올 요소가 있는지 확인하는 것이 안전하다.
void remove() next()로 읽어 온 요소를 삭제한다. next(0를 호출한 다음에 remove()를 호출해야한다.

Iterator 인터페이스를 실제로 ArrayList에서 구현한 코드를 통해 Iterator가 어떻게 컬렉션의 각 요소에 접근하는 지 확인할 수 있다.

ArrayList대신 List인터페이스를 구현한 다른 컬렉션 클래스에 대해서도 동일한 메서드를 사용할 수 있다. Iterator를 이용해서 컬렉션의 요소를 읽어오는 방법을 표준화했기 때문에 이처럼 코드의 재사용성을 높이는 것이 가능하다.

 

Map 인터페이스를 구현한 컬렉션 클래스는 키와 값을 쌍으로 저장하고 있기 때문에 iterator()를 직접 호출할 수 없고, 그 대신 keySet()이나 entrySet()과 같은 메서드를 통해서 키와 값을 각각 따로 Set의 형태로 얻어 온 후에 다시 iterator()를 호출해야 Iterator를 얻을 수 있다.

 

ListIterator와 Enumeration

Enumeration은 컬렉션 프레임워크가 만들어지기 이전에 사용하던 것으로 Iterator의 구버전으로 생각하면 된다. 각 인터페이스에 메서드이름만 다를 뿐 기능을 같다. 이전 버전으로 작성된 소스와의 호환을 위해서 남겨 두고 있을 뿐이므로 가능하면 Enumeration대신 Iterator를 사용하자.

 

ListIterator는 Iterator를 상속받아서 기능을 추가한 것으로, 컬렉션의 요소에 접근할때  Iterator는 단방향으로만 이동할 수 있는 데 반해 ListIterator는 양방향으로의 이동이 가능하다. 다만 ArrayList나 LinkedList와 같이 List인터페이스를 구현한 컬렉션에서만 사용할 수 있다.

 

Comparator와 Comparable

 Comparator와 Comparable은 모두 인터페이스로 컬렉션을 정렬하는데 필요한 메서드를 정의하고 있다. Comparable을 구현하는 클래스들은 같은 타입의 인스턴스끼리 서로 비교할 수 있는 클래스들, 주로 Integer와 같은 Wrapper클래스와 String, Date, File과 같은 것들이며 기본적으로 오름차순으로 정렬되도록 구현되어 있다. 실제 소스는 다음과 같다.

 

public interface Comparator{
	int compare(Object o1, Object o2);
	boolean equals(Object obj);
}

public interface Comparable{
	public int compareTo(Object o);
}

 compare()와 compareTo()는 선언형태와 이름이 다를 뿐 두 객체를 비교한다는 같은 기능을 목적으로 고안된 것이다. compareTo()의 반환값은 int이지만 실제로는 비교하는 두 객체가 같으면 0, 비교하는 값보다 작으면 음수, 크면 양수를 반환하도록 구현해야 한다. 이와 마찬가지로  compare()도 객체를 비교해서 음수, 0, 양수 중의 하나를 반환하도록 구현해야한다.

 

 Comparable을 구현한 클래스들이 기본적으로 오름차순으로 정렬되어 있지만, 내림차순으로 정렬한다던가 아니면 다른 기준에 의해서 정렬되도록 하고 싶을 때 Comparator를 구현해야 정렬 기준을 제공할 수 있다.

 

#Arrays.sort() 메소드를 통해보는 Comprable, Comparator 예시

sort() 메소드는 기본적으로 Comparable 구현에 의해 오름 차순으로 정렬된다. Comparator를 지정하면 다른 방식으로 정렬할 수 있다.

 

 

 

컬렉션 클래스

ArrayList

p584 ArrayList의 정의와 원리

P588 저장 꿀팁

P588 벡터의 원리

https://smujihoon.tistory.com/158

p599 arraylist,vector의 장단점 

 

LinkedList

P596 배열과 링크드리스트 장단점 비교

p597 링크드리스트, 더블 링크드 리스트(자바링크드리스트 실제구현), 더블 써뮬러 링크드리스트

P600 링크드리스트와 ARRAYlIST 성능차이 비교

Stack과 Queue

 스택은 마지막에 저장한 데이터를 가장 먼저 꺼내게 되는 LIFO(Last in First Out)구조로 되어 있다. 동적통과 같은 구조로 양 옆과 바닥이 막혀 있어서 한 방향으로 뺄 수 있는 구조다.

 

 큐는 처음에 저장한 데이터를 가장 먼저 꺼내게 되는 FIFO(First In First Out)구조로 되어있다. 파이프와 같은 구조롤 양 옆만 막혀 있고 위아래로 뚤려 있어서 한 방향으로는 넣고 한 방향으로는 뺄 수 있는 구조다.

 

 

Arrays

sort() 메서드 -> comparable 구현한거임 

 

 

출처

자바의 정석

자바의 신

http://tcpschool.com/java/java_collectionFramework_conceptObject

반응형

댓글