본문 바로가기

develop/Java

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

빈센조 ㄸㅐ문에 못올렸다 ;; 최근

 

Collection Framework

 

컴퓨터에서 데이터를 효율적으로 저장 및 관리하는 방법 = 자료구조

=> 자료구조를 자바에서 구현하여 제공하는 클래스 및 인터페이스 모음

=> 3대 인터페이스 : Set, List, Map

=> Set과 List 인터페이스는 공통적으로 Collection 인터페이스를 상속받았으므로 제공되는 메서드가 거의 동일함.

- java.util 패키지에 위치하며, 각 인터페이스를 구현한 구현체 클래스가 제공된다. 

 

ex) Set -> HashSet, TreeSet 클래스 등 사용

 

구현체 클래스 자체로 사용하거나 인터페이스 타입으로 업캐스팅 가능

toString() 메서드가 오버라이딩 되어 있어 저장된 데이터 확인이 편리함.

제네릭 타입 지정이 가능하며, 지정 생략 시 데이터 저장 및 리턴 시 사용되는 데이터타입은 Object 로 처리된다.

배열 구조와 달리 데이터 저장 공간이 자동으로 관리되므로 크기에 제한 없이 자유롭게 데이터 저장 가능함

(배열은 처음부터 저장공간을 지정하기 때문에)

 

 

 

1. Set 계열

 

- 데이터 저장 순서 유지x , 데이터 중복 허용 x

=> 주머니에 공을 무작위로 집어넣는 것과 유사한 방식

=> null값도 하나의 값만 저장 가능

- 대표적인 구현체 클래스 : HashSet, TreeSet등

- 아주 효율적인 중복 제거 방식으로 사용됨.

ex) 로또 번호 생성기, 빙고 게임 번호 생성 등

 

 

//HashSet 객체 생성
HashSet set = new HashSet(); //구현체 클래스 타입으로 직접 다루거나
Set set = new HashSet(); //Set 인터페이스 타입으로 업캐스팅도 가능함

// boolean isEmpty() : 컬렉션 객체가 비어있는지 여부 리턴
System.out.println("Set 객체가 비어있는가? " + set.isEmpty());
		
// int size() : 컬렉션 객체에 저장된 요소(데이터) 갯수 리턴
System.out.println("Set 객체에 저장된 요소 갯수 : " + set.size());

// boolean add(Object o) : Set 객체에 데이터(요소, Element) 추가
// => 파라미터가 Object 타입이므로 모든 타입 데이터 저장 가능
// => 리턴타입이 boolean 타입이며, 요소 추가 성공 여부 리턴(중복 허용X)
set.add(1);
set.add("TWO");
System.out.println("실수 3.14 추가 가능한가? " + set.add(3.14));
// => 기존 요소 중 3.14 가 없으므로 추가되며, true 리턴됨
		
System.out.println("Set 객체가 비어있는가? " + set.isEmpty());
System.out.println("Set 객체에 저장된 요소 갯수 : " + set.size());
		
// String toString() : 컬렉션 객체에 저장된 모든 요소를 문자열로 리턴
// => 저장 순서가 유지되지 않으므로, 리턴되는 데이터의 순서 다를 수 있음
//System.out.println("Set 객체의 모든 요소 : " + set.toString());
System.out.println("Set 객체의 모든 요소 : " + set); // toString() 생략
		
System.out.println("실수 3.14 추가 가능한가? " + set.add(3.14));
// => 이전에 이미 3.14 가 저장되어 있으므로, 중복 저장 불가. false 리턴됨
System.out.println("Set 객체의 모든 요소 : " + set);
		
System.out.println("문자 '4' 추가 가능한가? " + set.add('4'));
System.out.println("Set 객체의 모든 요소 : " + set);
		
