Map은 나중에 JPA Criteria (JPQL) 사용할때 알아둬야하니 공부공부..
ORM와 MyBatis(배우기쉽고 표준적으로 많이씀, 우리나라,중국등 동양쪽에서 많이씀) 도 있음
해싱?
해시 함수를 통해서 일정한 길이의 값을 뽑아 데이터를 저장, 검색
해쉬 테이블은 배열과 링크드 리스트가 조합된 형태이다.
(해싱은.. 보안 포렌식쪽에서만 써봤는데, 자바에서도 쓰이는줄은 몰랐다.)
1. 키로 해쉬함수를 호출해서 해쉬코드(hash code)를 얻는다.
2. 해쉬코드(해쉬함수 반환값)에 대응하는 Linked List를 배열에서 찾는다
3. Linked List에서 키와 일치하는 데이터를 찾는다.
해쉬 테이블은 잘 사용하지 않아 적지 않음
Map 계열 주요 메소드
키와 값을 String 타입으로 제한한 Map 컬렉션
프로퍼티 파일(*.properties) [자세하게 안써봄]
- 옵션정보 , 데이터베이스 연결정보 , 국제화 다국어 정보를 기록하여
텍스트파일로 활용
- 애플리케이션에서 주로 변경이 잦은 문자열을 저장하여 관리하기
때문에 유지보수를 편리하게 만들어 줌
- 키와 값이 기호로 연결되어 있는 텍스트 파일로 ISO 8859-1
문자셋으로 저장되고 , 한글은 유니코드로 변환되어 저장
Treeset
이진 트리 기반 Set 컬렉션
TreeMap
이진트리 기반 Map 컬렉션
키와 값이 저장된 Map.Entry를 저장
좌우 노드 참조를 위한 두개의 변수
기본적으로 오름차순 정렬이며
숫자(Int, Double)의 경우 값으로 정렬
문자열(String)은 유니코드로 정렬
만약 정렬을 위한 java.lang.Comparable을 구현한 객체를 제공하지 않을경우
ClassCastException 에러 발생
내림차순 (따로 구현)
매개변수 생성자를 통해 재정렬
ex) TreeSet<E> tSet
= new TreeSet(Comparator<? super E> comparator);
TreeMap<K, V> tMap
= new TreeMap(Comparator<? super K> comparator);
또는 compareTo()메소드로 오버라이딩
★ 추천: Java에서 정렬하지 말고 DB에서 order by 쿼리를 사용해서 가져오자
Stack
후입 선출(LIFO) 구조로 JVM Stack 메모리가 Stack 구조로 되있음
ex) Stack<e> stack = new Stack<E>();
push(E) : 주어진 객체를 스택에 넣는다
peek() : 스택 맨위 객체를 가져오며 스택을 제거 X
pop() : 맨위 객체를 가져오며 스택을 제거한다.
Queue
선입 선출(FIFO) 구조로 작업큐, 메세지큐가 Queue구조
ex) Queue() queue = new LinkedList();
offer(e) : 객체넣기
peek() : 객체를 하나 가져오고 큐를 제거하지 않는다
poll() : 객체를 하나가져오고 큐를 제거한다.
Deque
큐와 스택의 성질을 모두 가지고 있는 구조로 검색과 같은 반복적인 문제에 특히 유용한 데이터 구조
push, offer, add(e) : 해당 메소드와 메소드 뒤 First, Last를 붙여 앞 뒤에 주어진 객체를 넣음
peek, get() : 해당 메소드 + 메소드 뒤 First, Last를 붙여 객체를 가져온다, 큐를 제거하지않음
poll, remove() : 위와 동일, 큐를 제거함
Arrays
1. 배열의 출력 toString()
2. 다채원 배열의 비교,출력 deepEquals(), deepToSTring(), equals() [잘 안씀]
3. 배열 복사 copyOf(), copyOfRange()
4. 배열 채우기 fill(), setAll()
5. 배열 List로 변환 asList(Object)
6. 배열의 정렬과 검색, sort(), binarySearch()
※ Arrays 말고 컬렉션을 쓰자... 5번 정도만 알아두면 좋을듯
List 글과 같이 Member 클래스를 추가해 준뒤
[MapBasic.java]
package com.multi.ex04.map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class MapBasic {
// Map이란?
// Key - Value로 데이터가 구성되어 있는 컬랙션
// Key는 주로 숫자나 문자 활용, Value는 객체를 활용
// Key 기준으로만 중복확인함 -> Comparable, equals 필요 없음!
// HashMap : 순서 보장 안되고, 제일 빠른 성능, 가장 많이 사용하는 Map. ★★★★★
// LinkedHashMap : Key의 삽입순서 보장. ★
// TreeMap : Key의 문자열로 정렬. ★
// HashTable : HashMap Thread Safe Version ★
// ConcurrentHashMap : Thread safe한 버전의 map인데 가끔 현업에서 사용 ★★★
public static void main(String[] args) {
//기본적인 사용법
Map<String, String> map = new HashMap<>();
map.put("key", "value");
map.put("키", "값");
map.put("PK", "ROW"); //DB경우
System.out.println(map.get("key"));
System.out.println(map.get("키"));
System.out.println(map.get("PK"));
System.out.println("---------------------------------");
Map<String, String> map1= new HashMap<>();
// 객체 활용법
ArrayList<Member> list = new ArrayList<Member>();
list.add(new Member("testID1", "김길동1", 21, 10000.123));
list.add(new Member("testID1", "김길동1", 21, 10000.123)); // 완전동일
list.add(new Member("testID3", "김길동3", 23, 444000.123));
list.add(new Member("testID2", "홍길동3", 41, 3300.123)); // ID 만 다름
list.add(new Member("testID2", "김길동2", 22, 10000.123));
// 선언법
// key value
Map<String, Member> hashMap = new HashMap<String, Member>(); // 일반 Map과 유사함, 1.6버전 이전 문법
Map<String, Member> linkedHashMap = new LinkedHashMap<>(); //
Map<String, Member> treeMap = new TreeMap<>(); //hashMap에 없는 특정 기능이 몇개 있음
// 데이터 삽입
for(Member m : list) {
hashMap.put(m.getId(), m);
}
for(int i = 0; i < list.size(); i++) {
linkedHashMap.put(list.get(i).getId(), list.get(i));
}
list.forEach((m) -> treeMap.put(m.getId(), m));
System.out.println("HashMap");
System.out.println(hashMap.toString());
hashMap.forEach((k,v) -> System.out.println("key : " + k + "," + "value :" + v)); //신식?.. 편함 forEach
System.out.println(hashMap.keySet()); //정석?..
System.out.println(hashMap.size());
System.out.println("----------------------------------------------------------------------");
System.out.println("linkedHashMap"); // 삽입 순서대로 정렬되있음 ID1,ID3,ID2
System.out.println(linkedHashMap.toString());
linkedHashMap.forEach((k,v) -> System.out.println("key : " + k + "," + "value :" + v)); //신식?.. 편함 forEach
System.out.println(linkedHashMap.keySet()); //정석?..
System.out.println(linkedHashMap.size());
System.out.println("----------------------------------------------------------------------");
System.out.println("treeMap"); //key(ID)값 순서대로 정렬
System.out.println(treeMap.toString());
treeMap.forEach((k,v) -> System.out.println("key : " + k + "," + "value :" + v)); //신식?.. 편함 forEach
System.out.println(treeMap.keySet()); //정석?..
System.out.println(treeMap.size());
System.out.println("----------------------------------------------------------------------");
}
}
[MapBasic2.java]
package com.multi.ex04.map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MapBasic2 {
public static void main(String[] args) {
ArrayList<Member> list = new ArrayList<Member>();
list.add(new Member("testID1", "김길동1", 21, 10000.123));
list.add(new Member("testID1", "김길동1", 21, 10000.123)); // 완전동일
list.add(new Member("testID3", "김길동3", 23, 444000.123));
list.add(new Member("testID2", "홍길동3", 41, 3300.123)); // ID 만 다름
list.add(new Member("testID2", "김길동2", 22, 10000.123));
// 선언법
Map<String, Member> map = new HashMap<>();
// 1. 데이터 삽입하는 방법
for(Member m : list) {
// 기본적인 문법
//map.put(m.getId(), m);
// 덮어쓰기 하지 않는 방법 1 ※중요
if(map.get(m.getId()) == null) {
map.put(m.getId(), m);
}
// 덮어쓰기 하지 않는 방법 2
// if(map.containsKey(m.getId()) == false) {
// map.put(m.getId(), m);
// }
// 덮어쓰기 하지 않는 방법 3
// putIfAbsent : 키 값이 존재하지 않을때만 put 하는 메소드
// map.putIfAbsent(m.getId(), m);
}
map.forEach((k,v) -> System.out.println("k :" + k + ", v : " + v));
// 2. 순회하는 방법
// 1) keySet - 표준적인 방법
Set<String> keySet = map.keySet();
for(String key : keySet) {
System.out.println(map.get(key));
}
// 2) entrySet - key-value 둘다 쌍으로 가져오는 방법 (코드라인이 너무 김)
Set<Entry<String, Member>> entrySet = map.entrySet();
System.out.println("---------------------------------------------------------------------------");
// 3) forEach문 활용
map.forEach((k,v) -> System.out.println("k :" + k + ", v : " + v));
// 3. 데이터 가져오는 방법
System.out.println(map.get("testID1")); //key가 있으면 해당 value값출력
System.out.println(map.get("testID34828")); //key가 없으면 null
// getOrDefault : 키값이 없는경우, default값을 선언할 수 있는 기능
System.out.println(map.get("testID1").getId());
//System.out.println(map.get("testId34828").getId()); // 값이 없는경우 null 에러
System.out.println(map.getOrDefault(keySet, new Member()).getId()); // 값이 없는경우 빈멤버를 반환
// getOrDefault 없이 default값 초기화하는 문법 -> if문 필요
Member m = map.get("tsetId34828");
if(m == null) {
m = new Member();
}
System.out.println(m.getId());
// 아래 한줄로도 변환가능
System.out.println(map.getOrDefault(keySet, new Member()).getId());
// 4. 삭제하는 방법
// map.remove("testID1"); //기본적인 삭제 방법
Member m2 = map.remove("testID1"); // 삭제한 객체 받아오기
if(m2 == null) {
System.out.println("삭제 실패");
} else {
System.out.println("삭제된 데이터 : " + m2);
}
// 5. 데이터 수정하는 방법
// - 기본적으로 map은 덮어쓰기로 수정됨 -> put 사용
// - replace 메소드가 있지만 put과 같은 매커니즘임
map.put("testID2", new Member("testID2", "최길동3", 22, 10000.123));
System.out.println(map.get("testID2"));
map.replace("testID2", new Member("testID2", "박길동4", 22, 10000.123));
System.out.println(map.get("testID2"));
// value에 있는 객체에 일부 값만 변경하고 싶을때
// 1. 간편하지만 위험한 방법
map.get("testID2").setId("홍길동");
// 아래 안전한 방법 권장
Member m3 = map.get("testID2");
if(m3 != null) { // ※ null 체크는 필수!
m3.setAge(40);
}
System.out.println(map.get("testID2"));
// 6. map 비우는 방법
map.clear(); // 바로 전부 초기화
map = null; // 똑같이 전부삭제, java JVM - gc가 정리한다.
}
}
[MapBasic3.java]
package com.multi.ex04.map;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class MapBasic3 {
public static void main(String[] args) {
// ID가 중복이 되어도 HashMap으로 유지하는 방법
List<Member> list = new ArrayList<Member>();
list.add(new Member("testID1", "김길동1", 21, 10000.123));
list.add(new Member("testID1", "황길동2", 31, 10000.123));
list.add(new Member("testID1", "충길동3", 51, 10000.123));
list.add(new Member("testID2", "홍길동1", 61, 3300.123));
list.add(new Member("testID2", "고길동2", 32, 10000.123));
list.add(new Member("testID2", "박길동3", 22, 10000.123));
list.add(new Member("testID3", "이길동1", 13, 444000.123));
list.add(new Member("testID3", "김길동2", 23, 444000.123));
list.add(new Member("testID3", "홍길동3", 33, 444000.123));
// 2가지 방법
// 1. key + 다른값을 조합하여 새로운 ID를 만들어 낸다.
// 추천 X -- id + name을 하여 새로운 key값으로 분류한다.
// - id 기준으로 같은 사용자를 뽑거나그럴때 알고리즘이 들어간다는 문제점
// 2. Map + List를 결합하셔 컬렉션을 이중으로 설계하는 방법 ★
// - key 기준으로 List르 ㄹ생성하여 설계하면 된다.
// - map + set + list 이런식으로 3중 ~ 4주 ㅇ컬렉션 조합도 발생하는 경우가 있다
// id Member배열
Map<String, List<Member>> listMap = new TreeMap<>();
// 1. 기본적인 초기화 방법 (간단한 버전)
for(Member m : list) {
String key = m.getId();
if(listMap.get(key) == null) { // key값의 list가 존재하지 않을때 (덮어쓰기 방지)
listMap.put(key, new ArrayList<>()); //초기화
}
listMap.get(key).add(m); //값추가
}
// listMap.forEach((k,v) -> System.out.println(k + ":" + v));
// 출력하는 방법
Set<String> keySet = listMap.keySet();
for(String key : keySet) {
System.out.println("key : " + key);
List<Member> mlist = listMap.get(key);
for(Member m : mlist) {
System.out.println("\t" + m);
}
System.out.println();
}
System.out.println("-----------------------------------------------------------------------------------------------------------------------");
// 2. 발전된 초기화 방법
listMap = new TreeMap<>();
for(Member m : list) {
String key = m.getId();
List<Member> mList = listMap.getOrDefault(key, new ArrayList<Member>()); //빈값이 아니면 추가하기
}
System.out.println(listMap);
// 출력하는 방법
keySet = listMap.keySet();
for(String key : keySet) {
System.out.println("key : " + key);
List<Member> mlist = listMap.get(key);
for(Member m : mlist) {
System.out.println("\t" + m);
}
System.out.println();
}
System.out.println("-----------------------------------------------------------------------------------------------------------------------");
}
}
'자바' 카테고리의 다른 글
[Java] JDBC (Java DataBase Connectivity) (0) | 2023.11.29 |
---|---|
[Java] I/O 입출력 (0) | 2023.11.23 |
[Java] Collections - List (0) | 2023.11.22 |
[Java] Colletions - Set (0) | 2023.11.22 |
[JAVA] Collections - 컬렉션 (0) | 2023.11.22 |