컬렉션(Collection) 프레임워크란?
다수의 객체를 저장하고 효율적으로 추가, 삭제, 검색할 수 있도록 구현된 인터페이스와 클래스들을 말한다.
주요 인터페이스로 List, Set, Map이 있다.
배열도 다수의 객체를 저장할 수 있다. 하지만, 저장할 수 있는 크기가 고정적이며, 중간 인덱스의 자료를 삭제했을 때 빈 곳이 생기기도 한다. 이로 인해 고정적 크기의 연속된 객체를 저장하는 것은 좋지만, 유동적인 크기를 갖는 객체 저장에는 적합하지 않을 수 있다.
컬렉션이란? 사전적 의미로 요소를 수집해서 저장하는 것을 말한다.

List (순서)
set(종복X)
Map(key, value / 키, 값)

List 컬렉션
리스트(List)란 저장된 요소들의 순서가 있고 데이터에 중복이 가능하고 인덱스(index) 번호에 의해서 정렬됩니다. (배열과 비슷한 동작을 합니다.)
리스트(List)의 특징
- 리스트(List)는 컬렉션(Collection) 인터페이스 중 하나이다.
- 리스트(List)는 두 개의 종류로 나눠진다.
- ArrayList -> 배열로 이루어진 리스트(List)
- LinkedList
- 리스트(List)는 크기 조절이 가능하다.
- 리스트(List)는 초기 크기를 지정하지 않아도 된다.
- 리스트(List)에 삭제는 공간을 지우는 것이다.


ArrayList
(vector에서 개선된게ArrayList )
ArrayList는 요소를 순차적으로 추가하는 게 특징입니다. 배열과 매우 유사하며 배열은 배열 선언 시 크기도 같이 지정해 줘야 하는 반면 ArrayList는 크기를 지정하지 않아도 되며 추가될 때마다 크기가 정해집니다.
List<String> list = new ArrayList<>();
List<String> list = new ArrayList<String>(); // ArrayList 생성시 초기값 10
List<String> list = new ArrayList<String>(30);
// String 객체 30개를 저장할 수 있는 용량을 가짐
List list = new ArrayList<>();
ArrayList를 생성하고 런타임 시 필요에 의해 객체들은 추가 하는 것이 일반적이지만,
고정된 객체들로 구성된 List를 생성할 때도 있다.
이런 경우에는 Arrays.asList(T..a); 메소드를 사용하는것이 간편하다
List<T> list = new Arrays.asList(T....a);
T 타입 파라미터에 맞게 asList()의 매개값을 순차적으로 입력하거나, T[]배열을 매개값으로 주면 된다.
Vector
(vector에서 개선된게ArrayList )
Vector는 ArrayList와 동일한 내부 구조를 가지고 있다.
List<E> list = new Vector<E>();
vector
0 ... n- 1
|
← O 스레드1
← X 스레드2 |
|
LinkedList
ArrayList와 사용방법은 똑같지만 내부 구조는 완전히 다릅니다.
ArrayList는 내부 배열을 객체에 저장해서 인덱스로 관리하지만,
LinkedList는 인접 참조를 링크해서 체인처럼 관리합니다.
ArrayList는 중간 인덱스의 객체를 제거하면 뒤의 객체는 인덱스가 1씩 앞으로 당겨진다.
그렇게 때문에 빈번한 객체 삭제와 삽인이 일어나는 곳에서는 LinkedList가 좋은 성능을 발휘한다.
List<E> list = new LinkList<E>();
구분
|
순차적으로 추가/삭제
|
중간에 추가/ 삭제
|
검색
|
ArrayList
|
빠르다
|
느리다
|
빠르다
|
LinkedList
|
느리다
|
빠르다
|
느리다
|
Set 컬렉션
List 컬렉션은 저장 순서를 유지하지만, Set 컬렉션은 저장 순서가 유지되지 않는다. 또한 객체를 중 복해서 저장할 수 없고, 하나의 nul1만 저장할 수 있다.
Set 컬렉션은 수학의 집합에 비유될 수 있다.
집합은 순서와 상관없고 중복이 허용되지 않기 때문이다. 들어갈(저장할) 때의 순서와 나올 (찾을) 때의 순서가 다를 수도 있다.


