반응형
들어가기 전에
본 글은 제가 참여하고 있는 자바 기초 스터디에서 제가 발표한 내용으로 위의 책 Chapter 12 컬렉션 프레임워크 파트를 정리한 글입니다.
틀린 내용이나 오타가 있다면 댓글로 알려주시면 감사하겠습니다.
컬렉션 프레임워크란?
- 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미
- 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 클래스로 구현해 놓은 것으로 java.util 패키지에 구현되어 있음
- 컬렉션 프레임워크는 자바의 인터페이스(interface)를 사용하여 구현
- Collection, Map은 구현 코드 없는 인터페이스
- 위의 그림은 대표적인 것만 표현
Collection 인터페이스
- 하나의 객체를 관리하기 위한 메서드가 정의된 인터페이스
- 하위에 List와 Set 인터페이스가 있음
- 여러 클래스들이 Collection 인터페이스를 구현함
List 인터페이스
- 순서가 있는 자료 관리, 중복 허용
- ArrayList, Vector, LinkedList, Stack, Queue 등
메서드 | 설명 |
boolean add(E e) | 객체 추가 |
void clear() | 모든 객체 제거 |
Iterator<E> iterator | 순환할 반복자(Iterator) 반환 |
boolean remove(Object o) | 매개변수에 해당하는 인스턴스가 존재하면 제거 |
int size() | 요소 개수 반환 |
boolean isEmpty() | 컬렉션이 비어있는지 여부 반환 |
ArrayList와 Vector
- 객체 배열을 구현한 클래스
- 멀티 쓰레드 상태에서 리소스에 대한 동기화가 필요한 경우 Vector를 사용
- 일반적으로 ArrayList를 더 많이 사용
- ArrList에 동기화 기능이 추가되어야 하는 경우
List<타입> 변수 = Collections.synchronizedList(new ArrayList<String>());
- 동기화(synchronization)
- 두 개의 스레드가 동시에 하나의 리소스에 접근할 때 순서를 맞추어서 데이터에 오류가 발생하지 않도록 함
ArrayList
ArrayList<타입> arrayList = new ArrayList<>();
arrayList.add(value); // 요소 추가
/*
* 특정 위치에 요소를 추가 할 경우 해당 위치에 추가된 값이 들어가고
* 해당 위치 이후(해당 위치 포함)에 존재하던 기존 값들은 인덱스가 1씩 밀림
*/
arrayList.add(i, value); // i번째 인덱스에 해당 값 추가
arrayList.remove(i); // i번째 요소 삭제
arrayList.remove(value); // 해당 밸류값 삭제
arrayList.get(i); // i번째 요소 접근
System.out.println(linkedList); // [1, 2, 3, 4, 5]
for (타입 변수 : arrayList) {
System.out.println(변수); // arrayList 요소 전체 출력
}
/*
* 1
* 2
* 3
* 4
* 5
*/
// 밸류 존재 확인
arrayList.contains(value); // value 존재여부에 따라 true / false 반환
arrayList.indexOf(value); // value 존재여부에 따라 index / -1 반환
/*
* 배열 크기를 지정하지 않으면 크기가 10인 배열이 기본으로 생성
* 이를 배열의 용량(capacity)라고 부르며, size() 메서드를 사용했을때 나오는 값과는 다른 의미
* ArrayList(int) 생성자를 이용해 초기 생성할 배열의 용량 지정 가능
*
* ArrayList의 경우 설정된 용량보다 더 많은 값의 요소를 추가 할 경우
* 큰 용량의 배열을 새로 만들고 기존 항목을 복사
*/
LinkedList
- 배열의 단점을 개선한 자료구조
- 논리적으로 순차적인 자료구조가 구현된 클래스
- 다음 요소에 대한 참조값을 가지고 있음
- 요소의 추가 / 삭제에 드는 시간이 ArrayList에 비해 적음
- 크기를 동적으로 증가시킬 수 있음
- 추가하기
- 삭제하기
- 이때 제거된 요소의 메모리는 가비지 컬렉터에 의해 수거
LinkedList<타입> linkedList = new LinkedList<>();
linkedList.add(value); // 요소 추가
linkedList.add(i, value); // i번째 인덱스에 해당 값 추가
linkedList.remove(i); // i번째 요소 삭제
linkedList.remove(value); // 해당 밸류값 삭제
linkedList.get(i); // i번째 요소 접근
System.out.println(linkedList);
for (타입 변수 : linkedList) {
System.out.println(변수);
}
// 밸류 존재 확인
arrayList.contains(value); // value 존재여부에 따라 true / false 반환
arrayList.indexOf(value); // value 존재여부에 따라 index / -1 반환
배열과 링크드 리스트
- 배열
- 생성할 때 크기를 지정하고 이보다 더 많은 요소가 추가된 경우 용량을 늘려가며 수행
- 물리적으로 연결된 자료구조이므로 특정 위치의 요소를 찾을 때 메모리 위치를 바로 계산할 수 있어 접근이 빠름
- 링크드 리스트
- 요소를 추가할 때마다 동적으로 요소의 메모리를 생성
- 삽입과 삭제가 많은 경우 링크드 리스트 사용
이미 만들어진 구조에서 데이터의 접근이 많은 경우 배열 사용
Iterator
- Collection의 객체를 순회하는 인터페이스
Iterator<타입> iterator = arrayList.iterator();
// 읽어올 요소가 남아있는지 확인하는 메소드
while (iterator.hasNext()) {
iterator.next(); // 다음 데이터 반환
iterator.remove(); // next()로 읽어온 요소 삭제
}
Set 인터페이스
- 중복 불허용
- 순서가 없음
- 순서가 없기 때문에 저장된 순서와 출력 순서는 다를 수 있음
- get(i) 메서드가 제공되지 않음
- 유일한 값이나 객체를 관리할 때 사용
ex) 아이디, 주민번호 등
메서드 | 설명 |
boolean add(E e) | 객체 추가 정상적으로 추가 될경우 true를 중복 객체일 경우 false 반환 |
boolean contains(Object o) | 객체 존재여부 리턴 |
void clear() | 모든 객체 제거 |
Iterator<E> iterator | 순환할 반복자(Iterator) 반환 |
boolean remove(Object o) | 매개변수에 해당하는 인스턴스가 존재하면 제거 |
int size() | 요소 개수 반환 |
boolean isEmpty() | 컬렉션이 비어있는지 여부 반환 |
HashSet
HashSet<타입> hashSet = new HashSet<>();
hashset.add(value); // 요소 추가 true / false 반환
/*
* 정상적으로 추가 될 경우 true
* 이미 존재하는 값을 추가 할 경우 false
*/
// 순서가 없기 때문에 index로는 삭제가 불가능하며 객체로 삭제
hashset.remove(value); // true / false 반환
// 밸류 존재 여부 확인
// 순서가 없기 때문에 indexOf는 불가
hashset.contains(value); // true / false 반환
TreeSet
- 객체의 정렬에 사용되는 클래스
- 중복을 허용하지 않으면서 오름차순이나 내림차순으로 객체를 정렬
- 내부적으로 이진 검색 트리(binary search tree)로 구현되어 있음
- 이진 검색 트리에 자료가 저장될 때 비교하여 저장될 위치를 정함
- 객체 비교를 위해 Comparable이나 Comparator 인터페이스를 구현 필요
TreeSet<타입> treeSet = new TreeSet<>();
// TreeSet<String>로 가정
// String클래스를 확인해 보면 Comparable이 구현되어 있음
treeSet.add("a");
treeSet.add("d");
treeSet.add("e");
treeSet.add("b");
treeSet.add("c");
System.out.println(treeSet); // [a, b, c, d, e]
/** Comparable 예시 **/
public class Member {
private int id;
private String name;
}
// Comparable이 정의되지 않은 타입 출력
TreeSet<Member> memberTreeSet = new TreeSet<>();
memberTreeSet.add(new Member(1, "코블린"));
memberTreeSet.add(new Member(3, "코블린3"));
memberTreeSet.add(new Member(2, "코블린2"));
// Exception in thread "main" java.lang.ClassCastException: collection.Member cannot be cast to java.lang.Comparable
System.out.println(memberTreeSet);
// Member class (get, set메서드 등 생략)
public class Member implements Comparable<Member>{
private int id;
private String name;
@Override
public int compareTo(Member member) {
// 내(this)가 큰 경우(양수를 반환하면) 오름차순 반환
// 내(this)가 작은 경우(음수를 반환하면) 내림차순 반환
return (this.id - member.id);
// return (this.id - member.id) * (-1);
// String 타입 정렬시 compare가 이미 구현이 되어 있기 때문에 구현되어 있는 메서드 사용
// return (this.name.compareTo(member.name));
}
}
TreeSet<Member> memberTreeSet = new TreeSet<>();
memberTreeSet.add(new Member(1, "코블린"));
memberTreeSet.add(new Member(3, "코블린3"));
memberTreeSet.add(new Member(2, "코블린2"));
System.out.println(memberTreeSet);
// [Member [id=1, name=코블린], Member [id=2, name=코블린2], Member [id=3, name=코블린3]]
/** Comparable 예시 **/
public class Member implements Comparator<Member>{
private int id;
private String name;
@Override
public int compare(Member member1, Member member2) {
// member1 : 나
// member2 : 비교할 대상
return (member1.id - member2.id);
}
}
// new Member()가 필수
TreeSet<Member> memberTreeSet = new TreeSet<>(new Member());
memberTreeSet.add(new Member(1, "코블린"));
memberTreeSet.add(new Member(3, "코블린3"));
memberTreeSet.add(new Member(2, "코블린2"));
System.out.println(memberTreeSet);
// [Member [id=1, name=코블린], Member [id=2, name=코블린2], Member [id=3, name=코블린3]]
Comparable과 Comparator
- 정렬 대상이 되는 클래스가 구현해야 하는 인터페이스
- Comparable은 compareTo() 메서드를 구현
매개 변수와 객체 자신(this)을 비교 - Comparator는 compare() 메서드를 구현
두 개의 매개 변수를 비교
TreeSet 생성자에 Comparator가 구현된 객체를 매개변수로 전달TreeSet<Member> memberTreeSet = new TreeSet<>(new Member());
- 일반적으로 Comparable을 더 많이 사용
- Comparable이 구현된 경우에 Comparator를 이용해 다른 정렬 방식 정의
- ex) String 클래스를 내림차순으로 정렬할 경우
- String클래스는 Comparable이 이미 구현되어 있으며 오름차순 정렬로 되어 있음
String클래스는 final로 선언 되어 있어 compareTo() 메서드를 재정의 할 수 없음
이런 경우 Comparator를 사용
- String클래스는 Comparable이 이미 구현되어 있으며 오름차순 정렬로 되어 있음
- ex) String 클래스를 내림차순으로 정렬할 경우
Map 인터페이스
- key-value pair의 객체를 관리하는데 필요한 자료구조
- key는 중복될 수 없음
- value는 중복 가능
- 검색을 위한 자료 구조
- key를 이용하여 값을 저장하거나 검색, 삭제할 때 사용하면 편리함
- 내부적으로 hash 방식으로 구현됨
index = hash(key) // index는 저장 위치
- key가 되는 객체는 객체의 유일성 여부를 알기 위해 equals()와 hashCode() 메서드를 재정의
- 파이썬의 딕셔너리와 유사
메서드 | 설명 |
V put(K key, V value) | 주어진 키와 값을 추가 해당 키가 존재하지 않을경우(첫 추가) null 반환 이미 존재하는 키에 값을 추가할 경우 기존 값을 반환 |
boolean containsKey(Object Key) | 키 존재여부 반환 |
boolean containsValue(Object value) | 값 존재여부 반환 |
Set<Map.Entry<K,V>> entrySet() | 모든 Map.Entry 객체를 Set에 담아 반환 |
Set keySet() | 모든 키를 Set에 담아 반환 |
Collection values() | 모든 값을 Collection 형태로 반환 |
V get(Object key) | 주어진 키에 해당하는 값 반환 |
void clear() | 모든 객체 제거 |
Iterator iterator | 순환할 반복자(Iterator) 반환 |
V remove(Object Key) | 주어진 키와 일치하는 Map.Entry를 삭제하고 값 리턴 |
int size() | 객체 개수 반환 |
boolean isEmpty() | 컬렉션이 비어있는지 여부 반환 |
HashMap
- Map 인터페이스를 구현한 클래스 중 가장 일반적으로 사용하는 클래스
- HashTable 클래스는 Vector처럼 동기화를 제공
- 여러 메서드를 활용하여 pair 자료를 쉽고 빠르게 관리할 수 있음
HashMap<Key, Value> hashMap = new HashMap<>();
hashMap.put(key, value); // 요소 추가
hashMap.remove(key); // 요소 삭제
hashMap.get(key); // 해당 key로 value 가져오기
hashMap.keySet(); // 갖고 있는 key 전체를 array로 반환
hashMap.entrySet(); // key=value 형태의 array로 반환
Iterator<Key타입> iterator = hashMap.keySet().iterator();
while (iterator.hasNext()) { // 전체 출력
Key타입 key = iterator.next();
System.out.println("key : " + key + " value : " + hashMap.get(key));
}
TreeMap
- key 객체를 정렬하여 key-value를 pair로 관리하는 클래스
- key에 사용되는 클래스에 Comparable, Comparator인터페이스를 구현
- java에 많은 클래스 들은 이미 Comparable이 구현되어 있음
- 구현된 클래스를 key로 사용하는 경우는 구현할 필요 없음
TreeMap<Key, Value> treeMap = new TreeMap<>();
// HashMap과 동일한 메서드 사용
// TreeSet과 동일하게 Comparable, Comparator인터페이스를 구현
반응형
'프로그래밍 언어&프레임워크 > java' 카테고리의 다른 글
[Java/자바] 제네릭 프로그래밍 (0) | 2021.09.13 |
---|---|
[Java/자바] 배열과 ArrayList (0) | 2021.08.23 |
[Java/자바] MVC 패턴(Model, View, Controller) (0) | 2021.08.07 |
[Java/자바] 래퍼 클래스(Wrapper Class) (0) | 2021.08.06 |
[Java/자바] 자료형(DataType) (0) | 2021.08.04 |