18. 컬렉션 프레임워크(Collection Framework) - List, Set, Map [ JAVA ]

duck-ach·2022년 8월 8일
0

JAVA

목록 보기
18/27

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

자바에서 컬렉션 프레임워크(collection framework)란 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미합니다

  • 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것이다.
  • 컬렉션프레임워크는 인터페이스(interface)를 통해 구현이 되어있다.
ListSetMap
순서가 있는 집합순서가 없는 집합 (집합 주머니안에서 막 꺼내쓰는 느낌)Entry별로 저장 (key값, value값)
중복값 허용 O중복값 허용 Xkey중복값 : 허용X / value중복값 : 허용O
Vector, ArrayList, LinkedList, Stack, QueueHashSet, TreeSetHashMap, TreeMap, HashTable, Properties

ArrayList

  1. 연속적이다.
  2. 배열처럼 인덱스를 참조하므로 검색성능이 좋다.
  3. 배열은 크기를 미리 지정해주지만, ArrayList는 크기를 지정해주지 않아도 된다.
  4. 중복값이 허용된다.

ArrayList 객체 생성

특징

  • 제네릭(Generic)기반
  • 생성할 때 데이터타입을 결정한다(구체화)
ArrayList<String> list = new ArrayList<String>();

제네릭(Generic)

제네릭이란 데이터의 타입(data type)을 일반화한다(Generalize)는 것을 의미한다.
제네릭은 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하는 방법이다.

제네릭(Generic)의 장점

  • 제네릭을 사용하면 잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지할 수 있다.
  • 클래스 외부에서 타입을 지정해주기 때문에 따로 타입을 체크하고 변환해 줄 필요가 없다. 즉, 관리하기 편하다.
  • 비슷한 기능을 지원하는 경우 코드의 재사용성이 높아진다.
타입설명
<T>Type
<E>Element
<K>Key
<V>Value
<N>Number

ArrayList 초기화

배열을 리스트로 변환하는 과정 = 리스트의 초기화과정

List<String> list = new ArrayList<String> (Arrays.asList("일", "월", "화", "목"));

asList의 마침표 3개 붙어있는 건 갯수가 정해지지 않았을 때 사용한다. (asList("") asList("", "") 등)

ArrayList 요소추가

  1. 인덱스 지정이 없으면 순서대로 저장
  2. 인덱스 지정도 가능하다.
  3. add("값") 또는 add(index, "값")
List<String> list = new ArrayList<String>();
	list.add("월");
	list.add("화");
	list.add(2, "수");
	list.add(0, "일");
   
   // [일, 월, 화, 수]

ArrayList 요소제거

2가지 방법이 있다.
1. boolean remove(Object obj) : obj 제거. 성공하면 true반환
2. Object remove(int index) : index위치의 요소 제거. 제거한 요소를 반환

 List<String> list = new ArrayList<String> (Arrays.asList("일", "월", "화", "수"));
  	list.remove(0); // [월, 화, 수]
	list.remove("화"); // [월, 수]
	System.out.println(list);
 

ArrayList 길이

배열은 length를 이용하여 배열의 길이를 구하지만, ArrayList는 size()를 이용해 길이를 구한다.

List<String> list = Arrays.asList("일", "월", "화", "수");
	int size = list.size();
	System.out.println(size); // 4

ArrayList 비어있는지 여부확인

ArrayList가 요소가 하나도 없어서 비어있는지 확인하는방법은 간단하다.

List<Integer> list = new ArrayList<Integer> ();
boolean result = list.isEmpty(); // true

ArrayList의 요소 제거

ArrayList에 넣은 요소를 제거하기 위해서는 clear()를 사용하면 된다.

 List<String> list = Arrays.asList("일", "월", "화", "수");
 list.clear();

ArrayList와 for반복문

for문을 이용한 Array출력

우리가 배열을 출력할 때 인덱스값이 있기 때문에 인덱스의 i를 이용하여 for문을 이용하여 이렇게 출력을 했었다.

String arr[] = {"일", "월", "화", "수"};
		for(int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " "); // 일 월 화 수 
		}

for문을 이용한 ArrayList출력

List<String> list = Arrays.asList("일", "월", "화", "수");
	for(int i = 0, length = list.size(); i < length; i++) {
			System.out.print(list.get(i) + " ");
		} // 일 월 화 수

향상된 for문을 이용한 ArrayList출력

ArrayList도 Array의 일종이기 때문에 향상 for문을 이용하여 출력할 수 있다.

List<String> list = Arrays.asList("일", "월", "화", "수");
	for(String element : list) {
		System.out.print(element + " ");
	}

