고래씌
[JAVA] 14-3. 컬렉션(Collection) - Map 본문
1. Map
▶ 인터페이스 계층구조를 확인해봤을 때 List나 Set 계열은 Collection 인터페이스를 상속받고 있음
ex) 데이터를 추가할 때 전부 동일한 add메소드를 사용함
▶ 단, Map은 다르다. 데이터 추가시 put메소드를 사용(key + value을 세트로 추가)

1) Map의 특징
▶ key, value을 한쌍으로 요소를 구성한다.
▶ key를 통해서 value에 접근해 사용
▶ key는 중복을 허용하지 않는다. value는 중복되어도 좋다.
▶ 동일한 key로 추가 저장하면, 마지막에 추가한 value로 치환됨
▶ 동일한 key값 여부는 hashCode() 반환값으로 판단한다.
[표현법]
Map<String, Snack> hm = new HashMap<>(); |
▶ Map<K, V> : V value 값으로 Snack 객체만을 저장하겠다라고 선언
K key값으로 String자료형 값만을 사용하겠다고 선언

1) put(key, value)
■ Snack 클래스
package com.kh.chap03_hashMap.model.vo;
public class Snack {
private String flavor;
private int calory;
public Snack() {
}
public Snack(String flavor, int calory) {
super();
this.flavor = flavor;
this.calory = calory;
}
public String getFlavor() {
return flavor;
}
public void setFlavor(String flavor) {
this.flavor = flavor;
}
public int getCalory() {
return calory;
}
public void setCalory(int calory) {
this.calory = calory;
}
@Override
public String toString() {
return "Snack [flavor=" + flavor + ", calory=" + calory + "]";
}
}
■ Run클래스
package com.kh.chap03_hashMap.run;
import java.util.HashMap;
import java.util.Map;
import com.kh.chap03_hashMap.model.vo.Snack;
public class Run {
public static void main(String[] args) {
Map<String, Snack> hm = new HashMap<>();
hm.put("다이제", new Snack("초코맛", 1000));
hm.put("칸초", new Snack("초코맛", 600));
hm.put("포카칩", new Snack("짠맛", 500));
hm.put("새우깡", new Snack("짠맛", 500));
// hm.put(1, new Snack()); // 에러 발생. String자료형만 넣기로 했는데 int자료형을 넣어서 에러발생
System.out.println(hm);
// 중복된 key값으로 저장시 value값은 마지막에 등록한 값으로 치환됨
hm.put("새우깡", new Snack("짠맛", 400));
System.out.println(hm);
}
}

☞ hm.put(1, new Snack()); // 에러 발생. String자료형만 넣기로 했는데 int자료형을 넣어서 에러발생
☞ 중복된 key 값으로 저장시 valuer 값이 마지막에 등록한 값으로 치환된 것을 확인
2) get(Object key) : V => 컬렉션에서 해당 키값의 value값을 돌려주는 메소드
package com.kh.chap03_hashMap.run;
import java.util.HashMap;
import java.util.Map;
import com.kh.chap03_hashMap.model.vo.Snack;
public class Run {
public static void main(String[] args) {
Map<String, Snack> hm = new HashMap<>();
hm.put("다이제", new Snack("초코맛", 1000));
hm.put("칸초", new Snack("초코맛", 600));
hm.put("포카칩", new Snack("짠맛", 500));
hm.put("새우깡", new Snack("짠맛", 500));
hm.put("새우깡", new Snack("짠맛", 400));
System.out.println(hm.get("다이제"));
}
}

3) size() => 컬렉션에 담겨있는 개수
System.out.println("size : " +hm.size());

4) replace(K key, V value) => 컬렉션에 해당 key값을 찾아서 새로 전달된 value으로 변경시켜주는 메소드
hm.replace("포카칩", new Snack("트리플치즈", 1000));
System.out.println(hm);

