[이것이 자바다] 15. 컬렉션 자료구조

SeonJin·2023년 9월 5일
0

Java

목록 보기
10/11

📚 이것이 자바다 [개정판]


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>(); // E에 지정된 타입의 객체만 저장
List<E> list = new ArrayList<>(); // E에 지정된 타입과 동일하면 생략 가능
List list = new ArrayList(); // 모든 타입의 객체 저장
  • 객체를 추가하면 내부 배열에 객체가 저장된다 (null 저장 가능)
  • 객체 자체를 저장하는 것이 아닌 객체의 번지를 저장한다
  • 동일한 객체를 중복하여 저장하는 경우 동일한 번지가 저장된다
  • 제한 없이 객체를 추가할 수 있다는 것이 일반 배열과 차이점이다
  • 객체를 추가하거나 제거하면 인덱스 번호가 1씩 당겨지거나 밀려난다
    따라서, 빈번한 객체 삭제와 삽입이 일어나는 곳에서 사용하지 않는 것이 좋다
    list.remove(2);
     list.remove(2); 
    // 2번 인덱스를 삭제하면 기존의 3번이 2번으로 변경되므로
    // 다시 2번 인덱스를 제거할 수 있음

2. Vector

List<E> list = new Vector<E>(); // E에 지정한 타입의 객체만 저장
List<E> list = new Vector<>(); // E에 지정된 타입과 동일하면 생략 가능
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 컬렉션에서 제거
// 1. for문을 이용하는 방법
Set<E> set = new HashSet<>();
for(E e : set) {
	...
}

// 2. iterator() 메소드로 반복자를 얻는 방법
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<>();
// 검색 관련 메소드가 TreeSet에만 정의되어 있으므로 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를 리턴할 경우, 동일한 키로 보고 중복 저장을 허용하지 않는다

// key set 컬렉션을 얻고 반복해서 키와 값 얻기
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 컬렉션을 얻고, 반복해서 키와 값을 얻기
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 타입으로 제한한 컬렉션이다
  • 주로 프로퍼티 파일을 읽을 때 사용한다
// properties 파일 예시
driver=oracle.jdbc.OracleDirver
username=scott
password=tiger
// Properties 사용 예시
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<>();
// 검색 관련 메소드가 TreeMap에만 정의되어 있으므로 TreeMap 타입으로 대입
  • 이진 트리 기반
  • TreeSet과 다른 점은 key-value가 저장된 Entry를 저장한다는 점이다
  • 키를 기준으로 자동 정렬되며 부모 키 값과 비교해서 낮은 것은 왼쪽, 높은 것은 오른쪽 자식 노드에 Entry 객체를 저장한다
  • 검색 기능을 강화시킨 컬렉션이다

Comparable, Comparator

  • TreeSet에 저장되는 객체와 TreeMap에 저장되는 키 객체는 저장과 동시에 오름차순으로 정렬
  • 단, 객체가 Comparable 인터페이스를 구현하고 있는 경우에 정렬이 된다
  • Comparable 인터페이스에는 compareTo() 메소드가 정의되어 있어 메소드 재정의가 필요하다
  • Comparable 비구현 객체를 저장하고 싶은 경우 Comparator 비교자를 제공하면 된다
Comparable 예제
// 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; // 작으면 -1
		else if (age == o.age)
			return 0; // 같으면 0
		else
			return 1; // 크면 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 예시 코드
// 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() : 큐에서 객체를 빼낸다
profile
study notebook

0개의 댓글