Vector

  • ArrayList와 동일한 내부 구조를 사용하며, 같은 특징을 갖는다.
  • 차이점은 동기화된(Synchronized)메서드로 구성되어 있어 멀티 스레드 환경에서 Thread safe 하다.
  • 단일 스레드 환경에서도 동기화를 하기 때문에 비효율적이며, 성능면에서도 동일한 구조를 갖는 ArrayList보다 떨어져 일반적으로 ArrayList를 많이 사용한다.
  • 기존코드와의 호환성 문제로 남아있다고 한다.

HashSet

  1. 비연속적이다. (집합주머니 안에 들어있다고 생각하면 된다. 막 꺼내쓰는)
  2. 중복값이 허용되지 않는다.
  3. Set 컬렉션 클래스 중 가장 많이 사용된다.
  4. 내부적으로 Hash Algorism을 사용하여 데이터를 관리하기에 검색 속도 성능이 좋다.
  • hashCode()와 equals()를 이용해 데이터의 중복을 판단한다.

HashSet 생성

Set<String> set = new HashSet<String>();

HashSet 초기화

Set<String> set = new HashSet<String>(Arrays.asList("일","월","화","수"));

값을 한번에 지정해줄때는 ArrayList와 같이 Arrays의 asList()메소드를 활용하면 된다.

HashSet 요소추가

Set<String> set = new HashSet<String>();
	set.add("일");
	set.add("월");
	set.add("화");
	set.add("수");
	set.add("수"); // 중복저장 시도
    
    // [일, 월, 화, 수 ]

중복값이 허용되지 않는다.

HashSet 요소제거

Set<String> set = new HashSet<String>();
	set.add("일");
	set.add("월");
	set.add("화");
	set.add("수");
    set.add("목");

	boolean result = set.remove("목");
	System.out.println(result); // true

만약 제거할 값이 존재하지 않는다면 false를 출력하고 제거되지 않는다.

HashSet의 길이구하기

ArrayList와 똑같이 size()메소드를 활용하면된다.

Set<String> set = new HashSet<String>(Arrays.asList("일","월","화","수"));
int size = set.size(); // 4

HashSet의 반복문

HashSet은 index가 존재하지 않고, 순차적이지 않으므로 일반 for문을 사용할 수 없다.
그러므로 향상 for문을 사용하여 요소를 출력해보겠다.

Set<String> set = new HashSet<String>(Arrays.asList("일","월","화","수"));
for(String element : set) {
		System.out.println(element); // [일, 월, 화, 수 ]
	}

HashSet의 집합

HashSet이 마치 순서가 없는 집합 주머니와 같다고 설명했으니 합집합, 차집합, 교집합, 부분집합을 구해보겠다.

Set<Integer> set1 = new HashSet<Integer>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer> set2 = new HashSet<Integer>(Arrays.asList(3, 4, 5, 6, 7));
Set<Integer> set3 = new HashSet<Integer>(Arrays.asList(6, 7));

HashSet의 합집합

set1.addAll(set2); // [1, 2, 3, 4, 5, 6, 7]

HashSet의 차집합

set1.removeAll(set2); // [1, 2]

HashSet의 교집합

set1.retainAll(set2); // [3, 4, 5]

HashSet의 부분집합

부분집합은 여부를 판단할 수 있다.

boolean result1 = set1.containsAll(set3);
boolean result2 = set2.containsAll(set3);
System.out.println(result1); // false
System.out.println(result2); // true

Map

  • Key와 Value값으로 이루어진 데이터
  • Array나 ArrayList의 경우 자동으로 index가 할당되지만, Map의 key값은 자유롭게 만들면 된다.
  • Value(값)은 중복값이 있을 수 있으나, Key(키)는 중복값이 있을 수 없다.
  • Key와 Value 두개 묶음을 Entry라고 부른다.

HashMap 생성

Map<String, String> map1 = new HashMap<String, String>();
// 또는
Map<String, Object> map2 = new HashMap<String, Object>();

실무에서는 String이나 Object 타입을 많이 사용한다고 한다.
Map은 key값과 value값이 따로 있으니까 데이터타입을 두개 지정해주어야 한다.

<Object>는 모든 데이터타입을 받을 수 있다.

HashMap 요소추가

Map은 put()을 통해 요소추가를 한다.

Map<String, Object> map = new HashMap<String, Object>();
map.put("title", "소나기");
map.put("author", "황순원");
map.put("price", 20000);

HashMap Entry단위로 순회

Map<String, Object> map = new HashMap<String, Object>();

	map.put("title", "소나기");
	map.put("author", "황순원");
	map.put("price", 20000);

	for(Map.Entry<String, Object> entry : map.entrySet()) {
		System.out.println(entry.getKey() + ":" + entry.getValue());	
	}
    
	//author:황순원
	//price:20000
	//title:소나기