Set<String> set = ...;
set.add("홍길동"); // 객체추가
set.add("신용권");
set.remove("홍길동"); //객체삭제
Set<String> set = ...;
Iterator <String>iterator = set.iterator();


HashSet
HashSet은 Set 인터페이스에서 지원하는 구현 클래스이다.
Set<E> set = new hashSet<E>();
타입 파라미터 E에 String객체 저장
Set<String> set = new hashSet<String>();
HashSet은 객체들을 순서 없이 저장하고 동일한 객체는 중복 저장하지 않는다.
HashSet은 객체를 저장하기 전에 객체의 hashCode()메소드를 호출해서 해시코드를 얻어내고,
그리고 이미 저장된 객체의 해시코드와 비교한다.
만약 동일한 해시코드가 나온다면 equals() 메소드로 두 객체를 비교해서
true가 나온다면 동일한 객체로 판단하고 중복 저장을 하지 않는다.

HashSet
문자열을 HashSet에 저장하는 경우,
같은 문자열을 갖는 String 객체는 동등한 객체로 간주되고
다른 문자열을 갖는 String 객체는 다른 객체로 간주되는데,
그 이유는 String 클래스가 hashCode()와 equals()메소드를 재정의해서
같은 문자열의 경우 hashCode()의 리턴값을 같게,
equals()의 리턴값을 참으로 나오게 하기 때문이다.
String 객체를 중복 없이 저장하는HashSet
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
// String 객체를 중복 없이 저장하는HashSet
public class HashSetMain {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("JAVA"); // ........
set.add("자바"); // JAVA는 한번만 저장됨
set.add("JAVA"); // .......
set.add("SQL");
set.add("ABCD");
int size = set.size(); // 저장된 객체 수 얻기
System.out.println("총 객체수 : " + size);
Iterator<String> iterator = set.iterator(); // 반복자얻기
while(iterator.hasNext()) { // 객체 수만큼 루핑
String str = iterator.next(); // 한개의 객체를 가져온다
System.out.println(str);
}
set.remove("ABCD"); // 한 개의 객체 삭제
System.out.println("제거 후 총 객체수 : " + size); // 저장된 객체 수 얻기
iterator = set.iterator(); // 반복자 얻기
while(iterator.hasNext()) { // 객체 수만큼 루핑
String element = iterator.next();
System.out.println("\t" +element);
}
set.clear(); // 모든 객체를 제거하고 비움
if(set.isEmpty()) {
System.out.println("비었습니다.");
}
}
}
내용을 입력하세요.
import java.lang.reflect.Member;
import java.util.HashSet;
import java.util.Set;
// Member 객체를 중복없이 저장하는 HashSet
public class HashSetEx01 {
public static void main(String[] args) {
Set<Member> set = new HashSet<Member>();
set.add(new Member("홍길동",30)); // 인스턴스는 다르지만
set.add(new Member("홍길동",30)); //동일하므로 객체 1개만 저장
System.out.println("총 객체수 : " + set.size());
// 총 객체수 : 1
}
}
Map
Map 컬렉션은 키(key)와 값(value)으로 구성된 Entry 객체를 저장하는 구조를 가지고 있습니다.
여기서 키와 값은 모두 객체입니다. 키는 중복될 수 없지만 값은 중복 저장될 수 있습니다.
만약 기존에 저장된 키와 동일한 키로 값을 저장하면 기존의 값은 없어지고 새로운 값으로 대치됩니다.

Map 컬렉션에는 HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등이 있습니다.