☞ replace -> put으로 한다면 똑같은 key 값이 있다면 변경이 되지만,
☞ replace의 경우, key이 다른 것을 입력했다면 추가가 안되지만, put은 추가됨
5) remove(Object key) : 컬렉션에서 해당 key 값을 찾아서 지워주는 메소드
hm.remove("새우깡");
System.out.println(hm);
☞ 새우깡 key값과 value 값이 삭제됨
2. 순차적으로 HashMap에 담겨있는 값들에 접근하고자 할 때?
▶ keySet() : key값들을 set에 담아서 반환.["다이제","포카칩","칸초","새우깡"]
▶ entrySet() : key, value 한쌍을 set에 담아서 반환 ["다이제"=Snack, "포카칩"=Snack, ...]
※ 향상된 반복문 사용불가 => 향상된 반복문에는 배열, Collection 인터페이스를 구현한 클래스만 들어올 수 있음
☞ for( ? : hm) => X
※ List와 Map은 ★서로 다른 계열!!!★ 이기 때문에 ArrayList에 담아줄수가 없음
☞ new ArrayList(hm); => X
※ iterator()는 Collection의 추상메소드이기 때문에 사용 불가
=> 따라서 반복문을 돌리기 위해서는 keySet 혹은 entrySet을 통해 Set계열로 변환을 한 후 반복해야함
1) keySet()을 이용하는 방법
① hashMap의 Key 값들만 모아서 Set에 담아서 반환해줌
Set<String> keySet = hm.keySet(); // ["다이제","포카칩","칸초"]
② 1번과정에서 작업된 keySet을 Iterator에 담기
// keySet.iterator()
Iterator<String> itKey = keySet.iterator();
Iterator<String> itKey2 = hm.keySet().iterator(); // 1번 과정 생략
③ 반복자에 담긴 것들을 순차적으로 뽑기
while(itKey.hasNext()) {
String key = itKey.next();
Snack value = hm.get(key);
System.out.println("key : " + key);
System.out.println("value : " + value);
}

2) entrySet()을 이용하는 방법
① hm에 있는 key + value 값을 모두 묶어서 Set에 담은 후 반환
Iterator itEntry = hm.entrySet().iterator();
② 반복문을 활용해서 순차적으로 값을 출력
while(itEntry.hasNext()) {
// itEntry.next()는 Object로 되어 있기 때문에 Entry로 다운캐스팅을 해주어야 함
Entry entry = (Entry)itEntry.next();
System.out.println("key : " + entry.getKey());
System.out.println("value : " + entry.getValue());
}

☞ itEntry.next()는 Object로 되어 있기 때문에 Entry로 다운캐스팅을 해주어야 함

3. Properties
▶ Map 계열 => key, value 세트로 저장
▶ 단, Porperties의 특징은 key, value을 모두 String으로 제한함.
▶ 파일 입출력 메소드를 지원함
▶ 설정정보를 표현하는데 있어 최적의 형태를 가지고 있음
Properties prop = new Properties(); |
Q. prop에 String자료형이 아닌 값을 추가하게 될 경우?
=> Map계열 구현클래스이기 때문에 put메소드를 통해 key+value 추가 가능
package com.kh.chap04_Properties.run;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
import com.kh.chap03_hashMap.model.vo.Snack;
public class PropertiesRun1 {
public static void main(String[] args) {
Properties prop = new Properties();
prop.put("다이제", new Snack("초코", 1300));
System.out.println(prop);
System.out.println(prop.get("다이제"));
}
}

☞ 출력은 잘 되는 것을 확인.
☞ Properties를 사용하는 경우는 Properties 내부의 key값 value 값들을 묶어서 파일로 기록하거나, 기록된 내용을 읽어들일때만 사용됨.
☞ 이때 기록하고자 하는 파일에 문자열이 아닌 값이 존재하는 경우 기록 불가능
Properties prop = new Properties();
prop.put("다이제", new Snack("초코", 1300));
System.out.println(prop);
System.out.println(prop.get("다이제"));
try {
prop.store(new FileOutputStream("test.properties"), "Properties test");
} catch (IOException e) {
e.printStackTrace();
}

1) setProperty(String key, String value)
=> Properties에 값을 추가할 때는 put를 잘 사용안함
=> 잘못된 자료형의 값을 추가할 수 있기 때문
Properties prop = new Properties();
prop.setProperty("List", "ArrayList, Vector, LinkedList");
prop.setProperty("Set", "HashSet, TreeSet");
prop.setProperty("Map", "HashMap, Properties");
prop.setProperty("Map", "TreeMap");
System.out.println(prop); // 저장순서 유지 X, key값 중복 허용하지 않음

