JAVA

[자바/JAVA] 프로그래밍 - Map (HashMap, Properties)

21종 2023. 6. 20. 19:19

Snack Class

package com.kh.chap03_map.part01_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 + "]";
	}
	
}

계층 구조를 보면 
List 계열, set 계열의 클래스들은 collection 구현한 클래스다.
=> 객체를 추가하고자 할 때  공통적으로 add 메소드 이용!

Map 계열은 Collection 을 구현한 클래스가 아님!
=> 추가하고자 할 때 put 메소드 이용 (이때 key + value 세트로 담아야됨!)


1. put(K key, V value) : 컬렉션에 키 벨류 세트로 추가시켜주는 메소드

HashMap hm = new HashMap();

hm.put("다이제", new Snack("초코맛", 1500));
hm.put("칸초", new Snack("단맛", 600));
hm.put("새우깡", new Snack("짠맛", 500));

hm.put("포테이토칩", new Snack("짠맛", 500));

System.out.println(hm);	// {키=벨류, 키=벨류}

저장되는 순서 유지 안됨! value 값이 중복되도 키 값이 중복안되면 잘 저장됨!

hm.put("새우깡", new Snack("매운맛", 700));
System.out.println(hm);

동일한 키값으로 다시 추가하는 경우 value 값이 덮어 씌워짐!! (중복된 키값 공존할 수 없음!! 키 값이 식별자 같은 개념!!)

 

2. get(object key) : V => 컬렉션에서 해당 키값을 가지는 Value 값을 반환시켜주는 메소드

Snack s = (Snack)hm.get("다이제");
System.out.println(s);

 

3. size() : 컬렉션에 담겨있는 객체들의 개수 반환

System.out.println("몇개 있을까 ? : " + hm.size() + "개 있음");

 

4. replace(K key, V value) => 컬렉션에서 해당 키값을 찾아서 다시 전달한 value값으로 수정시켜주는 메소드

hm.replace("포테이토칩", new Snack("겁나 짠맛", 1000));	// 없는 키값 제시시 무시함
System.out.println(hm);

 

5. remove(Object key) => 컬렉션에서 해당 키 값 찾아서 그 키-벨류 세트로 삭제시켜주는 메소드

hm.remove("포테이토칩");
System.out.println(hm);


map 공간에 모든 키값과 벨류값 다 출력하고자 할 때

밑에 얘네들 안된다..

// for each(향상된 for문)문 안됨!
for(Object o : hm) {

}

 

// ArrayList도 안됨!!
ArrayList list = new ArrayList(hm);	// HashMap은 컬렉션이 아니라서 안됨
// Iterator 반복자 이용
Iterator it = hm.iterator();	// 곧바로 iterator() 호출 못함! 왜? iterator()는 List계열 또는 Set 계열에서만 쓸 수 있는 메소드

 

Map을 Set으로 바꿔주는 메소드 제공함!! (게다가 2개나..)

Map계열 => Set계열

 

1. keySet() 메소드 이용하는 방법

// 1-1) hm에 있는 키들만 Set에 담기(키들의 집합형태)
Set keySet = hm.keySet();
		
// 1-2) 1번 과정에서 작업된 keySet을 Iterator에 담기
//keySet.iterator() : Iterator
Iterator itkey = keySet.iterator();

// 1-3) 반복문을 통해 뽑기
while(itkey.hasNext()) {
    String key = (String)itkey.next();
    Snack value = (Snack)hm.get(key);
    System.out.println(key + "=" + value);
}


2. entrySet() 메소드 이용하는 방법

// 2-1) hm.entrySet() : Set
Set entrySet = hm.entrySet();

// 2-2) entrySet.iteratot() : Iterator
Iterator itEntry = entrySet.iterator();

// 2-3) 반복문을 통해 가져오기
while(itEntry.hasNext()) {
    Entry entry = (Entry)itEntry.next();
    String key = (String)entry.getKey();
    Snack value = (Snack)entry.getValue();
    System.out.println(key + "=" + value);
}


Properties : Map 계열의 컬렉션 => 키 + 벨류 세트로 저장

HashMap과의 차이점 : Properties에는 키값도 String, 벨류도 String 으로 담음!!

Properties prop = new Properties();

prop.put("다이제", new Snack("초코맛", 1500));	// value값이 Snack 형임, 나중에 파일 입출력할때 오류남
prop.put("새우깡", new Snack("짠맛", 500));

System.out.println(prop);
System.out.println(prop.get("다이제"));	// get메소드 이용 가능!!

 

하지만 properties 사용하는 경우 주로 Properties에 담긴 것들을 파일로 출력 또는 입력 받아 올 때 사용함!
즉, Properties에서 제공하는 store(), load() 메소드를 사용하기 위해서

 


ClassCastException 오류

try {
    prop.store(new FileOutputStream("test.properties"), "properties Test");
    // ClassCastException
    // 내부적으로 store 실행시 Properties에 담겨있는 키 + 벨류 세트로 String 형변환해서 출력함
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

파일 만들어서 출력해보기

Properties prop = new Properties();

// 1. setProperty(String key, String value)
prop.setProperty("List", "ArrayList");
prop.setProperty("Set", "HashSet");
prop.setProperty("Map", "HashMap");
prop.setProperty("Map", "properties");

System.out.println(prop);	// 저장 순서 유지 안됨, key값 중복시 덮어씌워짐

// 2. getProperty(String key) : String 
System.out.println(prop.getProperty("List"));
System.out.println(prop.getProperty("새우깡"));	// 존재하지 않는 키값 제시하면 null 반환

try {
    // 3. store(OutputStream os, String comments) : Properties에 담겨있는 key - value 값들을 파일로 출력
    prop.store(new FileOutputStream("test.properties"),"properties Test");

    // 4. storeToXML(OutputSteam os, String comments)
    prop.storeToXML(new FileOutputStream("test.xml"), "properties Test");

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

파일은 새로고침하면 생긴다.


txt 파일읽기

Properties prop = new Properties();

try {
    // 5. load()

    prop.load(new FileInputStream("test.properties"));
    System.out.println(prop);

    // 6. loadFromXML(InputStream is);
    prop.loadFromXML(new FileInputStream("test.xml"));


} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

 

xml파일읽기

Properties prop = new Properties();

try {

    // 6. loadFromXML(InputStream is);
    prop.loadFromXML(new FileInputStream("test.xml"));

} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

System.out.println(prop);

 

 * proterties 를 사용하는 경우
 프로그램상에 필요한 기본 환경설정 관련한 문구를 기술하는 경우
 => 모두 문자열이기 때문에 개발자가 아닌 일반 관리자가 해당 문서를 파악해서 수정하기 쉽다.