📚 이것이 자바다 [개정판]
sec01. 컬렉션 프레임워크
- 자바는 자료구조를 바탕으로 관련된 인터페이스와 클래스를 java.util 패키지에 포함시켜 놓았다
- 이 모든 것을 총칭하여 컬렉션 프레임워크라고 부른다
- 몇 가지 인터페이스를 통해 다양한 컬렉션 클래스를 이용할 수 있도록 설계되어 있다
sec02. List 컬렉션
- 순서를 유지하고 저장한다
- 중복 저장이 가능하다
기능 | 메소드 | 설명 |
---|
객체 추가 | add(E e) | 맨 끝에 객체 추가 |
| add(int index, E element) | 주어진 인덱스에 객체 추가 |
| set(int index, E element) | 주어진 인덱스의 객체를 새로운 객체로 변경 |
객체 검색 | contains(Object o) | 객체의 저장여부 확인 |
| get(int index) | 주어진 인덱스에 저장된 객체 리턴 |
| isEmpty() | 컬렉션이 비어 있는지 확인 |
| size() | 저장된 전체 객체 수 리턴 |
객체 삭제 | clear() | 저장된 모든 객체 삭제 |
| remove(int index) | 주어진 인덱스에 저장된 객체 삭제 |
| remove(Object o) | 주어진 객체 삭제 |
1. ArrayList
List<E> list = new ArrayList<E>();
List<E> list = new ArrayList<>();
List list = new ArrayList();
2. Vector
List<E> list = new Vector<E>();
List<E> list = new Vector<>();
List list = new Vector();
- ArrayList와 동일한 내부 구조를 가지고 있으나 Vector는 동기화된 메소드로 구성되어 있다
- 멀티 스레드가 동시에 Vector() 메소드를 실행할 수 없다는 뜻으로 멀티 스레드 환경에서 안전하게 객체 변경이 가능하다
3. LinkedList
List<E> list = new LinkedList<E>();
List<E> list = new LinkedList<>();
List list = new LinkedList();
- ArrayList와 사용 방법은 동일하지만 내부 구조는 완전히 다르다
- LinkedList는 인접 객체를 체인처럼 연결하여 관리한다
- 특정 위치에서 객체가 변경되면 바로 앞뒤 링크만 변경하면 되므로 빈번한 객체 변경이 일어나는 곳에서 좋은 성능을 발휘한다
sec03. Set 컬렉션
기능 | 메소드 | 설명 |
---|
객체 추가 | add(E e) | 주어진 객체를 저장하면 true, 중복 객체면 false 리턴 |
객체 검색 | contains(Object o) | 주어진 객체가 저장되어 있는지 여부 |
| boolean containsValue(Object value) | 주어진 값이 있는지 여부 |
| isEmpty() | 컬렉션이 비어 있는지 확인 |
| Iterator iterator() | 저장된 객체를 한 번씩 가져오는 반복자 리턴 |
| size() | 저장되어 있는 전체 객체 수 리턴 |
객체 삭제 | clear() | 저장된 모든 객체를 삭제 |
| remove(Object o) | 주어진 객체를 삭제 |
1. HashSet
Set<E> set = new HashSet<E>();
Set<E> set = new HashSet<>();
Set set = new HashSet();
- 다른 객체라도 hashCode() 리턴값이 같고 equals()가 true를 리턴하면 동일한 객체로 판단한다
- Set 컬렉션은 인덱스로 객체를 검색해서 가져오는 메소드가 없어서 객체를 한 개씩 반복해서 가져와야 한다
hasNext()
가져올 객체가 있으면 true를 리턴하고 없으면 false를 리턴
next()
컬렉션에서 하나의 객체를 가져옴
remove()
next()로 가져온 객체를 Set 컬렉션에서 제거
Set<E> set = new HashSet<>();
for(E e : set) {
...
}
Set<E> set = new HashSet<>();
Iterator<E> iterator = set.iterator();
while(iterator.hasNext()) {
E e = iterator.next();
}
2. TreeSet
TreeSet<E> treeSet = new TreeSet<E>();
TreeSet<E> treeSet = new TreeSet<>();
- 이진 트리 기반 : 루트 노드에서 시작하여 각 노드에 2개의 노드를 연결한 트리 형태의 구조
- 자동 정렬되며 부모 노드 객체와 비교하여 낮으면 왼쪽, 높으면 오른쪽 자식 노드에 저장한다
- 검색 기능을 강화시킨 컬렉션이다
sec04. Map 컬렉션
- Key-Value로 구성된 Entry 객체를 저장한다 (key와 value 모두 객체이다)
- Key는 중복 저장할 수 없고, 동일한 키로 값을 저장하면 새로운 값으로 변경된다
- Value는 중복 저장할 수 있다
기능 | 메소드 | 설명 |
---|
객체 추가 | put(K key, V value) | 키와 값을 추가하고 저장되면 값을 리턴 |
객체 검색 | containsKey(Object key) | 주어진 키가 있는지 여부 |
| containsValue(Object value) | 주어진 값이 있는지 여부 |
| Set(Map.Entry<K,V>> entrySet() | 키와 값의 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아 리턴 |
| get(Object key) | 주어진 키의 값을 리턴 |
| isEmpty() | 컬렉션이 비어있는지 여부 |
| Set keySet() | 모든 키를 Set 객체에 담아 리턴 |
| size() | 저장된 키의 총 수를 리턴 |
| Collection values() | 저장된 모든 값 Collection에 담아 리턴 |
객체 삭제 | clear() | 모든 Map.Entry(키와 값)를 삭제 |
| remove(Object key) | 주어진 키와 일치하는 Map.Entry를 삭제하고 삭제되면 값을 리턴 |
1. HashMap
Map<K, V> map = new HashMap<K, V>();
Map<String, Integer> map = new HashMap<String, Integer>();
Map<String, Integer> map = new HashMap<>();
키로 사용할 객체의 hashCode() 메소드 리턴값이 같고 equals() 메소드가 true를 리턴할 경우, 동일한 키로 보고 중복 저장을 허용하지 않는다
Set<String> keySet = map.keySet();
Iterator<String> keyIterator = keySet.iterator();
while(keyIterator.hasNext()) {
String k = keyIterator.next();
Integer v = map.get(k);
System.out.println(k + ":" + v);
}
Set<Entry<String, Integer>> entrySet = map.entrySet();
Iterator<Entry<String, Integer>> entryIterator = entrySet.iterator();
while (entryIterator.hasNext()) {
Entry<String, Integer> entry = entryIterator.next();
String k = entry.getKey();
Integer v = entry.getValue();
System.out.println(k + ":" + v);
}
System.out.println();
2. Hashtable
Map<String, Integer> map = new Hashtable<String, Integer>();
Map<String, Integer> map = new Hashtable<>();
- HashMap와 동일한 내부 구조를 가지고 있으나 Hashtable은 동기화된 메소드로 구성되어 있다
- 멀티 스레드가 동시에 Hashtable의 메소드를 실행할 수 없다는 뜻으로 멀티 스레드 환경에서 안전하게 객체 변경이 가능하다
💡 Properties
- Hashtable의 자식 클래스이므로 Hashtable의 특징을 그대로 가지고 있다
- key와 value를 String 타입으로 제한한 컬렉션이다
- 주로 프로퍼티 파일을 읽을 때 사용한다
driver=oracle.jdbc.OracleDirver
username=scott
password=tiger
Properties properties = new Properties();
properties.load(Xxx.class.getResourceAsStream("파일명.properties"));
3. TreeMap
TreeMap<K, V> treeSet = new TreeMap<K, V>();
TreeMap<K, V> treeSet = new TreeMap<>();
- 이진 트리 기반
- TreeSet과 다른 점은 key-value가 저장된 Entry를 저장한다는 점이다
- 키를 기준으로 자동 정렬되며 부모 키 값과 비교해서 낮은 것은 왼쪽, 높은 것은 오른쪽 자식 노드에 Entry 객체를 저장한다
- 검색 기능을 강화시킨 컬렉션이다
Comparable, Comparator
- TreeSet에 저장되는 객체와 TreeMap에 저장되는 키 객체는 저장과 동시에 오름차순으로 정렬
- 단, 객체가 Comparable 인터페이스를 구현하고 있는 경우에 정렬이 된다
- Comparable 인터페이스에는 compareTo() 메소드가 정의되어 있어 메소드 재정의가 필요하다
- Comparable 비구현 객체를 저장하고 싶은 경우 Comparator 비교자를 제공하면 된다
Comparable 예제
class Person implements Comparable<Person> {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
if (age < o.age)
return -1;
else if (age == o.age)
return 0;
else
return 1;
}
}
public class ComparableEx {
public static void main(String[] args) {
TreeSet<Person> treeSet = new TreeSet<Person>();
treeSet.add(new Person("홍길동", 45));
treeSet.add(new Person("김길동", 26));
treeSet.add(new Person("차길동", 30));
for (Person person : treeSet) {
System.out.println(person.name + ":" + person.age);
}
}
}
Comparator 예시 코드
class Fruit {
public String name;
public int price;
public Fruit(String name, int price) {
this.name = name;
this.price = price;
}
}
class FruitComparator implements Comparator<Fruit> {
@Override
public int compare(Fruit o1, Fruit o2) {
if(o1.price < o2.price) return -1;
else if(o1.price == o2.price) return 0;
else return 1;
}
}
public class ComparatorEx {
public static void main(String[] args) {
TreeSet<Fruit> treeSet = new TreeSet<Fruit>(new FruitComparator());
treeSet.add(new Fruit("포도", 3000));
treeSet.add(new Fruit("수박", 10000));
treeSet.add(new Fruit("딸기", 6000));
for(Fruit fruit : treeSet) {
System.out.println(fruit.name + ":" + fruit.price);
}
}
}
sec06. LIFO, FIFO 컬렉션
1. Stack (LIFO)
Stack<E> stack = new Stack<E>();
Stack<E> stack = new Stack<>();
- Last In First Out 후입선출 - 나중에 넣은 객체가 먼저 빠져 나가는 구조
- push(E item) : 주어진 객체를 스택에 넣는다
- pop() : 스택의 맨 위 객체를 빼낸다
2. Queue (FIFO)
Queue<E> queue = new Queue<E>();
Queue<E> queue = new Queue<>();
- First In First Out 선입선출 - 먼저 넣은 객체가 먼저 빠져 나가는 구조
- offer(E e) : 주어진 객체를 큐에 넣는다
- poll() : 큐에서 객체를 빼낸다