Set
저장 순서가 유지되지 않고 중복 객체도 저장하지 못하게 하는 자료 구조
null도 중복을 허용하지 않기 때문에 1개의 null만 저장
구현 클래스로 HashsSet,LinkedHashSet,TreeSet이 있음
Set 계열 주요 메소드
HashSet
Set에 객체를 저장할 때 hash함수를 사용하여 처리 속도가 빠름
동일 객체 뿐 아니라 동등 객체도 중복하여 저장하지 않음
LinkedHashSet
HashSet과 거의 동일하지만 Set에 추가되는 순서를 유지한다는 점이다름
Enumeration,Iterator,Listlterator
컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스
-Enumeration : Iterator의 구버전
-Listlterator : Iterator를 상속받아 양방향 특징
[그림1]의 상속구조 때문에 iterator()메소드는 List와Set 계열에서만 사용
-> Map의 경우 Set 또는 List화 시켜서 iterator()를 사용해야 함!
Map
키(Key)와 값(Value)으로 구성되어 있으며 키와 값은 모두 객체
키는 중복 저장을 허용하지 않고 (Set방식),값은 중복 저장 가능 (List방식)
키가 중복되는 경우, 기존에 있는 키에 해당하는 값을 덮어 씌움
구현 클래스로 HashMap,HashTable,LinkedHashMap,Properties,TreeMap이 있음
Map 계열 주요 메소드
HashMap
키 객체는 hashCode()와 equals()를 재정의해 동등 객체가 될 조건을 정해야 함
때문에 키 타입은 hashCode와 equals()메소드가 재정의되어 있는 String타입을 주로 사용
예) Map<K,V> map = new hashMap<K,V>0;
Hashtable
키 객체 만드는 법은 HashMap과 동일하나 Hashtable은 스레드 동기화가 된 상태이기 때문에,
복수의 스레드가 동시에 Hashtable에 접근해 객체를 추가,삭제 하더라도 스레드에 안전
(Thread safe) 예) Map<K,V> map = new HashTable<K,V>();
TreeSet과 TreeMap
검색 기능을 강화시킨 컬렉션으로,계층 구조를 활용해 이진 트리 자료구조를 구현하여 제공
트리 : 각 노드 간 연결된 모양이 나무와 같다고 해서 붙여진 이름
Tree 구조
TreeSet
이진 트리를 기반으로 한 Set컬렉션으로,왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성
TreeMap
이진 트리를 기반으로 한 Map컬렉션으로, 키와 값이 저장된 Map.Entry를 저장하고
왼쪽과 오른쪽 자식 노드를 참조하기 위한 두 개의 변수로 구성
TreeSet,TreeMap정렬
오름차순(기본 정렬)
-TreeSet의 객체와 TreeMap의 Key는 저장과 동시에 자동 오름차순 정렬
-숫자(Integer,Double) 타입일 경우 값으로 정렬
-문자열(String) 타입일 경우 유니코드로 정렬
-정렬을 위해 Java.lang,Comparable을 구현한 객체 요구
그러지 않을 경우 ClassCastException 발생
(Integer,Double,String 모두 Comparable 인터페이스를 통해 오름차순이 구현되어 있음)
내림차순(따로 구현)
-TreeSet,TreeMap 객체 생성 시 매개변수 생성자를 통해 재정렬 가능
ex. Tree tSet = new TreeSet(Comparator<? super E> comparator);
TreeMap<K,V> tMap = new TreeMap(Comparator<? sper K>comparator);
코드(Set)
package edu.kh.collection.model.servuce;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
import edu.kh.collection.model.vo.Member;
public class SetService {
// Set(집합)
// - 순서를 유지하지 않음(== 인덱스 없음)
// - 중복을 허용하지 않는다. (null도 중복 X,1개만 저장 가능)
// ***Set이 중복을 확인하는 방법***
// -> 객체가 가지고 있는 필드값이 모두 같으면 중복으로 판단
// -> 이 때,필드값이 모두 같은지 비교하기 위해서
// 객체에 "equals()"가 반드시 오버라이딩 되어있어야 한다.
private Set<String> memberSet;
public void ex1() {
Set<String> set = new HashSet<String>();
// HashSet : Set의 대표적인 자식 클래스
// 사용 조건 1: 저장되는 객체에 equals() 오버라이딩 필수
// 사용 조건 2: 저장되는 객체에 hashCode() 오버라이딩 필수
//***hash 라는 단어가 붙은 컬렉션은 반드시 저장되는 객체에
// equals(),hashCode() 오버라이딩 해야함.
set.add("네이버");
set.add("카카오");
set.add("쿠팡");
set.add("당근마켓");
set.add("배민");
set.add("배민");
set.add("배민");
set.add(null);
set.add(null);
set.add(null);
System.out.println(set);
//확인된 것 : 순서 유지 X / 중복 X / null 중복 X
//size() : 저장된 데이터으 개수 반환
System.out.println("저장된 데이터 개수 : "+ set.size());
//remove(String e) : Set에 저장된 객체 중 매개변수 e와
// 필드값이 같은 객체를 제거
System.out.println(set.remove("당근마켓"));
System.out.println(set.remove("라인"));
System.out.println(set);
//Set은 순서가 없어서 저장된 객체 하나를 얻어올 수 있는 방법이 없다!
// -> 대신에 Set 전체의 데이터를 하나씩 반복적으로 얻어올 순 있다!
// 1. Iterator(반복자)
// - 컬렉션에서 제공하는 컬렉션 객체 반복 접근자
//(컬렉션에 저장된 데이터를 임의로 하나씩 반복적으로 꺼내는 역할)
Iterator<String> it = set.iterator();
// Iterator가 얻어온 데이터의 타입은 모두 String임을 알려줌
// set.Iterator() : Set을 Iterator로 하나씩 꺼내갈 수 있는 모양으로 변환
while(it.hasNext()) { // hasNext() : 다음 값이 있으면 true 반환
//if.next() : 다음값(객체)을 얻어옴
System.out.println(it.next());
}
System.out.println("===========================");
//2. 향상된 for문 사용
//for( 하나씩 꺼내서 저장할 변수 : 컬렉션)
for(String temp : set) {
System.out.println( temp );
}
}
public void ex2() {
Set<Member> memberSet = new HashSet<Member>();
memberSet.add(new Member("user01","pass01",30));
memberSet.add(new Member("user01","pass01",30));
memberSet.add(new Member("user02","pass02",25));
for(Member mem : memberSet) {
System.out.println(mem);
}
// Object 의 equals()< hashCode() 오버라이딩
//A.equals(B) : A와 B가 가지고 있는 필드 값이 모두 같으면 true,아니면 false
// Hash 함수: 입력된 단어를 지정된 길이의 문자열로 변환하는 함수(중복 X)
//ex) 입력 : 111 -> "asdfg" (5글자)
//ex) 입력 : 1233242 -> "qwert" (5글자)
//hashCode() : 필드 값이 다르면 중복되지 않는 숫자를 만드는 메서드
// -> 왜 만들까? 빠른 데이터 검색을 위해서 (객체가 어디에 있는지 빨리 찾기 위해서)
// HashSet() : 중복 없이 데이터 저장하고,데이터 검색이 빠름(Hash)
}
public void ex3() {
// Wrapper 클래스 : 기본 자료형 -> 객체로 포장하는 클래스
// - 컬렉션에 기본 자료형값을 저장 할 때 사용
// - 기본 자료형에 없던 추가 기능,값을 이용하고 싶을 때 사용
//<Wrapper 클래스 종류>
// int -> Integer
//char -> Character
// Double,Boolean,Float,Byte,Short,Long
int iNum = 10;
double bNum = 3.14;
//기본 자료형 -> 포장
Integer w1 = new Integer(iNum); //int가 Integer로 포장
Double w2 = new Double(bNum);
// 삭제선 == 해당 구문은 삭제될 예정이다.
// ==> 사용을 권장하지 않는다.
// Wrapper 클래스 활용
System.out.println("int 최대값 : " + w1.MAX_VALUE);
System.out.println("double 최소값 : "+ w2.MIN_VALUE);
// 기울어진 글씨 ? ==static
// static은 클래스명.필드명/클래스명.메소드명()호출 가능
System.out.println("static 방식으로 Wrpper 클래스 사용하기");
System.out.println("int 최대값 : " + Integer.MAX_VALUE);
System.out.println("double 최소값 : "+ Double.MIN_VALUE);
//****************************************************
//parsing : 데이터 형식을 변환
int num1 = Integer.parseInt("100");// 문자열 "100" 을 int 형식으로 변환
double num2 =Double.parseDouble("1.23456");// 문자열 "1.23456" double형식으로 변환
System.out.println(num1 + num2);
}
public void ex4() {
//Wrapper 클래스의 AutoBoxing /AutoUuboxing
Integer w1 = new Integer(100);
Integer w2 = 100;
Integer w3 = 200;
// (Integer) (int -> Integer)자동 포장
//w2와 100은 원래 연산이 안되어야 하지만
//Integer는 int의 포장 형식이라는것을 Java가 인식하고 있어서
// 위와 같은 경우 int를 Integer로 자동 포장해준다.
System.out.println("w2 + w3 = "+ (w2+ w3));
// w2 (Integer 객체)
// w3 (Integer 객체)
// w2 + w3 == 객체+객체 --> 원래는 불가능
// Integer는 int의 포장형태라는걸 java가 인식하고 잇어서
// + 연산 시 포장을 자동으로 벗겨냄
//Integer + Integer -> int + int (자동 포장 해제) (AutoUnboxing)
}
public void lotto() {
//로또 번호 생성기 Version.2
//6개 난수 1~45 사이
// 중복 X
//Set<Integer> lotto = new HashSet<Integer>();
Set<Integer> lotto = new TreeSet<Integer>(); // 자동정렬 Set
//Set<Integer> lotto = new LinkedHashSet<Integer>(); // 순서 유지 Set
//Integer 는 eqauls(), hashCode() 이미 오버라이딩 완료상태
while( lotto.size() < 6) {
//lotto에 저장된 값이 개수가 6개 미만이면 반복
int random = (int)(Math.random()* 45 + 1);
System.out.println(random);
lotto.add(random);
//int값이 자동으로 Integer로 포장되어 lotto에 추가
}
System.out.println("로또 번호 : " + lotto);
}
}
코드(Map)
package edu.kh.collection.model.servuce;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import edu.kh.collection.model.vo.Member;
public class MapService {
//Map : Key 와 Value 한 쌍이 데이터가 되어 이를 모아둔 객체
// - Key를 모아두면 Set의 특징 (중복 X)
// - Value를 모아두면 List의 특징(중복 O)
public void ex1() {
//HashMap<K,V> : Map의 자식 클래스 중 가장 대표되는 Map
Map<Integer, String> map = new HashMap<Integer, String>();
// Map.put(Integer Key,String Value): 추가
map.put(1, "홍길동");
map.put(2, "고길동");
map.put(3, "김길동");
map.put(4, "박길동");
map.put(5, "이길동");
map.put(6, "최길동");
//Key 중복
map.put(1,"홍홍홍"); // 중복허용 X, 대신 value 덮어쓰기
// value 중복
map.put(7, "최길동");
System.out.println(map); //map.toString() 오버라이딩 되어있음.
}
public void ex2() {
//Map 사용 예제
// VO(값 저장용 객체)는 특정 데이터 묶음의 재사용이 많은 경우 주로 사용
// -> 재사용이 적은 VO는 오히려 코드 낭비
// -> Map을 이용해서 VO와 비슷한 코드를 작성할 수 있다.
//1) VO 버전
Member mem = new Member();
//값세팅
mem.setId("user01");
mem.setPw("pass01");
mem.setAge(30);
//값 출력
System.out.println( mem.getId());
System.out.println( mem.getPw());
System.out.println( mem.getAge());
System.out.println("========================");
//) Map 버전
Map<String, Object> map = new HashMap<String, Object>();
// Value가 Object 타입 == 어떤 객체든 Value에 들어올 수 있다.
//값 세팅
map.put("id","uset02");
map.put("pw","pass02");
map.put("age",25);
//값출력
System.out.println( map.get("id"));
System.out.println( map.get("pw"));
System.out.println( map.get("age"));
//**** Map에 저장된 데이터 순차적으로 접근하기 ****
// Map 에서 Key만 모아두면 Set의 특징을 가진다.
// -> 이를 활욜 할 수 잇도록 Map에서
// KeySet() 메서드 제공
// -> Key만 모아서 Set으로 반환
Set<String> set = map.keySet(); // id,pw,age 가 저장된 Set반환
System.out.println("keySet() : " + set);
//향상된 for문
for( String key : set ) {
System.out.println( map.get(key));
}
//map에 저장된 데이터가 많거나
//어떤 key가 있는지 불분명할때
// 또는 map에 저장된 모든 데이터에 접근해야할 때
//keySet() + 향상된 for문 코드 사용
}
public void ex3() {
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
for(int i = 0; i<10; i++) {
//Map 생성
Map<String,Object> map = new HashMap<String, Object>();
//Map에 데이터 추가
map.put("id","user0" + i);
//Map을 List에 추가
list.add(map);
}
//for문 종료 시 List에 10개의 Map 객체가 추가되어있다.
for(Map<String,Object> temp : list) {
System.out.println(temp.get("id"));
}
}
}