set.add(5);
set.add("육");
System.out.println("Set 객체에 저장된 요소 갯수 : " + set.size());
System.out.println("Set 객체의 모든 요소 : " + set);
		// boolean contains(Object o) : 객체 내에서 요소 o 포함 여부 리턴
		System.out.println("Set 객체에 실수 3.14 존재 여부 : " + set.contains(3.14));
		System.out.println("Set 객체에 정수 3 존재 여부 : " + set.contains(3));
		
		// boolean remove(Object o) : 객체 내에서 요소 o 삭제 후 결과 리턴
		System.out.println("Set 객체에서 실수 3.14 삭제 : " + set.remove(3.14));
		System.out.println("Set 객체에서 실수 3.14 삭제 : " + set.remove(3.14));
		
		// Object[] toArray : 컬렉션 객체를 Object 타입 배열로 변환하여 리턴
		Object[] oArr = set.toArray();
		
		for(int i = 0; i < oArr.length; i++) { // for(Object o2 : oArr)
			System.out.println(oArr[i]);       //    System.out.println(o2);
		}
		
		// void clear() : 객체 내의 모든 요소 삭제(초기화)
//		set.clear();
//		System.out.println("Set 객체의 모든 요소 : " + set);

		
		// Set 또는 List 계열 객체 생성 시 생성자에 컬렉션 객체 전달 시
		// 해당 요소를 갖는 새로운 객체 생성 가능
		Set set2 = new HashSet(set);
		System.out.println("set 객체의 모든 요소 : " + set);
		System.out.println("set2 객체의 모든 요소 : " + set2);
		
		// equals() 메서드를 사용하면 두 객체의 요소를 비교하여
		// 모든 요소가 같으면 true, 아니면 false 리턴(주소값 비교가 아님!)
		System.out.println("set 과 set2 객체는 같은가? " + set.equals(set2));
		
		// 객체 생성 후 addAll() 메서드를 호출하여 데이터 이전(복사)도 가능
		Set set3 = new HashSet();
		set3.addAll(set2);
		System.out.println("set3 객체의 모든 요소 : " + set3);

 

 

배열로 변환 후 반복문을 사용하는 방법 외에도 set 객체 요소를 접근하는. 방법

1. 향상된 for문 사용

for(Object o5 : set5){
	Sysyem.out.println(o5)
}

2. lterator(반복자)를 활용하는 방법

Iterator ite = set5.iterlator();
//=> While() 문을 사용하여 Iterator 객체의 hashNext() 메서드를 호출하여
//다음 요소가 존재할 동안 반복 수행

while(ite.hasNext()){
	System.out.println(ite.next());
}

 

 

TreeSet 객체를 활용하면 같은 타입 데이터가 저장된 Set 객체에 대한 정렬 기능이 수행 가능

=> 수치 데이터는 수치의 크기 순으로 오름차순 정렬되며 문자열 데이터는 문자 코드값 순으로 오름차순 정렬도므로

각각의 정렬 결과는 데이터타입에 따라 달라질 수 있다.

주의할 점은 반드시 같은 타입 데이터만 저장되어야 함

 

// TreeSet 객체를 사용하여 set4 객체 생성 후 
		// 문자열 "1", "10", "30", "100", "200", "300" 추가 => 섞기
		Set set4 = new TreeSet();
		set4.add("200");
		set4.add("30");
		set4.add("1");
		set4.add("300");
		set4.add("100");
		set4.add("10");
//		set4.add(10); // 오류 발생! 문자열 외에 다른 데이터 저장 불가!
		
		System.out.println("set4 객체의 모든 요소 : " + set4);
		
		Set set5 = new TreeSet();
		set5.add(200);
		set5.add(30);
		set5.add(1);
		set5.add(300);
		set5.add(100);
		set5.add(10);
//		set5.add(3.14); // 오류 발생! 정수 외에 다른 데이터 저장 불가!
		
		System.out.println("set5 객체의 모든 요소 : " + set5);

 

 

 

2. List 타입 

 

 

-Set 계열과 달리 데이터 저장순서 유지 o , 데이터 중복 허용 o

-저장되는 데이터에는 자동으로 인덱스가 부여됨(0번부터 시작) = 배열과 동일

-대표적인 구현체 클래스 : ArrayList, Vector, LinkedList emd

-기본적인 메서드 대부분 Set 계열과 동일 (부모가 동일)

 