☞ 저장순서 유지 X, key값 중복 허용하지 않음
2) getProperty(String key)
System.out.println(prop.getProperty("Set"));

3) store( OutputStream os, String comments ) Properties 에 담긴 key-value값들을 파일로 출력
: Properties 객체 내부의 데이터를 기록하는 방법
prop.setProperty("List", "ArrayList, Vector, LinkedList");
prop.setProperty("Set", "HashSet, TreeSet");
prop.setProperty("Map", "HashMap, Properties");
prop.setProperty("Map", "TreeMap");
// Properties 객체 내부의 데이터를 기록하는 방법
// 3. store( OutputStream os, String comments ) Properties 에 담긴 key-value값들을 파일로 출력
try {
prop.store(new FileOutputStream("test.properties"), "Properties test 1");
} catch (IOException e) {
e.printStackTrace();
}

4) storeToXML(OutputStream os, String comments) - xml문서에 출력
prop.setProperty("List", "ArrayList, Vector, LinkedList");
prop.setProperty("Set", "HashSet, TreeSet");
prop.setProperty("Map", "HashMap, Properties");
prop.setProperty("Map", "TreeMap");
try {
prop.storeToXML(new FileOutputStream("test.xml"), "xml test 1");
} catch (IOException e) {
e.printStackTrace();
}


5) load(InputStream is)
: 파일 내부를 읽어오는 것
package com.kh.chap04_Properties.run;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesRun2 {
public static void main(String[] args) {
Properties prop = new Properties();
System.out.println("읽기 전 : " + prop);
try {
// 5. load(InputStream is)
prop.load(new FileInputStream("test.xml"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("읽은 후 " + prop);
}
}

6) loadFromXml(InputSteam is) : xml형태의 데이터를 읽어들일때 사용
package com.kh.chap04_Properties.run;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesRun2 {
public static void main(String[] args) {
Properties prop = new Properties();
System.out.println("읽기 전 : " + prop);
try {
// 6. loadFromXml(InputSteam is) : xml형태의 데이터를 읽어들일때 사용
prop.loadFromXML(new FileInputStream("test.xml"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("읽은 후 " + prop);
}
}

7) 요소 가져오기
: key 값을 넣으면 그 안에 value 값이 출력됨
package com.kh.chap04_Properties.run;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesRun2 {
public static void main(String[] args) {
Properties prop = new Properties();
try {
// 5. load(InputStream is)
// prop.load(new FileInputStream("test.xml"));
// 6. loadFromXml(InputSteam is) : xml형태의 데이터를 읽어들일때 사용
prop.loadFromXML(new FileInputStream("test.xml"));
} catch (IOException e) {
e.printStackTrace();
}
// 1. 요소 가져오기
String map = prop.getProperty("Set"); // 대소문자 구별함
System.out.println(map);
}
}

☞ 만약 요소를 가져올 때 Set이 아닌 "set"을 넣어준다면 null 이 출력됨. => 대소문자 구별
※ 정리
☞ .properties 사용하는 경우는
☞ 해당 프로그램이 기본적으로 가져야할 설정정보들을 .properties 확장자 문서로 저장해두면 key값, value값 모두 문자열로 이루어져있어서 개발자가 아닌 일반관리자가 문서를 다루기에 편하다.
☞ 개발자와 일반관리자가 협업을 하기에 좋은 도구임
☞ jdbc시간 이후에 다시 한번 사용할 예정
☞ .xml 사용하는 경우는
☞ db에서 실행할 쿼리문을 기록할 때 사용할 예정이며, 그 외에도 다른 프로그래밍 언어와 호환성이 좋기때문에 가장 보편적으로 사용되는 파일 형태임
'JAVA > JAVA 기초' 카테고리의 다른 글
[JAVA] Map - Member 실습 문제 (0) | 2023.10.26 |
---|---|
[JAVA] Set 실습 문제 - Lottery (0) | 2023.10.25 |
[JAVA] 14-2. 컬렉션(Collection) - Set (0) | 2023.10.25 |
[JAVA] ArrayList - Music 실습 문제 (0) | 2023.10.24 |
[JAVA] 14-1. 컬렉션(Collection) - ArrayList (0) | 2023.10.24 |