- 컬렉션 프레임워크 다시보기
- 자료형이 결정되지 않은 클래스를 제네릭 클래스라고 한다.
Q. ArrayList로 자료를 저장하고 해당 자료 중 자료 20을 지우기
package ex1;
import java.util.List;
import java.util.ArrayList;
public class Ex1_Iterator {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(10); // 추가할때는 add
list.add(20);
list.add(20);
list.add(30);
list.add(40);
System.out.println("1차 출력");
for(int i=0; i<list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("삭제 후 출력");
for(int i=0; i<list.size();i++) {
if(list.get(i)==20) {
list.remove(i);
i--;
}
}
for(int i=0; i<list.size(); i++) {
System.out.println(list.get(i));
}
}
}
출력)
1차 출력
10
20
20
30
40
삭제 후 출력
10
30
40
ㄴ get으로 꺼내고 remove로 꺼낸걸 지우고
+ set, Iterator
Q. set으로 자료를 저장하고 Iterator를 이용해 저장된 자료 30을 삭제
package ex1;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Ex2_set {
public static void main(String[] args) {
Set<Integer> hSet = new HashSet<Integer>();
hSet.add(10); //저장
hSet.add(20); //저장
hSet.add(20); //제외
hSet.add(30); //저장
hSet.add(30); //제외
Iterator<Integer> itr = hSet.iterator(); // Iterator 반복자 인스턴스
System.out.println("1차 출력");
while (itr.hasNext()) { // 참이면 가져오기
int curStr = itr.next(); // 내보내기
System.out.println(curStr);
if (curStr == 30) {
itr.remove();
}
}
System.out.println("삭제 후 출력");
itr = hSet.iterator(); // 새로운 반복자 생성
while (itr.hasNext())
System.out.println(itr.next());
}
}
출력)
1차 출력
20
10
30
삭제 후 출력
20
10
ㄴ set은 중복인정이 안되기 때문에 자료 저장 시에도 동일한 자료값은 저장하지 않는다.
ㄴ 순서대로 정렬되지 않는다.
ㄴ 만약에 데이터가 많아서 비교할 대상이 많아진다면 해쉬 알고리짐을 이용해서 비교한다.
※ 해쉬 알고리즘; 검색을 빨리 하기 위한 도구
- 데이터 < 3, 5, 7, 12, 25, 31 >
- 해시 알고리즘 <num%3>
- 해시 알고리즘은 데이터의 분류에 사용이 된다. 데이터를 3으로 나머지 연산하였을 때 얻게 되는 반환값을 '해시값'으로하여 총 세 개의 부류를 구성하였다.
- 이렇게 분류해 놓으면, 데이터의 검색이 빨라진다. 정수 12가 저장되어 있는지 확인한다고 했을 떄 문제 정수 12의 해시 값으 구한다. 그 다음에 해시 값에 해당하는 부류에서만 정수 12의 존재 유무를 확인하면 된다.
- HashSet의 검색단계
1) Object 클래스의 hashCode 메서드의 반환 값을 값으로 활용하여 검색의 그룹을 선택한다.
2) 그룹 내의 인스턴스를 대상으로 Object 클래스의 equals 메서드의 반환 값의 결과로 동등을 판단한다.
예제)
package ex3;
import java.util.HashSet;
import java.util.Iterator;
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + "(" + age + "세)";
}
@Override
public int hashCode() {
return age%3;
}
// 선생님
// 이름과 나이가 똑같은 사람을 한 그룹으로 모은다.
// @Override
// public int hashCode() {
// return name.hashCode()+age%7;
// }
// 동등비교 기준
@Override
public boolean equals(Object obj) {
Person ps = (Person)obj;
if(ps.name==this.name && ps.age==this.age)
return true;
return false;
}
// 선생님
// 동등비교 기준
// @Override
// public boolean equals(Object obj) {
// Person ps = (Person)obj;
// if(ps.name.equals(name) && ps.age==this.age)
// return true;
// return false;
// }
public static void main(String[] args) {
HashSet<Person> hSet = new HashSet<Person>();
hSet.add(new Person("최순이", 10));
hSet.add(new Person("최순이", 20));
hSet.add(new Person("갑돌이", 20));
hSet.add(new Person("갑돌이", 15));
hSet.add(new Person("최순이", 20)); //제외
hSet.add(new Person("갑돌이", 20)); //제외
System.out.println("데이터 수:" + hSet.size());
Iterator<Person> itr = hSet.iterator();
while (itr.hasNext())
System.out.println(itr.next());
}
}
결과)
데이터 수:4
갑돌이(15세)
최순이(10세)
최순이(20세)
갑돌이(20세)
- TreeSet<E> 클래스의 이해와 활용
- TreeSet<E> 클래스의 트리라는 자료구조를 기반으로 데이터를 저장한다.
- 데이터를 정렬된 순서로 저장하며, HashSet<E>와 마찬가지로 데이터의 중복저장하지 않는다.
- 정렬의 기준은 프로그래머가 직접 정의한다.
- 데이터는 정렬되어 저장이 되며, 때문에 Iter
※Tree? ;
- 이진 트리 간이 설명
- 부모의 왼쪽자식은 부모보다 작고 오른쪽 자식은 부모보다 크다.
- L부R
- 트리는 정렬을 의미
- Tree 다이어그램은 "구조 Tree 기법" 이라고도 불리는 기법으로서 다룰 수 있는 문제들로 체계적으로 세분화하거나, 문제의 근본원인을 명확히 하기 위해 사용한다.
예제)
package ex1;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Ex4_treeSet {
public static void main(String[] args) {
Set<Integer> tS = new TreeSet<Integer>();
tS.add(30);
tS.add(20);
tS.add(10);
tS.add(30);
tS.add(20);
tS.add(40);
tS.add(50);
System.out.println("size =" + tS.size());
Iterator<Integer> itr = tS.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
// 입력되는 순서는 보장되지 않지만 정렬이 된다.
} // main method end
} // class end
결과)
size =5
10
20
30
40
50
ㄴ 입력되는 순서는 보장되지 않지만 정렬이 된다.
ㄴ Iterator는 오름차순으로 정렬.
ㄴ 그렇다면 내림차순은?
예제_역순)
package ex1;
import java.util.Iterator;
//import java.util.NavigableSet;
//import java.util.Set;
import java.util.TreeSet;
public class Ex4_treeSet {
public static void main(String[] args) {
TreeSet<Integer> tS = new TreeSet<Integer>();
tS.add(30);
tS.add(20);
tS.add(10);
tS.add(30);
tS.add(20);
tS.add(40);
tS.add(50);
System.out.println("size = " + tS.size());
Iterator<Integer> itr = tS.descendingIterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
// 입력되는 순서는 보장되지 않지만 정렬이 된다.
} // main method end
} // class end
결과)
size = 5
50
40
30
20
10
6) 정렬의 기준을 정하는 Comparable<T> 인터페이스 // 비교인자 T를 비교
- TreeSet<E> 인스턴스에 저장이 되려면 Comparable<T> 인터페이스를 구현해야 한다.
- Comparable<T> 인터페이스의 유일한 메서드는 int compareTo(T obj); 이다.
- TreeSet<E>는 인스턴스가 저장될 떄마다 기존에 저장된 인스턴스와의 비교를 위해서 compareTo 메서드를 빈번히 호철하여, 이 때 반환되는 값을 기준으로 정렬을 진행한다.
- compareTo 메서드는 다음의 기준으로 구현을 해야 한다.
1) 인자로 전달되 obj가 작다면 양의 정수를 반환해라.
2) 인자로 전달된 obj가 크다면 음의 정수를 반환해라.
3) 인자로 전달되 obj가 같다면 0을 반환해라.
- 참고로, String 클래스의 compareTo 메서드는 사전편찬 순서를 정렬의 기준으로 정의되어 있다.
예제)
package ex1;
import java.util.Iterator;
import java.util.TreeSet;
public class Ex6_comparable implements Comparable<Ex6_comparable> {
String name;
int age;
public Ex6_comparable(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + "(" + age + "세)";
}
@Override
public int hashCode() {
return age % 3;
}
// 정렬 기준 설정
@Override // 정렬 기준 명시
public int compareTo(Ex6_comparable c) {
if (age > c.age)
return 1;
else if (age < c.age)
return -1;
else
return 0;
}
public static void main(String[] args) {
TreeSet<Ex6_comparable> tSet = new TreeSet<Ex6_comparable>();
tSet.add(new Ex6_comparable("Lee", 19)); // 나이 순으로 저장
tSet.add(new Ex6_comparable("Park", 20));
tSet.add(new Ex6_comparable("Kim", 21));
tSet.add(new Ex6_comparable("Choi", 22));
tSet.add(new Ex6_comparable("Choi", 20)); // 나이 같은 사람 비교 후 제외
tSet.add(new Ex6_comparable("Hong", 23));
System.out.println("데이터 수:" + tSet.size());
Iterator<Ex6_comparable> itr = tSet.iterator();
while (itr.hasNext())
System.out.println(itr.next());
}
}
출력)
데이터 수:5
Lee(19세)
Park(20세)
Kim(21세)
Choi(22세)
Hong(23세)
예제의 이름 갯수를 오름차순으로 정렬하고 싶다면?)
// 정렬 기준 설정
@Override // 정렬 기준 명시
public int compareTo(Ex6_comparable c) {
if (name.length() > c.name.length())
return 1;
else if (name.length() < c.name.length())
return -1;
else
return 0;
}
예제의 이름을 사전편찬순으로 정렬하고 싶다면)
// 정렬 기준 설정 // 이름을 사전편찬순으로 정렬
@Override // 정렬 기준 명시
public int compareTo(Ex6_comparable c) {
if (name.compareTo(c.name)>0)
return 1;
else if (name.compareTo(c.name)<0)
return -1;
else
return 0; //제외
}
예제의 이름을 사전편찬순으로 정렬하고 나이가 똑같으면)
// 정렬 기준 설정 // 이름을 사전편찬순으로 정렬
@Override // 정렬 기준 명시
public int compareTo(Ex6_comparable c) {
if (name.compareTo(c.name)>0)
return 1;
else if (name.compareTo(c.name)<0)
return -1;
else
return age-c.age;
}
7. Map(K, V) 인터페이스를 구현하는 컬렉션 클래스들
- K ; key, V ; value
- K는 유니크 해야한다. (ex. 주민번호, 전화번호 etc,)
- 컬렉션과 다른점은 저장하는 구조가 다르다.
- Map<K, V> 인터페이스를 구현하는 컬렉션 클래스는 key-value 방식의 데이터를 저장을 한다.
- value는 저장할 데이터를 의미하고, key는 value를 찾는 열쇠를 의미한다.
- Map<K, V>를 구현하는 대표적인 클래스로는 HashMap<K,V>와 TreeMap<K,V>가 있다.
- value에 상관없이 중복된 key의 저장은 불가능하다.
- value는 같더라도 key가 다르면 둘 이상의 데이터 저장도 가능하다.
예제1) 학번과 이름 입력 후 삭제 및 출력
package ex2;
import java.util.HashMap;
public class Ex_1_IntroMap {
public static void main(String[] args) {
// 키(학번) 값(이름)
HashMap<Integer, String> hM = new HashMap<Integer, String>();
hM.put(1, "차지헌"); // put으로 입력
hM.put(2, "이주성");
hM.put(3, "홍길동");
hM.put(4, "김철수");
hM.put(5, "황미애");
// 삭제
hM.remove(3);
// 출력
System.out.println("3 = " + hM.get(3));
}
}
출력)
3 = null
예제2) 아이디와 비번를 입력하고 나이가 문자열도 오고 정수값도 온다면
package ex2;
import java.util.HashMap;
public class Ex_1_IntroMap {
public static void main(String[] args) {
// 키(아이디) 값(비번)
HashMap<String, Object> hM = new HashMap<String, Object>();
// 입력
hM.put("aaa", 1111);
hM.put("bbb", "2222b");
hM.put("ccc", "3333c");
hM.put("ddd", 4444);
hM.put("eee", "1111a");
// 출력
System.out.println("aaa비번 : "+hM.get("aaa"));
}
}
예제3) 아이디와 비번를 ArrayList로 입력한다면
package ex2;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
public class Ex_1_IntroMap {
public static void main(String[] args) {
// 키(아이디) 값(비번)
HashMap<String, Object> hM = new HashMap<String, Object>();
ArrayList<Integer> list = new ArrayList();
list.add(10);
list.add(20);
list.add(30);
hM.put("ddd", list);
// 출력
System.out.println("ddd비번 : "+hM.get("ddd"));
}
}
- 전화번호부 6단계
PhoneBook Class)
package phoneBook;
import java.util.Scanner;
public class PhoneBook {
public static Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws MenuInputException {
PhoneBookManager manager = PhoneBookManager.creatManagerInst();
while (true) {
showMenu();
// menuNum=sc.nextInt();
int menuNum = readMenuNum();
switch (menuNum) {
case INIT_MENU.INPUT:
manager.inputData();
break;
case INIT_MENU.SEARCH:
manager.searchData();
break;
case INIT_MENU.DELETE:
manager.deleteData();
break;
case INIT_MENU.LIST:
manager.showList();
break;
case INIT_MENU.EXIT:
System.out.println("프로그램이 종료되었습니다.");
return; // System.exit(0);
}
} // while End
}// main End
public static int readMenuNum() {
Scanner key = new Scanner(System.in);
int menuNum = key.nextInt();
if (menuNum >= 6 || menuNum <= 0) {
new MenuInputException();
}
return menuNum;
}
private static void showMenu() {
System.out.println("메뉴를 입력하세요.");
System.out.println("-------------------");
System.out.println("1. 데이터 입력");
System.out.println("2. 데이터 검색");
System.out.println("3. 데이터 삭제");
System.out.println("4. 전체 출력");
System.out.println("5. 프로그램 종료");
System.out.println("-------------------");
System.out.print("선택:");
}
}// class End
PhoneBookManager class)
package phoneBook;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
public class PhoneBookManager {
HashSet<PhoneInfo> list = new HashSet<PhoneInfo>();
static PhoneBookManager inst = null;
private PhoneBookManager() {
}
public static PhoneBookManager creatManagerInst() {
if (inst == null)
inst = new PhoneBookManager();
return inst;
}
public void inputData() throws MenuInputException {
System.out.println("1.일반, 2.대학, 3.회사");
System.out.print("선택: ");
int subMenu = readSubMenuNum();
PhoneInfo info = null;
switch (subMenu) {
case INPUT_MENU.NORMAL:
info = normalInput();
break;
case INPUT_MENU.UNIV:
info = univInput();
break;
case INPUT_MENU.COMPANY:
info = companyInput();
break;
}
boolean result = list.add(info);
if (result) {
System.out.println("입력 완료");
} else {
System.out.println("이미 저장되어 있는 데이터!!");
}
}
public static int readSubMenuNum() {
Scanner key = new Scanner(System.in);
int subMenu = key.nextInt();
if (subMenu >= 4 || subMenu <= 0) {
new MenuInputException();
}
return subMenu;
}
private PhoneInfo normalInput() {
System.out.print("이름:");
String name = PhoneBook.sc.next();
System.out.print("전화번호:");
String phoneNum = PhoneBook.sc.next();
return new PhoneInfo(name, phoneNum);
}
private PhoneInfo univInput() {
System.out.print("이름:");
String name = PhoneBook.sc.next();
System.out.print("전화번호:");
String phoneNum = PhoneBook.sc.next();
System.out.print("전공:");
String major = PhoneBook.sc.next();
System.out.print("학년:");
int year = PhoneBook.sc.nextInt();
return new PhoneUnivInfo(name, phoneNum, major, year);
}
private PhoneInfo companyInput() {
System.out.print("이름:");
String name = PhoneBook.sc.next();
System.out.print("전화번호:");
String phoneNum = PhoneBook.sc.next();
System.out.print("회사명:");
String company = PhoneBook.sc.next();
return new PhoneCompanyInfo(name, phoneNum, company);
}
public void searchData() {
System.out.println("검색 시작....");
System.out.print("이름:");
String name = PhoneBook.sc.next();
PhoneInfo info = search(name);
if (info == null) {
System.out.println("데이터가 존재하지 않습니다.");
} else {
info.showPhoneInfo();
System.out.println("검색 완료");
}
}
private PhoneInfo search(String name) {
Iterator<PhoneInfo> itr = list.iterator();
while (itr.hasNext()) {
PhoneInfo curInfo = itr.next(); // PhoneInfo의 자식들까지 반환가능
if (name.equals(curInfo.getName())) {
return curInfo;
}
}
return null;
}
public void deleteData() {
System.out.println("삭제 시작....");
System.out.print("이름:");
String name = PhoneBook.sc.next();
PhoneInfo info = delete(name);
if (info == null) {
System.out.println("데이터가 존재하지 않습니다.");
} else {
list.remove(info);
System.out.println("삭제 완료");
}
// 선생님 delete 메서드 사용 안하고.
// Iterator<PhoneInfo> itr = list.iterator();
// while(itr.hasNext()) {
// PhoneInfo curInfo = itr.next();
// if(curInfo.getName().equals(name)) {
// itr.remove();
// System.out.println("삭제 완료");
// return;
// }
// }
}
private PhoneInfo delete(String name) {
Iterator<PhoneInfo> itr = list.iterator();
while (itr.hasNext()) {
PhoneInfo curInfo = itr.next();
if (name.equals(curInfo.getName())) {
return curInfo;
}
}
return null;
}
public void showList() {
Iterator<PhoneInfo> itr = list.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
}
}
PhoneInfo class)
package phoneBook;
//데이터 클래스
public class PhoneInfo {
// 필드
private String name;
private String phoneNum;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public PhoneInfo(String name, String phoneNum) {
this.name = name;
this.phoneNum = phoneNum;
}
public void showPhoneInfo() {
System.out.println("name: " + name);
System.out.println("phoneNum: " + phoneNum);
}
@Override
public int hashCode() {
return name.hashCode();
}
// 동등 비교 이름
@Override
public boolean equals(Object obj) {
PhoneInfo cmp = (PhoneInfo) obj;
if (name.equals(cmp.name)) {
return true; // add는 저장 실패
}
return false; // add는 저장성공
}
}
'ICIA 수업일지' 카테고리의 다른 글
2021.06.30 수업일지 (0) | 2021.07.03 |
---|---|
2021.06.29 수업일지 (0) | 2021.07.03 |
2021.06.25 수업일지 (0) | 2021.06.26 |
2021.06.24 수업일지 (0) | 2021.06.26 |
2021.06.23 수업일지 (0) | 2021.06.26 |