List 객체 생성 -> ArrayList  클래스 활용(업캐스팅)

 

 

		// add() 메서드를 사용하여 데이터 추가
		list.add(1);
		list.add("TWO");
		list.add(3.14);
		System.out.println("List 객체가 비어있는가? " + list.isEmpty());
		System.out.println("List 객체에 저장된 요소 갯수 : " + list.size());
		System.out.println("List 객체에 저장된 요소 : " + list);
		
		System.out.println("중복 데이터 3.14 추가 가능한가? " + list.add(3.14));
		System.out.println("List 객체에 저장된 요소 : " + list);
		
		// List 객체는 인덱스를 활용한 메서드가 다양
		// Object get(int index) : index 에 해당하는 위치의 요소 리턴
		System.out.println("List 객체 1번 인덱스 요소 : " + list.get(1));
		// 주의! 배열과 마찬가지로 존재하지 않는 인덱스 지정 시
		// IndexOutOfBoundsException 예외 발생!
//		System.out.println("List 객체 5번 인덱스 요소 : " + list.get(5));
		
		// int indexOf(Object o) : o 에 해당하는 요소의 인덱스 번호 리턴
		System.out.println("문자열 TWO 요소 인덱스 번호 : " + list.indexOf("TWO"));
		
		// Object set(int index, Object o) : index 위치에 o 덮어씀
//		list.set(2, '4');
		System.out.println(list.set(2, '4')); // 덮어쓸 때 제거되는 요소 리턴됨
		System.out.println("List 객체에 저장된 요소 : " + list);
		
		// Object remove(int index) : 해당 인덱스 요소 제거
		// Object remove(Object o) : 해당 요소 o 제거
//		list.remove(1); // 정수 1이 아닌 1번 인덱스 요소("TWO") 제거됨
		// => 정수 1 삭제하기 위해서는 정수 1의 인덱스번호(0) 지정하거나
		//    정수 1을 Object 타입으로 변환하여 직접 지정해야함
//		list.remove((Object)1); // 1번 인덱스가 아닌 Object 타입 1 로 지정됨
		// => indexOf() 메서드와 조합하여 가장 정확하게 삭제 가능
		list.remove(list.indexOf(1)); // 1번 데이터의 인덱스를 찾아 전달
		System.out.println("List 객체에 저장된 요소 : " + list);
		
		// List subList(int fromIndex, int toIndex)
		// => 시작인덱스 ~ 끝인덱스-1 까지의 부분 리스트 추출하여 List 로 리턴
//		List subList = list.subList(1, 2); // 1 ~ 1번 인덱스까지 추출
		List subList = list.subList(1, 3); // 1 ~ 2번 인덱스까지 추출
		System.out.println("List 객체의 부분 리스트 모든 요소 : " + subList);
		
		System.out.println("==================================");
		
		List list2 = new ArrayList();
		list2.add(5);
		list2.add(3);
		list2.add(2);
		list2.add(6);
		list2.add(1);
		list2.add(4);
		System.out.println("정렬 전 : " + list2);
		
		// java.util.Collections 클래스의 static 메서드 sort() 사용 시
		// List 객체에 대한 정렬 작업 수행 가능(동일한 타입만 가능)
		Collections.sort(list2);
		System.out.println("정렬 후 : " + list2);
		
		// java.util.Collections 클래스의 static 메서드 shuffle() 사용 시
		// List 객체에 대한 섞기(셔플) 작업 수행 가능(모든 타입 데이터 가능)
		Collections.shuffle(list2);
		System.out.println("셔플 후 : " + list2);
		
	
		System.out.println("========================================");
		
		// List 객체의 모든 요소에 차례대로 접근하는 방법
		// => Set 계열과 달리 인덱스 활용이 가능하므로 배열처럼 사용도 가능
		// 1. 배열 접근 방법과 동일한 방법 사용
		//    => 배열명.length 대신 List객체명.size() 로 대체
		for(int i = 0; i < list2.size(); i++) {
			// 인덱스번호를 제어변수 i 로 지정 가능
			System.out.println(list2.get(i));
		}
		
		System.out.println("-----");
		
		// 2. 향상된 for문 사용
		for(Object o : list2) {
			System.out.println(o);
		}
		
		System.out.println("-----");
		
		// 3. Iterator(반복자) 사용
		Iterator ite = list2.iterator();
		
		while(ite.hasNext()) {
			System.out.println(ite.next());
		}
		
	}

 

 

 

3. Map 계열

- 데이터를 키(Key)와 값(Value)의 한 쌍으로 갖는 자료구조

