# Run
package com.kh.chap02_set.run;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import com.kh.chap02_set.model.vo.Student;
public class Run {
public static void main(String[] args) {
> HashSet
: Value값만 저장, index의 개념이 없음, 순서보장 x, 중복x
[표현법]
HashSet 객체이름 = new HashSet(); //빈 HashSet
유형1, 문자열
HashSet<String> hs = new HashSet();
System.out.println(hs);//[]
- 값 추가: add(추가할 값)
hs.add("안녕하세요"); //String Pool
hs.add(new String("반갑습니다.")); //새로 공간 할당=>공간낭비
hs.add("여러분");
hs.add("자바 끝났습니다");
hs.add("월요일은 평가날 입니다");
hs.add("반갑습니다."); //=> 중복이 허용되지 않음
//hs.add(new Student()); => 자료형이 달라 실행되지 않음
//String의 특성 상 안에 담긴 문자열을 기반으로 hashcode를 생성하고, equals를 사용했을 때 String의 경우 주소값이 아닌 문자열을 비교하도록 Object의 메소드가 오버라이딩됨.
System.out.println(hs); //저장 순서 보장 x, 중복저장 x** [안녕하세요, 월요일은 평가날 입니다, 자바 끝났습니다, 여러분, 반갑습니다.]
- 크기 구하기 : size()
System.out.println("hs의 크기: " + hs.size()); //5
- 값 삭제: remove(삭제할 값)
hs.remove("월요일은 평가날 입니다");
//인덱스가 없으므로 그대로 값 입력
System.out.println(hs); //=> 삭제됨
- 모든 값 삭제 : clear()
hs.clear();
System.out.println(hs); //=> 모든 값 삭제됨
유형2, Student 객체
HashSet<Student> stds = new HashSet();
stds.add(new Student("홍길동", 15, 100));
stds.add(new Student("김**", 40, 99));
stds.add(new Student("송**", 40, 95));
stds.add(new Student("이**", 34, 25));
stds.add(new Student("김**", 40, 99));
System.out.println(stds);
//[Student [name=이**, age=34, score=25], Student [name=김**, age=40, score=99], Student [name=송**, age=40, score=95], Student [name=홍길동, age=15, score=100]]
Student st = new Student("김**", 15, 100);
Student st2 = new Student("김**", 15, 100);
System.out.println(st.hashCode());
//1378192830
System.out.println(st2.hashCode());
//1378192830
중복저장이 가능한 이유는? => 동일객체로 판단이 되지 않기 때문
- HashSet의 특징: 값이 추가될 때 마다 equals()와 hashcode()로 비교 후 둘 다 결과가 true일 경우 동일객체로 판단
//equals() : 현재 객체의 주소값을 비교해서 결과반환(같으면 true) : boolean
//hashCode() : 현재 객체의 주소값을 해싱 알고리즘을 돌려서 10진수로 반환 : int
System.out.println(st.equals(st2)); //true
* 총정리
: HashSet에 객체를 담을 때 내부적으로 equals 메소드랑 hashCode메소드를 기준으로 값이 일치하는지를 비교하고 담는다.
==equals의 결과가 true이고 (그리고) hashCode의 값도 일치한다면
=> 동일객체로 판단(중복저장을 안 함)
* Object클래스
* equals() : 두 객체의 주소값을 비교해서 일치하면true
* hashCode() : 객체의 주소값을 해싱해서 10진수 형태로 반환
=> 반환한 결과들끼리 비교 => 두 결과가 모두 일치해야만 한다.
=> 내용물은 같은데 주소값이 달라서 동일객체가 아닌 것으로 판단이 되면서 중복저장 => 방지하고 싶다면?
= equals메소드와 hashCode메서드를 오버라이딩해서 사용해야 한다.
* Student 클래스
* hashCode() : 세 필드값을 하나의 문자열로 만들고 해시코드값을 만들어서 반환
* equals() : 세 필드의 값이 모두 일치하면 true
- HashSet에 들어있는 모든 값들을 출력하는 방법
1. 반복문 => 인덱스 개념 but hashCode는 인덱스 개념이 없음
for(Student s : stds) {
System.out.println(s);
} //=> 향상된 for문 사용
2.HashSet의 내용물을 ArrayList에 담아서
//인덱스를 이용해서 출력
1단계) ArrayList객체 생성
ArrayList list = new ArrayList();
2단계) addAll(collection c) 사용 - 전부 추가
list.addAll(stds);
for(int i = 0; i<list.size(); i++) {
System.out.println(list.get(i));
}
1+2단계) 생성과 동시에 초기화
ArrayList<Student> student = new ArrayList(stds);
for(int i = 0; i<list.size(); i++) {
System.out.println(list.get(i));
}
3. Interator(반복자) => HashSet클래스에서 제공
- String의 StringTokenizer과 비슷한 원리
- Set계열과 List계열에서 호출이 가능=> Map계열에서는 바로 호출이 불가능
Iterator it = stds.iterator();
/*
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());
System.out.println(it.next());//NosuchElementException (RunTimeException의 자손)
*/
- hasNext()사용하기*************: //it에 next로 더 빼올 값이 있는지 있으면 true, 없으면 false
while(it.hasNext()) {
System.out.println(it.next());
}
# Student
package com.kh.chap02_set.model.vo;
public class Student {
private String name;
private int age;
private int score;
public Student() {
}
public Student(String name, int age, int score) {
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
}
직접 hashCode()와 equals()를 오버라이딩 해보면,
//hashCode()
@Override
public int hashCode() {
// 객체들의 주소 16진수 어쩌고저쩌고 뭐시뭐시기를해가지고 10진수로 반환
return (name + age + score).hashCode();
// (이름 + 나이 + 점수)
// "김**15100"
// "김**5050"
// (이름 + 나이 + 점수).해싱
}
// equals()
public boolean equals(Object obj) {
Student other = (Student)obj;
// 이름, 나이, 점수
// 셋중에 하나라도 다르면 false값 리턴
if(!this.name.equals(other.name) || this.age != other.age || this.score != other.score) {
return false;
}
// 필드값이 모두다 동일하다면 true값 리턴
return true;
// 결과반환 true / false
}
//hashCode
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + score;
return result;
}
//equals()
@Override
public boolean equals(Object obj) {
//현재 객체(this)와 obj를 비교
if (this == obj) //현재 객체와 비교객체의 주소값이 일치하는가?
return true; // == 같은 곳을 가리키고 있음 == 모든 필드값이 일치
if (obj == null) //비교대상이 null
return false; //비교할 가치가 x
if (getClass() != obj.getClass())//메소드 타입비교
return false;
//위에 세가지 조건을 만족하지 않았을 경우
//각 내용물을 다 비교
Student other = (Student) obj;
if (age != other.age) //현재 객체랑 들어온 객체랑 나이가 다른 경우
return false;
if (name == null) { //현재 객체 이름값이 null일 경우
if (other.name != null) //비교 객체 이름 값이 null이 아닐 경우
return false;
} else if (!name.equals(other.name)) //현재 객체이름과 비교객체 이름이 다를 경우
return false;
if (score != other.score) //점수가 달라도
return false;
//모든 경우를 빗겨나갔을 경우에는 true
return true;
}
}
# Map
- Vo
package com.kh.chap03_map.chap03_map.part01_hashMap.model.vo;
public class Burger {
private String flavor; //맛
private int calorie;//열량
public Burger() {
}
public Burger(String flavor, int calorie) {
this.flavor = flavor;
this.calorie = calorie;
}
public String getFlavor() {
return flavor;
}
public void setFlavor(String flavor) {
this.flavor = flavor;
}
public int getCalorie() {
return calorie;
}
public void setCalorie(int calorie) {
this.calorie = calorie;
}
@Override
public String toString() {
return "Burger [flavor=" + flavor + ", calorie=" + calorie + "]";
}
}
- Run
package com.kh.chap03_map.chap03_map.part01_hashMap.run;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import com.kh.chap03_map.chap03_map.part01_hashMap.model.vo.Burger;
public class Run {
public static void main(String[] args) {
> hashMap
[표현법]
HashMap 이름 = new HashMap();
key + value 세트로 추가
//key == 식별자 =>버거 이름
//value == 값 =>맛, 열량
HashMap<String, Burger> hm = new HashMap();
//key, 클래스자료형
//비어있는 해시 맵에 추가해보자
- ArrayList, HashSet => add()
-> List계열 Set계열 Collection을 구현한 클래스
//HashMap => put() - Map계열
// => key + value 세트로 추가
1. put(K key, V value) : 맵공간에 key + value 세트 추가
hm.put("싸이버거", new Burger("바삭바삭한 맛", 400));
hm.put("와퍼", new Burger("근본있는맛", 550));
hm.put("상하이 스파이시 버거", new Burger("매콤한맛", 360));
hm.put("블랙오징어버거", new Burger("매운맛", 350));
hm.put("징거버거", new Burger("징거버거맛", 350));
hm.put("88서울비프버거", new Burger("부드럽고 고소한 에그 양배추 샐러드에\n"+
"쫄깃 바삭 크로켓 번, 육즙 가득 쇠고기 패티로 풍미 가득한\n" +
"88년 추억의 맛을 담은 버거!", 521));
System.out.println(hm);// {상하이 스파이시 버거=Burger [flavor=매콤한맛, calorie=360], 88서울비프버거=Burger [flavor=부드럽고 고소한 에그 양배추 샐러드에 쫄깃 바삭 크로켓 번, 육즙 가득 쇠고기 패티로 풍미 가득한 88년 추억의 맛을 담은 버거!, calorie=521], 와퍼=Burger [flavor=근본있는맛, calorie=550], 블랙오징어버거=Burger [flavor=매운맛, calorie=350], 징거버거=Burger [flavor=징거버거맛, calorie=350], 싸이버거=Burger [flavor=바삭바삭한 맛, calorie=400]}
//값의 저장 순서 유지 x , Key=Value
//Value값의 중복 저장 허용 => Key값은 중복 안 됨.
hm.put("88서울비프버거", new Burger("옛날맛",521)); //기존의 Key값에 Value값이 덮어씌워진다.
System.out.println(hm); //{상하이 스파이시 버거=Burger [flavor=매콤한맛, calorie=360], 88서울비프버거=Burger [flavor=옛날맛, calorie=521], 와퍼=Burger [flavor=근본있는맛, calorie=550], 블랙오징어버거=Burger [flavor=매운맛, calorie=350], 징거버거=Burger [flavor=징거버거맛, calorie=350], 싸이버거=Burger [flavor=바삭바삭한 맛, calorie=400]}
Key는 식별자 개념! => Key로 Value를 찾아감
2. get(Object key): Object
=> 제네릭 설정을 해놨기 때문에 매개변수는 String, 반환형은 Burger
해당 key값에 해당하는 value값을 반환해주는 메소드
System.out.println(hm.get("88서울비프버거"));
//Burger [flavor=옛날맛, calorie=521]
Burger ob = /*(Burger)*/hm.get("와퍼");
제네릭 설정을 안 해놨다면 매 번 다운캐스팅을 했어야 함
3. size() : 맵에 담겨있는 요소의 개수
System.out.println(hm.size()); //6
4. replace(K key, V value) : 해당 Key값을 찾아서 Value를 변경시켜줌
hm.replace( "블랙오징어버거", new Burger("검은 오징어맛", 361));
//기존에 존재하지 않는 키값을 제시했을 땐 추가가 안됨
hm.replace("없는 버거", new Burger("없는 맛",0));
System.out.println(hm);
//{상하이 스파이시 버거=Burger [flavor=매콤한맛, calorie=360], 88서울비프버거=Burger [flavor=옛날맛, calorie=521], 와퍼=Burger [flavor=근본있는맛, calorie=550], 블랙오징어버거=Burger [flavor=검은 오징어맛, calorie=361], 징거버거=Burger [flavor=징거버거맛, calorie=350], 싸이버거=Burger [flavor=바삭바삭한 맛, calorie=400]}
5. remove(Object key) => 해당 키값을 찾아서 => Key + Value 세트를 지워주는 메소드
hm.remove("블랙오징어버거");
System.out.println(hm);
//{상하이 스파이시 버거=Burger [flavor=매콤한맛, calorie=360], 88서울비프버거=Burger [flavor=옛날맛, calorie=521], 와퍼=Burger [flavor=근본있는맛, calorie=550], 징거버거=Burger [flavor=징거버거맛, calorie=350], 싸이버거=Burger [flavor=바삭바삭한 맛, calorie=400]}
해시맵에 들어있는 모든 요소들에 순차적으로 접근하고자 할 때 ?
- for문 X, 향상된 for문
어느 방법을 써야할까?
//List에 addAll 하는 방법 => collection라인이 아니라서 불가능
//Interator를 쓰는 방법 => 바로 호출은 안됨
====> Map계열을 Set계열로 바꿔서 => Iterator을 사용할 것
1. keySet()을 이용하는 방법
=>HashMap에서 제공하는 메소드, Set에 key들만 담아준다. 반환형은 Set
1단계: Key들만 Set에 담는다.
Set<String> keyset = hm.keySet();
2단계: 1단계에서 만들어진 Set내용물을 Iterator에 담기
Iterator<String> itKey = keyset.iterator();
3단계 : Iterator로 부터 반복문 이용해서 순차적으로 key - value 뽑기
while(itKey.hasNext()) {
String key = itKey.next();
System.out.println(key + "-" + hm.get(key));
}
2. entrySet() 이용하는 방법
1)Map에 있는 key + value 세트를
Entry형식으로 Set에 담기
Set<Entry<String, Burger>> entrySet = hm.entrySet();
for(Entry<String, Burger> e :entrySet){
System.out.println(e.getKey() + "-" + e.getValue());
}
* Map계열 특성상 요소들에 순차적으로 접근할 직접적인 방법이 없음
=> Map계열을 Set계열로 바꿔서 => 반복문, ArrayList로 바꿔서 반복문
* Iterator를 쓰는 방법
* => Map계열을 Set계열로 바꾸는 2가지 방법: keySet(), entrySet()
# Properties
package com.kh.chap03_map.chap03_map.part01_hashMap.run;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesRun1 {
public static void main(String[] args) {
- Properties : Map계열 -> key + value세트로 저장됨
// Key와 Value 모두 String형을 다룬다.
[표현법]
Properties 이름 = new Properties();
Properties prop = new Properties();
prop.put("와퍼", new Burger("근본있는맛", 1550));
System.out.println(prop);
//{와퍼=Burger [flavor=근본있는맛, calorie=1550]}
System.out.println(prop.get("와퍼"));
//Burger [flavor=근본있는맛, calorie=1550]
Properties의 용도 => 파일 입출력을 하기 위함
* key + value세트로 파일로 기록한다던가
* 파일로부터 읽어오는 용도로 많이 사용됨
=> .properties 파일 확장자
* 자주 변경되지 않는 설정파일이나
* 해당 프로그램이 기본적으로 가져야 할 정보들을 담는 파일
- String, String형으로 담아보자
prop.setProperty("List", "ArrayList" );
prop.setProperty("Set", "HashSet" );
prop.setProperty("Map", "HashMap" );
prop.setProperty("Map", "Properties" ); //덮어쓰기
System.out.println(prop);
//{Map=Properties, List=ArrayList, Set=HashSet}
Properties inputProp = new Properties(); //******잘 기억하기
try {
prop.store(new FileOutputStream("test.properties"), "Properties Test");
- store(OutputStream os, String Comments): 파일을 기록할 때 쓰는 메소드
//key = value형태로 파일이 출력됨.
//입력
System.out.println("\n여기서부터는 입력");
inputProp.load(new FileInputStream("test.properties"));
//load(InputStream is) : 파일로부터 읽어올 때 쓰이는 메소드
System.out.println(inputProp.get("List")); //ArrayList
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
# Properties 2
package com.kh.chap03_map.chap03_map.part01_hashMap.run;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class PropertiesRun2 {
public static void main(String[] args) {
//.xml
//다양한 프로그래밍 언어 간에 호환성이 좋다.
Properties prop = new Properties();
prop.setProperty("List", "ArrayList" );
prop.setProperty("Set", "HashSet" );
System.out.println(prop);
try {
prop.storeToXML(new FileOutputStream("test.xml"), "안녕하세요.");
//storeTOXML(OutputStream os, String comments)
//Properties 객체의 키 + 밸류 세트를 XML파일로 저장
//불러오기: loadFromXML(InputStream is)
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
'클라우드 융합 Full-stack 웹 개발자 양성과정 > Java' 카테고리의 다른 글
프로그래밍 언어응용 - IO(Object),Collection(list) (0) | 2022.09.25 |
---|---|
프로그래밍 언어응용 - API(String, Math, Wrapper), IO (1) | 2022.09.25 |
프로그래밍 언어응용-추상화, 인터페이스, 예외처리 (1) | 2022.09.25 |
프로그래밍 언어응용-다형성 (1) | 2022.09.25 |
프로그래밍 언어응용-상속 (1) | 2022.09.25 |