티스토리 뷰
1. Map 컬렉션
- 특징 :
- 1 ) 키(Key)와 값(Value)으로 구성된 Map.Entry 객체를 저장하는 구조이다.
- 2 ) 키와 값은 모두 객체이며, 키는 중복될 수 없지만 값은 중복이 가능하다.
- 키로 접근해서 값을 추출하기에 순서의 개념이 존재하지 않는다.
- Set과 비슷하게 hashCode와 equals로 중복을 판단하게 된다.
- 구현 클래스 : HashMap, Hashtable, LinkedHashMap, Properties, TreeMap
2. HashMap ( P.742 )
- Map <K, V> map = new HashMap< > ( ) ;
- K는 key 값 타입, V는 value 값 타입을 의미한다.
- Set과 비슷하게 hashCode와 equals로 중복을 판단하게 된다.
- 키 타입은 String 타입을 많이 사용힌다.
3. Hashtable
- HashMap과 대체적으로 비슷하지만, Hashtable은 복수의 스레드가 동시에 Hashtable에 접근해서 객체를 추가하거나 삭제하더라도 스레드에 안전하다는 다른 특징을 지니고 있다.
4. Properties
- 특징 : 키와 값을 String 타입으로 제한한 Map 컬렉션
- Properties는 프로퍼티(xxx.properties) 파일(설정 파일)을 읽어 들일 때 주로 사용된다.
- 프로퍼티(xxx.properties) 파일 : 키와 값이 “ = “ 기호로 연결되어 있는 텍스트 파일
- + 프로퍼티 파일에서 한글은 유니코드로 변환되어 저장된다.
5. Tree ( 검색 기능을 강화한 컬렉션 )
- 종류 : TreeSet , TreeMap ( 이진 트리를 사용하기 때문에 검색속도가 향상된다. )
- 이진 트리 구조 :
- 부모 노드와 자식 노드로 구성된다.
- 자식 노드에서 왼쪽 자식 노드는 부모보다 적은 값, 오른쪽 자식 노드는 부모보다 큰 값을 넣게 된다.
- 이진 트리가 균형감있게 나아갈 수 있도록 하는 것이 좋다.
- 정렬하는 방법 :
- 1 ) 오름차순 : 왼쪽 노드 - > 부모 노드 - > 오른쪽 노드
- 2 ) 내림차순 : 오른쪽 노드 - > 부모 노드 - > 왼쪽 노드
6. TreeSet
- 특징 : 이진 트리를 기분으로 한 Set 컬렉션으로, 왼쪽과 오른쪽 노드를 참조하기 위한 2개의 변수로 구성되어 있다.
- 특정 객체를 찾는 메소드 : first( ) – 가장 작은 값, last ( ) – 가장 큰 값, lower( ) – 지정한 값보다 작은 값, higher ( ) – 지정한 값보다 큰 값
01. HashSet 1
package hash_set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashExample1 {
public static void main(String [] args) {
Set <String> set = new HashSet<String>();
set.add("JAVA");
set.add("JDBC");
set.add("Servlet/JSP");
set.add("Java");
set.add("iBATIS");
// ===============================================
int size = set.size();
System.out.println(" 총 객체수 : " + size);
// ===============================================
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println("\t" + element);
// iterator.remove(); (***) : 돌아가는 도중에 삭제할 수 있다.
} // while
// 출력 :
// JAVA
// Java
// JDBC
// Servlet/JSP
// iBATIS
// ===============================================
set.remove("JDBC");
set.remove("iBATIS");
// ===============================================
System.out.println("삭제 후 총 객체 수 : " + set.size());
for(String element : set) {
System.out.println("\t" + element);
} // for
// ===============================================
set.clear(); // 공통적으로 사용 : 리스트를 비우는 코드
if(set.isEmpty()) {System.out.println("비어있습니당");}
} // main
} // end class
02. HashSet 2
package hash_set;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
@AllArgsConstructor
public class Member extends Object { // HashCode - 중복값 확인
// Set계열과 Map계열의 키는 중복 값을 허용하지 않기에 값이 들어가 있는지 확인해야 한다.
public String name;
public int age;
// ===========================================
// 아래의 코드는 @EqualsAndHashCode가 대체할 수 있다!!(******)
// @Override
// public boolean equals(Object obj) { // 2. equals - 다시 한번 이름과 나이가 같은지 확인한다.
//
// if( obj instanceof Member) {
// Member member = (Member) obj;
// return member.name.equals(name) && (member.age == age);
// } else {
// return false;
// } // if - else
//
// } // equals
//
// @Override
// public int hashCode() {
// return name.hashCode() + age;
// }// 1. hashCode - 이름과 나이를 붙여서 유니크한 값(OID)을 가지게 한다.
} // end class
package hash_set;
import java.util.HashSet;
import java.util.Set;
import lombok.EqualsAndHashCode;
public class HashExample2 {
public static void main(String [] args) {
Set <Member> set = new HashSet<Member>();
set.add(new Member("홍길동",30));
set.add(new Member("홍길동",30)); // 위와 동일한 값을 가지고 있기에 2번째 것은 들어가지 않는다. ( 중복판단 )
// 이는 @EqualsAndHashCode의 영향으로 이것을 작성하지 않는다면 중복된 값이라도 저장되게 된다.
System.out.println(" 총 객체 수 : " + set.size());
} // main
} // end class
03. HashMap
package map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class HashMapExample {
public static void main (String [] args) {
// Map<k,v> 컬렉션 저장
Map<String, Integer> map = new HashMap<>();
// ==================================================================
// 객체 저장
map.put("신용권", 85);
map.put("홍길동", 90); // 키 중복
map.put("동장군", 80);
map.put("홍길동", 95); // 키 중복 - > 키가 중복되기에 들어가지 못한다.
System.out.println(" 총 Entry 수 : " + map.size());
System.out.println();
// 출력 : 총 Entry 수 : 3
// ==================================================================
// 객체 찾기
System.out.println(" > > 홍길동 : " + map.get("홍길동"));
System.out.println();
// 출력 : > > 홍길동 : 95 ( key는 중복이라서 못들어가지만, value는 나중의 것이 대체한 것을 알 수 있다. ** )
// ==================================================================
// 객체를 하나씩 처리 (****)
// Map 컬렉션에 있는 모든 요소들의 키(key)만 뽑아서, set<key> 객체로 되돌려 준다.
Set<String> keySet = map.keySet(); // import문!!
Iterator<String> keyIterator = keySet.iterator(); // 외부반복자 Iterator를 이용한 순회(***)
while(keyIterator.hasNext()) { // 그 다음 객체가 남아있는지 확인
String key = keyIterator.next();
Integer value = map.get(key); // Key를 통해서 Value값 추출하기
System.out.println("\t" + key + " : " + value);
} // while
System.out.println();
// 출력 :
// 홍길동 : 95
// 신용권 : 85
// 동장군 : 80
// ==================================================================
// 객체를 하나씩 처리 ( enhanced for 버전)
for( String key : map.keySet()) {
Integer value = map.get(key);
System.out.println("\t" + key + " : " + value);
} // enhanced for
System.out.println();
// 출력 :
// 홍길동 : 95
// 신용권 : 85
// 동장군 : 80
// ==================================================================
//객체 삭제
map.remove("홍길동");
System.out.println(" 총 Entry 수 : " + map.size());
System.out.println();
// 출력 : 총 Entry 수 : 2
// ==================================================================
// 객체를 하나씩 처리
Set<Map.Entry<String, Integer>> entrySet = map.entrySet(); // 키와 값으로 구성된 Map.Entry 객체를 Set에 담아서 리턴
Iterator<Map.Entry<String, Integer>> entryIterator = entrySet.iterator();
while(entryIterator.hasNext()) {
Map.Entry<String, Integer> entry = entryIterator.next();
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("\t" + key + " : " + value);
} // while
System.out.println();
// 출력 :
// 신용권 : 85
// 동장군 : 80
// ==================================================================
// 객체 전체 삭제
map.clear(); // 힙 영역 관리를 위해서 꼭 해야한다!!
map.isEmpty(); // 비어 있는지 boolean 값으로 받는다.
System.out.println(" 총 Entry 수 : " + map.size());
// 출력 : 총 Entry 수 : 0
} // main
} // end class
04. HashMap 2 - 중복이 가능한지 확인
package map;
import java.util.HashMap;
import java.util.Map;
public class HashMapExample2 {
public static void main (String [] args) { // HashMap의 중복확인
// 다형성 1
Map<Student,Integer> map = new HashMap<>();
map.put(new Student(1, "홍길동"), 95);
map.put(new Student(1, "홍길동"), 80);
System.out.println("총 Entry 수 : " + map.size());
// 출력 : 총 Entry 수 : 1
// Student에서 작성한 @EqualsAndHashCode가 중복을 방지해 준다.
// ---------------------------------------------------------------
System.out.println(map);
// 출력 : {Student(sno=1, name=홍길동)=80}
} // main
} // end class
05. Hashtable
package map;
import java.util.Hashtable;
import java.util.Map;
import java.util.Scanner;
public class HashtableExample { // Hashtable
public static void main(String[] args) {
// Hashtable : HashMap과 내부 구현은 같으나, 차이점은 Thread-safe다.
Map<String,String> map = new Hashtable<>();
// ===============================================
// 객체 저장
map.put("spring", "12");
map.put("sumer", "123");
map.put("fall", "1234");
map.put("winter", "12345");
System.out.println(map);
// 출력 : {sumer=123, spring=12, winter=12345, fall=1234}
// ===============================================
Scanner scanner = new Scanner(System.in);
while(true) {
// 입력받기 위한, 프롬프트(prompt) 메세지 출력
System.out.println("아이디와 비밀번호를 입력해주세요.");
System.out.print("아이디 : ");
String id = scanner.nextLine();
System.out.print("비밀번호 : ");
String password = scanner.nextLine();
System.out.println();
// User Authentication ( 사용자 인증 )
if(map.containsKey(id)) { // 입력한 ID가 존재하는 가
if(map.get(id).equals(password)) { // 입력한 암호도 일치
System.out.println("로그인이 되었습니다.");
break; // 무한루프 탈출조건
} else {
System.out.println("아이디와 비밀번호가 일치하지 않습니다.");
} // inner if-else
} else {
System.out.println("입력하신 아이디가 존재하지 않습니다.");
}// outer if-else
} // while
// ===============================================
// 출력 1 :
// 아이디와 비밀번호를 입력해주세요.
// 아이디 : spring
// 비밀번호 : 12
//
// 로그인이 되었습니다.
// ===============================================
// 출력 2 :
// 아이디와 비밀번호를 입력해주세요.
// 아이디 : spring
// 비밀번호 : 123456
//
// 아이디와 비밀번호가 일치하지 않습니다.
// 아이디와 비밀번호를 입력해주세요.
// 아이디 :
// ===============================================
} // main
} // end class
06. Properties
option1=value1
option2=\uD55C\uAE00
option3=value3
package map;
import java.io.FileReader;
import java.net.URLDecoder;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class PropertiesExample {
public static void main(String[] args) throws Exception { // Properties (*****)
// 1. properties map 객체 생성
Properties properties = new Properties();
// =================================================
// 2. 지정된 xxx.properties 파일을 로딩하여,
// 1에서 생성한 Properties map 객체로 저장한다.
// getResource를 보면 URL java.lang.Class.getResource(String name(properties의 파일이름))라고 설명되고 있음을 알 수 있다. (****)
String path = PropertiesExample.class.getResource("TTT.properties").getPath(); // clazz객체 생성
// 이는 "TTT.proprtties"에 대한 URL을 준다는 것을 알 수 있다.
// properties 파일은 설정 파일이라고 생각하면 편하다.
System.out.println("1. path : " + path);
// 출력 : path : /C:/app/workspace/JSE/project1/bin/map/TTT.properties
// TTT.properties의 위치를 보여주고 있음을 알 수 있다.
path = URLDecoder.decode(path, "utf-8");
System.out.println("2. path : " + path);
// 출력 : 2. path : /C:/app/workspace/JSE/project1/bin/map/TTT.properties
properties.load(new FileReader(path)); // 로딩 및 Map에 저장!! (***)
// 파일 리더(FileReader)로 path에 있는 경로를 읽어낸다.
// =================================================
// + Clazz객체를 얻어내는 방법 3가지 :
// (1) 타입명.class 속성을 이용하는 방법
Class clazz1 = PropertiesExample.class;
// (2) 참조타입변수명.getClass() 을 이용하는 방법
Class clazz2 = properties.getClass();
// (3) FQCN 이름과 Class.forName(FQCN을 작성)를 이용하는 방법 ( FQCN은 fullname이다.)
Class clazz3 = Class.forName("java.util.Properties");
System.out.println("1. clazz1 : " + clazz1);
System.out.println("2. clazz2 : " + clazz2);
System.out.println("3. clazz3 : " + clazz3);
// 출력 :
// 1. clazz1 : class map.PropertiesExample // PropertiesExample의 clazz이고,
// 2. clazz2 : class java.util.Properties
// 3. clazz3 : class java.util.Properties // 위의 2개는 Properties properties의 clazz이다.
// =================================================
// clazz객체 비교
System.out.println("4. clazz1 == clazz3 : " + (clazz1 == clazz3));
System.out.println("5. clazz2 == clazz3 : " + (clazz2 == clazz3));
System.out.println();
// 출력 :
// 4. clazz1 == clazz3 : false
// 5. clazz2 == clazz3 : true
// =================================================
// 3. Properties 맵 객체에 저장된 개별 속성(properties)를 사용
// 이때 Properties에 있는 getProperty(속성명) 메소드를 호출해서 값을 얻어낸다.
String value1 = properties.getProperty("option1");
String value2 = properties.getProperty("option2");
String value3 = properties.getProperty("option3");
// String java.util.Properties.getProperty(String key)을 보아
// getProperty는 무조건 String타입으로 돌려준다는 것을 알 수 있다.
// 출력 :
// option1 : value1
// option2 : 한글
// option3 : value3
// properties 파일에서는 유니코드로 바뀌었던 한글이 다시 한글로 바뀌어 출력된 것을 볼 수 있다.
// =================================================
// 4. 얻어낸 각 속성값을 출력
System.out.println("option1 : " + value1);
System.out.println("option2 : " + value2);
System.out.println("option3 : " + value3);
} // main
} // end class
07. TreeSet
package TreeSet;
import java.util.TreeSet;
public class TreeSetExample { // TreeSet
// TreeSet은 이진 트리를 통해, 요소를 미리 정렬시켜주고
// 정렬된 데이터를 이용해서, 빠른 검색을 해주는 장점이 있다!!(**)
public static void main (String [] args) {
TreeSet<Integer> scores = new TreeSet<Integer>();
// =========================
// Auto-Boxing
scores.add(87);
scores.add(98);
scores.add(75);
scores.add(95);
scores.add(80);
// scores.add(new Integer(100)); : 구버전
System.out.println(scores);
// 출력 : [75, 80, 87, 95, 98] < - - 데이터를 자동으로 정렬해 준다.
// =========================
Integer score = null;
score = scores.first(); // 가장 작은 값을 의미한다.
System.out.println("가장 낮은 점수 : " + score);
// =========================
score = scores.last(); // 가장 큰 값을 의미한다.
System.out.println("가장 높은 점수 : " + score + "\n");
// =========================
score = scores.lower(95);
System.out.println("95점 바로 아래의 점수 : " + score);
// 95점 바로 아래의 점수 : 87
// =========================
score = scores.higher(95);
System.out.println("95점 바로 위의 점수 : " + score);
// 95점 바로 위의 점수 : 98
// =========================
score = scores.floor(95);
System.out.println("95점이거나 바로 아래의 점수 : " + score);
// 95점이거나 바로 아래의 점수 : 95
// =========================
score = scores.ceiling(85);
System.out.println("85점이거나 바로 위의 점수 : " + score);
// 85점이거나 바로 위의 점수 : 87
// =========================
while ( !scores.isEmpty() ) { // 전체가 다 빠져나가면 비어버리기 때문에 자동으로 flase가 되어 끝나버린다.
score = scores.pollFirst(); // 첫번째 요소를 빼낸다. ( 아예 TreeSet에서 없애버린다. )
System.out.println(score + " ( 남은 객체의 수 : " + scores.size() + " )");
} // while
// 출력
// 75 ( 남은 객체의 수 : 4 )
// 80 ( 남은 객체의 수 : 3 )
// 87 ( 남은 객체의 수 : 2 )
// 95 ( 남은 객체의 수 : 1 )
// 98 ( 남은 객체의 수 : 0 )
// =========================
} // main
08. TreeSet 2 - 정렬
package TreeSet;
import java.util.NavigableSet;
import java.util.TreeSet;
public class TreeSetExample2 { // TreeSet - 정렬하기
public static void main (String [] args) {
TreeSet<Integer> scores = new TreeSet<Integer>();
// =========================
// Auto-Boxing
scores.add(87);
scores.add(98);
scores.add(75);
scores.add(95);
scores.add(80);
// scores.add(new Integer(100)); : 구버전
System.out.println(scores);
// 출력 : [75, 80, 87, 95, 98] < - - 데이터를 자동으로 오름차순으로 정렬해 준다.
// =========================
// 내림차순(descending)으로 정렬하기
NavigableSet<Integer> descendingSet = scores.descendingSet();
for ( Integer score : descendingSet ) {
System.out.print(score + " ");
} // enhanced for
// 출력 : 98 95 87 80 75
System.out.println();
// =========================
// 오름차순으로 정렬하기 - descendingSet을 한 번 더 해주면 내림차순으로 바꾼 것이 다시 오름차순으로 변경된다.
NavigableSet<Integer> ascendingSet = descendingSet.descendingSet();
for ( Integer score : ascendingSet ) {
System.out.print( score + " ");
} // enhanced for
// 출력 : 75 80 87 95 98
System.out.println();
// =========================
} // main
} // end class
09. TreeSet 3 - 범위 검색 메소드
package TreeSet;
import java.util.NavigableSet;
import java.util.TreeSet;
public class TreeSetExample3 { // TreeSet - 정렬하기
public static void main (String [] args) {
TreeSet<String> treeSet = new TreeSet<String>();
// =========================
// TreeSet은 요소의 차입이 숫자뿐만이 아니라, 아래와 같이 문자열도 이진 트리로 자동정렬이 가능하다.
// 문자열은 사전 순서대로 정렬된다.
// Auto-Boxing
treeSet.add("apple");
treeSet.add("forever");
treeSet.add("description");
treeSet.add("ever");
treeSet.add("zoo");
treeSet.add("base");
treeSet.add("guess");
treeSet.add("cherry");
System.out.println(treeSet);
// 출력 : [apple, base, cherry, description, ever, forever, guess, zoo]
System.out.println();
// =========================
// 범위검색
System.out.println(" [ c ~ f 사이의 단어를 검색 ] ");
NavigableSet <String> rangeSet = treeSet.subSet("cherry", true, "forever", true);
// 정한 범위 내에서 검색한다. 만약 true가 아닌 false로 작성하면 cherry와 forever은 출력되지 않는다.
for ( String word : rangeSet ) {
System.out.println(word);
} // enhanced for
// 출력 :
// [ c ~ f 사이의 단어를 검색 ]
// cherry
// description
// ever
// forever
System.out.println();
// =========================
} // main
} // end class
'KH 정보교육원 [ Java ]' 카테고리의 다른 글
KH 24일차 - 자바 입출력 ( Reader / Writer ) (0) | 2022.03.31 |
---|---|
KH 23일차 - 컬렉션 프레임워크 및 IO (0) | 2022.03.30 |
KH 21일차 - 함수적 인터페이스 및 컬렉션 프레임 워크 (0) | 2022.03.28 |
KH 20일차 - 람다식과 함수적 인터페이 (0) | 2022.03.26 |
KH 19일차 - 제네릭 타입 (0) | 2022.03.25 |