=> 키와 값의 한 쌍을 Map.Entry 타입 객체로 관리(저장)

- 키는 중복 불가능, 값은 중복 가능

=> 키는 Set 계열 객체로 관리됨

- 대표적인 구현체 클래스 : HashMap, Properties 등

- Set, List 계열과 구조가 전혀 다르므로 사용하는 메서드가 다름 (동일한 이름으로 제공되는 메서드도 존재)

- toString() 메서드 등 오버라이딩 되어 있음

 

Map map = new HashMap();

 

		// put(Object key, Object value) : key 에 해당하는 데이터 value 추가
		map.put(1, "자바");
		map.put(2, "JSP");
		map.put(3, "Android");
		
		System.out.println("Map 객체의 모든 키, 값 출력 : " + map);
		
		// 주의! 기존에 존재하는 키(중복 키)의 새 값을 저장할 경우
		// 기존 키의 값을 덮어씀(제거되는 값이 리턴됨)
		System.out.println(
				"정수 3을 키로 갖는 문자열 Spring 값 저장 : " + map.put(3, "Spring"));
		System.out.println("Map 객체의 모든 키, 값 출력 : " + map);
		
		// Object get(Object key) : key 에 해당하는 value 리턴
		System.out.println("정수 3에 해당하는 키의 값 : " + map.get(3));
		System.out.println("정수 5에 해당하는 키의 값 : " + map.get(5));
		// => 존재하지 않는 키를 지정하면 null 값이 리턴됨
		
//		map.remove(3); // 3번 키의 데이터 삭제(키도 함께 삭제)
//		System.out.println("3번 키 Spring 삭제 가능? " + map.remove(3, "Spring"));
		// => 3번 키의 "Spring" 데이터가 일치하면 삭제
//		System.out.println("2번 키 Android 삭제 가능? " + map.remove(2, "Android"));
		// => 2번 키의 "Android" 데이터가 일치하면 삭제
		//    키 또는 값 중 하나라도 일치하지 않으면 삭제 불가 
//		System.out.println("Map 객체의 모든 키, 값 출력 : " + map);
		
		System.out.println("-------------------");
		
		// Set keySet() : Map 객체의 Key 목록을 Set 타입 객체로 리턴
		Set keySet = map.keySet();
		System.out.println(keySet);
		
		// Collection values() : Map 객체의 Value 목록을 Collection 타입으로 리턴
		// => Set, List 타입 객체 생성 시 생성자에 전달 가능 
//		Set valueSet = new HashSet(map.values()); // 중복 제거됨
		List valueList = new ArrayList(map.values()); // 중복 유지됨
		System.out.println(valueList);
		
		// Set entrySet() : Map 객체의 Key=Value 형태 객체(Map.Entry) 한 쌍씩을 
		//                  묶음으로 갖는 Set 객체 리턴
		Set entrySet = map.entrySet();
		System.out.println(entrySet);
		
		System.out.println("==============================");
		
		// Key 또는 Value 는 Object 타입이므로 모든 타입 사용 가능
		// ex) 키를 문자열로, 값을 정수로 사용 가능
		// map2 객체 생성 "딸기"=1000, "바나나"=500, "자몽"=2000 엔트리 저장
		Map map2 = new HashMap();
		map2.put("딸기", 1000);
		map2.put("바나나", 500);
		map2.put("자몽", 2000);
		
		System.out.println("전체 과일 목록 : " + map2);
		
		System.out.println("자몽의 가격 : " + map2.get("자몽") + "원");
		
		System.out.println(
				"과일 중에 바나나가 있습니까? " + map2.containsKey("바나나"));
		System.out.println(
				"과일 중에 사과가 있습니까? " + map2.containsKey("사과"));
		
		System.out.println(
				"500원짜리 과일 있습니까? " + map2.containsValue(500));
		System.out.println(
				"5000원짜리 과일 있습니까? " + map2.containsValue(5000));
	}

 

 

 

 

'develop > Java' 카테고리의 다른 글

중첩 클래스  (0) 2021.04.12
제네릭(Generic, 일반화)  (1) 2021.04.05
java.lang / java.util  (0) 2021.03.23
StringBuilder, StringBuffer 클래스  (0) 2021.03.23
String 클래스  (0) 2021.03.21