위에 말했다시피 Entry(Key + Value)를 합쳐 부르는 말이다.
Entry를 기준으로 순회하는 방법 말고도 key를 이용해 순회하는 방법도 있다.

HashMap key를 이용한 순회

향상 for문을 사용해서 순회출력을 해보겠다.

Map<String, Object> map = new HashMap<String, Object>();

	map.put("title", "소나기");
	map.put("author", "황순원");
	map.put("price", 20000);	
    
    for(String key : map.keySet()) {
			System.out.println(key + ":" + map.get(key));
		}
        
    //author:황순원
	//price:20000
	//title:소나기    
        

[응용] HashMap을 사용하여ArrayList에 저장된 요소를 중복값을 제외하고 출력

Map<String, Object> map1 = new HashMap<String, Object>();
		map1.put("title", "summer");
		map1.put("author", "hisahisijo");
		map1.put("price", 10000);
		
		Map<String, Object> map2 = new HashMap<String, Object>();
		map2.put("title", "어린왕자");
		map2.put("author", "생택쥐베리");
		map2.put("price", 12000);
		
		Map<String, Object> map3 = new HashMap<String, Object>();
		map3.put("title", "홍길동전");
		map3.put("author", "허균");
		map3.put("price", 16000);
		
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		list.add(map1);
		list.add(map2);
		list.add(map3);
		
		for(Map<String, Object> map : list) { // List
			for(Map.Entry<String, Object> entry : map.entrySet()) { // Map
				System.out.println(entry.getKey() + ":" + entry.getValue());
			}
			System.out.println();
		}

TreeMap

이진트리 (Binary Tree)
1. 모든 노드는 2개의 자식을 가질 수 있다.
2. 작은 값은 왼쪽, 큰 값은 오른쪽에 저장한다.

TreeMap
1. key를 기준으로 왼쪽에 작은 값, 오른쪽에 큰 값이 저장된다.
2. key를 기준으로 자동으로 정렬되면서 저장된다.
3. 크기 비교 및 범위 연산에 적절하다.

TreeMap 생성

Map<Integer, String> map = new TreeMap<Integer, String>();

선언하는 방법은 부모 Map을 선언하고 TreeMap객체를 생성하는 방법으로 같다.

TreeMap 요소 추가

put()를 이용해서 요소를 추가한다.

map.put(65, "제시카");
map.put(85, "에밀리");
map.put(35, "제임스");
map.put(95, "사만다");
// {35=제임스, 65=제시카, 85=에밀리, 95=사만다}

TreeMap자체에서는 key의 정렬을 자동적으로 해서 출력된다.

TreeMap Entry단위로 for순회

TreeMap도 Map이므로 Entry단위로 for순회를 할 수 있다.

for(Map.Entry<Integer, String> entry : map.entrySet()) {
		System.out.println(entry.getKey() + ":" + entry.getValue());			
		}

TreeMap의 정렬

기본정렬 : 오름차순 정렬
TreeMap은 TreeMap만 사용할 수 있는 메소드가 다수 있으므로 TreeMap 타입으로 생성하는 것이 좋다.

NavigableMap<K,V> : 지정된 검색 대상에 대해 가장 근접한 일치 항목을 반환하는 탐색 메서드와 함께 확장된 정렬된 맵입니다.

  • SortedMap<K,V> 인터페이스를 상속하는 인터페이스이다.
  • 구현체는 TreeMap을 사용하면 된다.
// 생성중요
TreeMap<Integer, String> map = new TreeMap<Integer, String>();

	map.put(65, "제시카");
	map.put(85, "에밀리");
	map.put(35, "제임스");
	map.put(95, "사만다");
  
 // 정렬변경 : decendingMap() 메소드 호출
 // 오름차순 정렬 ↔ 내림차순 정렬
 // TreeMap타입으로 써야 TreeMap에서 사용할 수 있는 메소드들을 호출할 수 있다.

NavigableMap<Integer, String> map2 = map.descendingMap();

	for(Map.Entry<Integer, String> entry : map2.entrySet()) {
		System.out.println(entry.getKey() + ":" + entry.getValue());
	//95:사만다
	//85:에밀리
	//65:제시카
	//35:제임스
    
 // 다시 decendingMap() 메소드를 호출하면 오름차순 정렬이 된다.
 NavigableMap<Integer, String> map3 = map2.descendingMap();
 // key값으로 순회
 	for(Integer key : map3.keySet()) {
			System.out.println(key + ":" + map3.get(key));
		}
	
}

profile
자몽 허니 블랙티와 아메리카노 사이 그 어딘가

0개의 댓글