위 표에서 메소드의 매개 변수 타입과 리턴 타입에 K와 V라는 타입 파라미터가 있는데, 이것은 Map 인터페이스가 제네릭 타입이기 때문입니다.
앞에서도 언급했듯이 구체적인 타입은 구현 객체를 생성할 때 결정됩니다.
객체 추가는 put() 메소드를 사용하고, 키로 객체를 찾아올 때에는 get() 메소드를 사용합니다.
그리고 객체 삭제는 remove()메소드를 사용한다.
Map<String, Integer> map = ~;
map.put("홍길동", 30); // 객체 추가
int score = map.get("홍길동"); // 객체 찾기
map.remove("홍길동"); // 객체 삭제
HashMap
HashMap은 Map 인터페이스를 구현한 대표적인 Map 컬렉션입니다.
HashMap의 키로 사용할 객체는 hashCode()와 equals() 메소드를 재정의해서 동등 객체가 될 조건을 정해야 합니다. 동등 객체, 즉 동일한 키가 될 조건은 hashCode()의 리턴값이 같아야 하고, equals() 메소드가 true를 리턴해야 합니다.


주로 키 타입은 String을 많이 사용하는데, String은 문자열이 같을 경우 동등 객체가 될 수 있도록 hashCode()와 equals() 메소드가 재정의되어 있습니다. HashMap을 생성하기 위해서는 키 타입과 값 타입을 파라미터로 주고 기본 생성자를 호출하면 됩니다.
Map<K, V> map = new HashMap<K, V>(); // k 키 타입 , v 값 타입
다시 정리 ↓
Map<String, Integer> map = new HashMap<>(); // Map 컬렉션 생성
map.put("신용권",85);
map.put("홍길동",90);
map.put("동장군",80);
map.put("홍길동",95); // 동일한 key 때문에 덮어써짐(마지막에 저장한 값)
System.out.println("총 Entry 수 : "+map.size()); // 저장된 총 Entry 수 얻기
// 객체 찾기
System.out.println("\t홍길동" : "+map.get("홍길동")); // 이름(키)으로 점수(값)를 검색
//객체를 하나씩 처리
Set<String> keySet = map.keySet(); // key set 얻기
Iterator<String> keyIterator = keySet.iterator();
while (keyIterator.hasNext()){
String k = keyIterator.next();
Integer v = map.get(key); // 반복해서 키를 얻고
System.out.println(k+" : "+v); // 값을 Map에서 얻어냄
}
// 객체 삭제
map.remove("홍길동"); // 키로 Map.Entry를 제거
System.out.println("총 Entry 수 : "+map.size());
System.out.println();
Hashtable
Hashtable은 HashMap과 동일한 내부구조를 갖고 있다.
동기화된 (synchronized) 메소드를 갖고 있어서, 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있다.이것을 스레드가 안전(thread safe)하다라고 말한다.
HashtableMap
키
|
...
|
키
|
← O 스레드1
← X 스레드2 |
|
값
|
...
|
값
|
Hashtable 생성 방법은 Hashmap 똑같다
Map <K, V> map = new Hashtable<K, V> ();
k=키 타입 v = 값 타입
Map <String, Intrger> map = new Hashtable<String, Intrger> ();
Properties
HashTable의 하위 클래스이다.
키와 값을 String이라는 타입으로만 제한한 클래스이다.
보통 애플리케이션의 옵션 정보, 데이터베이스 연결 정보, 다국어 정보 등이 저장된 프로퍼티 파일(.properties)을 읽을 때 주로 사용한다.
프로퍼티 파일(.properties)은 키와 값이 =기호로 연결된 텍스트 파일로 ISO-8859-1 문자셋으로 저장된다. 이 문자셋으로 저장할 수 없는 한글은 유니코드로 변환되어 저장된다.
프로퍼티 파일을 읽기 위해서는 Properties 객체를 생성 후에 .load() 메소드를 이용하면 된다. .load() 메소드는 프로퍼티 파일로부터 데이터를 읽기 위해 FileReader 객체를 매개값으로 받는다.
'JAVA > JAVA 정리' 카테고리의 다른 글
[JAVA] JAVA 네트워크란 ? (0) | 2023.05.28 |
---|---|
[JAVA] 스트림과 병렬 처리 (0) | 2023.05.27 |
[JAVA] 람다식 (0) | 2023.05.10 |
[JAVA] 예외처리 (0) | 2023.05.09 |
[JAVA] 중첩 클래스와 중첩 인터페이스 (0) | 2023.05.08 |