🚨 Map은 key와 Value가 있으므로 컬렉션에 포함되지 않는다!
List는 인터페이스, ArrayList는 클래스
import java.util.List;
import java.util.ArrayList;
public class T01_ArrayListTest {
public static void main(String[] args) {
// 기본용량 : 10
List list1 = new ArrayList();
// add() 메서드를 사용해서 데이터를 추가한다
list1.add("aaa");
list1.add("bbb");
list1.add(111);
//111이라는 값은 int로 들어오는게 아니다!
//int값을 integer클래스를 이용해 객체를 가져옴, 즉 여기엔 int가 아니라
//Integer 객체!!가 들어옴
list1.add('k');
//따라서 이것도 마찬가지로 char가 아니라 character클래스 의 객체가 들어옴
list1.add(true);
list1.add(12.34);
// 모든 리스트의 컬렉션 프레임워크에는 **add메소드**가 있다
// 왜냐면 인터페이스를 implement했기 때문에 add가 없으면 컴파일이 안됨
// 즉 모든 list는 add메소드를 가지고있다
// size() => 데이터 개수
System.out.println("size => "+list1.size());
System.out.println("list1 => "+list1);
// get()으로 데이터 꺼내오기 : 인덱스를 매개변수로!
System.out.println("1번째 자료: "+list1.get(0));
// 데이터 끼워넣기도 가능하다 : 매개변수 두개
list1.add(0,"zzz");
System.out.println("list1 => "+list1);
// 데이터 변경하기 : set을 이용한다
String temp = (String) list1.set(0,"YYY");
System.out.println("temp => "+temp);
System.out.println("list1 => "+ list1);
list1.remove(0);
System.out.println("삭제후 : "+list1);
list1.remove("bbb");
System.out.println("bbb 삭제후: "+list1);
//주의!!!!!!!!!!!!!!! 만약 111값과 같은 인티저를 지우고싶다?
//list1.remove(111);
//System.out.println("11 삭제후: "+list1); => **오류!!! 111을 index로 인식**
list1.remove(new Integer(111));
// 해결방법 : **파라미터를 다르게 오버로드해주면 됨**
System.out.println("111 삭제후: "+list1);
위에서 add()를 통해 어떤 타입의 값이든 list에 잘 추가되는것을 알 수 있었다.
그런데!! 나중엔 이게 문제가돼!!
⇒ 예를들어 list에 String타입만 넣고 다른타입은 못들어가게 제한하고싶을때!
⇒ 그럼 이땐 Generic을 사용한다
//제네릭을 지정하여 선언 해보자
//List list1 = new ArrayList(); << 아까는 이렇게 선언했음!
List<String> list2 = new ArrayList<String>();
list2.add("AAA");
list2.add("BBB");
list2.add("CCC");
list2.add("DDD");
list2.add("EEE");
// list1.add(111); 이거 이제 안돌아감 String타입이 아니니까!
for(int i=0; i<list2.size(); i++) {
System.out.println(i+" : " + list2.get(i));
}
System.out.println("----------------------------------------------");
//향상된 for문(for-each)으로도 list를 출력 할 수 있다
for(String s : list2) {
System.out.println(s);
}
System.out.println("----------------------------------------------");
//contains(비교객체); => 리스트에 '비교객체'가 있으면 true 없으면 false 리턴
System.out.println(list2.contains("DDD"));
System.out.println(list2.contains("ZZZ"));
// indexOf(비교객체); => 리스트에서 '비교객체'를 찾아 '비교객체'가 있는 index값을 반환한다.없으면 -1 반환
System.out.println("DDD의 index값: "+ list2.indexOf("DDD"));
System.out.println("ZZZ의 index값: "+ list2.indexOf("ZZZ"));
System.out.println("-----------------------------------------------");
//리스트를 배열로 만드는 toArray()에서 캐스팅은 되지 않는다
Object[] strArr = list2.toArray();
// String[] strArr2 = (String [])list2.toArray(); -> 캐스팅 안되므로
// 런타임중에(실행중에) 예외 발생
System.out.println("배열의 갯수: "+strArr.length);
// 그렇다면 리스트의 제네릭 타입에 맞는 자료형의 배열로 변환하는 방법?
// => 제네릭타입의 0개짜리 배열을 생성해서 매개변수로 넣어준다!
// 형식) toArray(new 제너릭타입[0]) 또는 toArray(new 제너릭타입[]{})
String[] strArr2 = list2.toArray(new String[0]);
System.out.println("strArr의 갯수: "+ strArr.length);
// 지우기
for(int i=0; i<list2.size();i++) {
list2.remove(i);
}
System.out.println(list2.size());
// 왜 0이아니라 2가 떠?
// = arrayList는 내부적으로 배열, 한개 지우면 다 떙겨지고,
// 그다음지우면 또 땡겨지고 해서 다 안지워진것(그림그려보면 느낌옴)
// 끝에서부터 지우면 해결!
}
}
스택과 큐를 linkedList와 결합하여 만들어보자
import java.util.LinkedList;
public class T02_StackQueueTest {
public static void main(String[] args) {
/* stack => LIFO
* queue => FIFO
*/
LinkedList<String> stack = new LinkedList<String>();
/* stack의 명령
* 1) 자료입력 : push(저장할 값)
* 2) 자료출력 : pop() => 자료를 꺼내온 후 꺼내온 자료를 stack에서 삭제
*/
stack.push("홍길동");
stack.push("일지매");
stack.push("변학도");
stack.push("강감찬");
System.out.println("현재 stack 값들: "+stack);
String data = stack.pop();
System.out.println("꺼내온 자료: "+data);
System.out.println("꺼내온 자료: "+stack.pop());
System.out.println("현재 stack 값들: "+stack);
stack.push("성춘향");
System.out.println("현재 stack 값들: "+stack);
System.out.println("꺼내온 자료: "+stack.pop());
System.out.println("==================================");
System.out.println();
LinkedList<String> queue = new LinkedList<String>();
/* queue의 명령
* 1) 자료입력 : offer(저장할 값)
* 2) 자료출력 : poll() => 자료를 Queue에서 꺼내온 후 꺼내온 자료는 Queue에서 삭제
*/
queue.offer("홍길동");
queue.offer("일지매");
queue.offer("변학도");
queue.offer("강감찬");
System.out.println("현재 queue의 값:"+queue);
String temp = queue.poll();
System.out.println("꺼내온자료: "+temp);
System.out.println("꺼내온자료: "+queue.poll());
System.out.println("현재 queue의 값: "+queue);
if(queue.offer("성춘향")) {
System.out.println("신규등록자료 : 성춘향");
}
System.out.println("현재 queue의 값 :"+queue);
System.out.println("꺼내온 자료 :"+queue.poll());
}}
arrayList는 내부적으로 배열이다. 따라서 인덱스만 알면 원하는 데이터에 접근 가능
그러나 데이터를 삭제할때 빈공간을 하나씩 땡겨줘야됨. 즉 0번을 지우면 뒤의 몇만개의 배열을 옮기는 일이 발생해 속도가 느려질 수 있다! (끼워넣기도 마찬가지)
linkedList는 그냥 사이에 바로 끼워넣기가 가능, 그러나 검색시 링크를 따라 계속 이동해야하므로(?) 검색시 효율적이지 않다. 따라서 일반적으로 arrayList를 많이 사용한다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class T03_ListSortTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("일지매");
list.add("홍길동");
list.add("성춘향");
list.add("변학도");
list.add("이순신");
System.out.println("정렬 전 :" + list);
// 정렬은 Collections.sort() 메서드를 이용하여 정렬한다.
// 정렬은 기본적으로 '오름차순 정렬'을 수행한다.
// 정렬 방식을 변경하려면 정렬방식을 결정하는 객체를 만들어서
// Collections.sort() 메서드에 인수로 넘겨주면 된다
// 컬렉션은 인터페이스, 컬렉션스는 클래스(컬렉션에 관련한 메소드 있음)
Collections.sort(list);
// 오름차순 정렬 (java.doc에서 String객체 문서 보면 **Comparable**에 정의 되어있음,
// 즉 list안의 애들이 오름차순으로 구현 되어있음.. 리스트안에 객체 넣는순간 자동정렬)
System.out.println("정렬 후 :"+ list);
Collections.shuffle(list); // 데이터를 섞어준다
System.out.println("자료 섞기 후 :"+list);
// 정렬방식을 결정하는 객체(정렬자)를 이용하여 정렬하기
Collections.sort(list, new Desc());
// compare메소드를 갖고있음 Comparator를 implement 했으니까
System.out.println("외부정렬자 정렬 후 :"+list);
}
}
class Desc implements Comparator<String> {
// compare() 반환값을 결정하는 방법
// => 이 메서드가 양수를 반환하면 두 값의 순서가 바뀐다 (오름차순이 디폴트)
// 오름차순 정렬일경우,
// => 값이 크면 양수, 같으면0, 앞의값이 작으면 음수를 반환하도록 한다.
// String객체는 정렬을 위해서 compareTo() 메소드가 구현되어있는데
// 이 메서드의 반환값은 오름차순에 맞게 반환되도록 구현되어있다
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2)*-1; //값을 반대로 리턴하게 만들어 내림차순 완성
}
}
이전엔 String클래스로 정렬했다면 이번엔 사용자정의객체로 해보자
package kr.ddiot.basic;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class T04_ListSortTest {
public static void main(String[] args) {
List<Member> memList = new ArrayList<Member>();
memList.add(new Member(1,"홍길동","010-1111-1111"));
memList.add(new Member(5,"변학도","010-1111-2222"));
memList.add(new Member(9,"성춘향","010-1111-3333"));
memList.add(new Member(3,"이순신","010-1111-4444"));
memList.add(new Member(6,"강감찬","010-1111-5555"));
memList.add(new Member(2,"일지매","010-1111-6666"));
System.out.println("정렬전 ");
for(Member mem : memList) {
System.out.println(mem);
}
System.out.println("-------------------------------------------------");
class Member implements Comparable<Member> {
private int num;
private String name;
private String tel;
public Member(int num, String name, String tel) {
super();
this.num = num;
this.name = name;
this.tel = tel;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Member [num=" + num + ", name=" + name + ", tel=" + tel + "]";
}
//Comparable을 임플리먼트하면 결국 compareTo()를 구현해야한다는 뜻
//이름을 기준으로 오름차순정렬이 되도록 설정한다.
@Override
public int compareTo(Member mem) {
// String에 compare가 이미 구현이 되어있지. 그래서int인 애들은 compareTo가 안되네
//나랑 mem을 비교하므로, 나자신은 getter를 통해 얻어온다
// compareTo()메소드는 String객체에 저장되어있음. 오름차순으로!
return this.getName().compareTo(mem.getName());
}
}
Collections.sort(memList);
System.out.println("정렬후 (이름 오름차순) ");
for(Member mem : memList) {
System.out.println(mem);
}
System.out.println("-------------------------------------------------");
// 외부정렬자 사용하기
Collections.sort(memList, new SortNumDesc());
System.out.println("정렬후 (번호 내림차순) ");
for(Member mem : memList) {
System.out.println(mem);
}
System.out.println("-------------------------------------------------");
}
}
// 외부정렬자 사용하여
// Member의 번호(num)의 내림차순으로 정렬하기
class SortNumDesc implements Comparator<Member>{
@Override
public int compare(Member mem1, Member mem2) {
// if(mem1.getNum() > mem2.getNum()) {
// return -1;
// }else if(mem1.getNum() == mem2.getNum()){
// return 0;
// }else {
// return 1;
// }
// }
// Integer에도 Comparable<>이 구현되어있음
// Wrapper클래스에서 제공하는 메서드를 이용하는 방법도 있다
return new Integer(mem1.getNum()).compareTo(mem2.getNum())*-1;
}
}
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class T05_SetTest {
public static void main(String[] args) {
Set hs1 = new HashSet();
//Set에 데이터를 추가할 때도 add()메서드를 사용
hs1.add("DD");
hs1.add("AA");
hs1.add(2);
hs1.add("CC");
hs1.add("BB");
hs1.add(1);
hs1.add(3);
System.out.println("Set 데이터 : "+hs1);
System.out.println();
//Set은 데이터의 순서(인덱스)가 없고, 중복을 허용하지 않는다
// 그래서 이미 있는 데이터를 add하면 false를 반환하고, 데이터는 추가되지 않는다
boolean isAdded = hs1.add("FF");
System.out.println("중복되지않을때 : "+isAdded);
System.out.println("Set 데이터: "+hs1);
System.out.println();
isAdded = hs1.add("CC");
System.out.println("중복 될 때 : "+isAdded);
System.out.println("Set 데이터 : "+hs1);
//Set의 데이터를 수정하려면 수정하는 명령이 따로 없기 때문에 해당 자료를
//삭제한 후 새로운 데이터를 추가해주어야 한다
//삭제하는 메서드
//1)clear() => Set데이터 전체삭제
//2)remove(삭제할자료) => 해당자료삭제
// 예) 'FF'를 'EE'로 수정하기
hs1.remove("FF"); //'FF'자료 삭제
System.out.println("삭제후 Set데이터: "+hs1);
System.out.println();
hs1.add("EE"); //EE자료추가
System.out.println("Set 데이터: "+hs1);
System.out.println();
//hs1.clear(); 전체자료 삭제
//System.out.println("clear후 Set 데이터: "+hs1);
System.out.println("Set의 자료 개수 : "+hs1.size());
System.out.println();
//Set은 데이터의 순서가 없기 떄문에 List처럼 인덱스를 이용해 하나씩 불러올 수 없다
//그래서 데이터를 하나씩 얻기 위해서는 Iterator객체를 이용해야 한다
//=>Set객체의 iterator() 메서드를 호출하면 된다
Iterator it = hs1.iterator();
//데이터 갯수만큼 반복하기
//hashNext() => 포인터 다음위치에 데이터가 있으면 true,
// 없으면 false 반환
while(it.hasNext()) {
// 다음자료가 있는지 검사
// next() => 포인터를 다음 자료위치로 이동하고 이동한 위치의 자료를 반환한다
System.out.println(it.next());
}
// 1~100 사이의 중복되지 않는 정수 5개 만들기
Set<Integer> intRnd = new HashSet<Integer>();
while(intRnd.size()<5) {
int num = (int) (Math.random()*100+1);
intRnd.add(num);
}
System.out.println("만들어진 난수들: "+intRnd);
//Collection유형의 객체들은 서로다른 자료구조로 쉽게 변경해서 사용할 수 있다.
// 다른종류의 객체를 생성할 때 매개변수에 변경할 데이터를 넣어주면 된다
List<Integer> intRndList = new ArrayList<Integer>(intRnd);
System.out.println("List의 자료 출력...");
for(int i = 1; i<intRndList.size(); i++) {
System.out.println(intRndList.get(i));
}
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
public class T06_SetTest {
public static void main(String[] args) {
TreeSet<String> ts = new TreeSet<String>();
List<String> abcList = new ArrayList<String>();
// 영어대문자를 문자열로 변환하여 List에 저장
for(char ch='A'; ch<='Z'; ch++) {
String temp = String.valueOf(ch);
abcList.add(temp);
}
Collections.shuffle(abcList);
System.out.println("abcList 자료: "+abcList);
for(String str:abcList) {
ts.add(str);
}
System.out.println("TreeSet자료: "+ts);
// TreeSet에 저장된 자료 중 특정한 자료보다 작은 자료를 찾아
// SortedSet으로 반환하는 메서드가 있다
// 이진 트리 그리면 왼쪽이 작은값 오른쪽이 큰값이 들어오는데
// 이때 왼쪽을 headSet 오른쪽은 tailSet으로 한다
// 사이의 값을 가져올수도 있을텐데, 이때는 subSet(부분집합)을 사용한다
// => headSet(기준값) => 기본적으로 **'기준값'은 포함시키지 않는다**
// => headSet(기준값,논리값) => 논리값이 **true**이면, '기준값' 포함함
SortedSet<String> ss1 = ts.headSet("K");
System.out.println("K 이전자료: "+ss1); // 기준값 미포함
System.out.println("K 이전자료(기준값 포함): "
+ ts.headSet("K", true));
// 기준값 보다 큰 자료를 찾아 SortedSet으로 반환하는 메소드
// tailSet(기준값) => **기본적**으로 **기준값을 포함**시킨다
// tailSet(기준값,논리값) => 논리값이 true이면 기준값 포함함
SortedSet<String> ss2 = ts.tailSet("K");
System.out.println("K 이후자료: "+ss2); // 기준값 포함
System.out.println("K 이후자료: "
+ ts.tailSet("K",false));
// subSet(기준값1,기준값2) => 기준값1 ~ 기준값2 사이의 값을 가져옴
// ('기준값1' 포함, '기준값2' 미포함)
// subSet(기준값1,논리값1,기준값2,논리값2) => 각 기준값을 포함할지 여부를 설정한다
// (논리값이 true이면 포함, false이면 미포함)
System.out.println("K(포함)부터 N(미포함)까지 :"
+ ts.subSet("K","N"));
System.out.println("K(포함)부터 N(포함)까지 :"
+ ts.subSet("K",true,"N",true));
System.out.println("K(포함)부터 N(미포함)까지 :"
+ ts.subSet("K",false,"N",false));
System.out.println("K(포함)부터 N(포함)까지 :"
+ ts.subSet("K",false,"N",true));
}
}
package kr.ddiot.basic;
import java.util.HashSet;
import java.util.Set;
public class T07_equals_hashCodeTest {
public static void main(String[] args) {
// 해시함수는 임의의 길이의 데이터를 고정된길이의 데이터로 매핑하는 함수이다
// 해시함수에 의해 얻어지는 해시값, 해시코드, 해시체크썸 또는 간단하게 해시라고 한다
// HashSet, HashMap, Hashtable과 같은 객체들을 사용할경우
// 객체가 서로 같은지 비교하기위해 **equals()메서드와 hashCode()메서드를 호출**한다
// 그래서 객체가 서로 같은지 여부를 결정하려면 두 메서드를 재정의 해야한다
// HashSet, HashMap, Hashtable에서는 객체가 같은지 여부는 **데이터를 추가할때 검사**한다
// - equals()는 두 객체의 내용(값)이 같은지 비교하는 메서드이고
// - hashCode()는 객체에 대한 해시코드값을 반환하는 메서드이다
// => 해시테이블 생성시 사용된다
// -equals()와 hashCode()에 관련된 규칙(Convention)
// 1. 두 객체가 같으면 반드시 같은 hashCode를 가져야한다.
// 2. 두 객체가 같으면 equals()를 호출했을때 true를 반환해야한다.
// 즉, 객체 a,b가 같다면 a.equals(b)와 b.equals(a) 둘다 true여야 한다
// 3. **두 객체의 hashCode가 같다고 해서 두 객체가 반드시 같은 객체는 아니다
// 하지만 두 객체가 같으면 반드시 hashCode가 같아야한다**
// 4. equals()를 override하면 반드시 hashCode()도 override해야 한다
// 5. hashCode()는 기본적으로 Heap메모리에 있는 각 객체에 대한 메모리 주소 매핑 정보를 기반으로 한 정수값을 반환한다
// 그러므로, 클래스에서 hashCode()를 override하지 않으면 절대로 두 객체가 같은것으로 간주 될 수 없다
// -hashCode()에서 사용하는 **'해싱알고리즘'에서 서로다른 객체에 대하여 같은 hashCode값을 만들어 낼 수 있다**
// 그래서 객체가 같지 않더라도 hashCode가 같을 수 있다
System.out.println("Aa".hashCode()); //2112
System.out.println("BB".hashCode()); //2112
// 해쉬코드가 같다고해서 같은객체라고 말하지 못한다, 따라서 내부적으로 equals()를 이용해 판단해줘야한다
Person p1 = new Person(1,"홍길동");
Person p2 = new Person(1,"홍길동");
Person p3 = new Person(1,"이순신");
System.out.println("p1.equals(p2) : "+p1.equals(p2));
System.out.println("p1==p2 : "+(p1==p2));
Set<Person> set = new HashSet<Person>();
set.add(p1);
set.add(p2);
System.out.println("p1,p2 등록 후 데이터");
for(Person p : set) {
System.out.println(p.getId()+" : "+p.getName());
}
}
}
class Person{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
새로 클래스 만들었을때 해쉬코드와 이퀄스를 정상적으로 사용하고 싶으면 equals() 해쉬코드 메소드 오버라이드 필요하다
오브젝트에 있는 이 기능을 그대로 쓰면 중복체크가 잘 안돼!
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class T08_MapTest {
// Map => key값과 value값을 한쌍으로 관리하는 객체
// key값은 중복을 허용하지않고 순서가 없다 (Set의 특징)
// value값은 중복을 허용한다.
public static void main(String[] args) {
Map<String, String>map = new HashMap<String, String>();
//자료추가 => put(key값, value값);
map.put("name", "홍길동");
map.put("addr", "대전");
map.put("tel", "010-1234-5678");
System.out.println("map=> "+map);
//자료수정 => 데이터를 저장할때 key값이 같으면 나중에 입력한 값이 저장된다
// put(수정할 key값, 새로운key값);
map.put("addr","서울");
System.out.println("map=> "+map);
// 자료삭제 => remove (삭제할key값)
map.remove("name");
System.out.println("map=> "+map);
// 자료읽기 => get(key값);
System.out.println("addr=> "+map.get("addr"));
System.out.println("==================================");
// key값들을 순회하며 읽어와 자료를 출력하는 방법
// 방법1 => keySet() 이용하기 (key만 모아놓은 집합. Set이니 Iterator 무조건 존재)
// => Map의 key값들만 읽어와 Set형으로 반환한다
Set<String> keySet = map.keySet();
System.out.println("Iterator를 사용하는 방법");
Iterator<String>it=keySet.iterator(); //Iterator 이용해서 key 얻어와서 순회
while(it.hasNext()) {
String key = it.next();
System.out.println(key+" : "+map.get(key));
}
// 방법2 => Set형의 데이터를 향상된 for문; 으로 처리하면 Iterator를 사용하지 않아도 된다
// 향상된for문은 자바문서에서 Iterable<E>이 상위인터페이스일때 쓸 수 있다
System.out.println("향상된 for문을 이용한 방법");
for(String key : keySet) {
System.out.println(key+" : "+map.get(key));
}
System.out.println("---------------------------------");
// 방법3 => value값만 읽어와 출력하기 => value() 이용하기
System.out.println("values() 이용한 방법");
for(String value:map.values()) {
System.out.println(value);
}
System.out.println("-----------------------------------");
// 방법4 => Map관련클래스에는 Map.Entry 타입의 내부 Class가 만들어져 있다
// 이 내부 클래스는 key와 value라는 멤버변수로 구성되어 있다.
// Map에서 이 Map.Entry타입(키와 벨류 묶어줌)의 객체들을 Set형식으로 저장하여 관리한다
// Map.Entry 타입의 객체 모두 가져오기 => entrySet() 이용하기
Set<Map.Entry<String, String>> mapSet = map.entrySet();
// 가져온 Entry객체들을 순서대로 처리하기 위해서 Iterator 객체를 가져온다
Iterator<Map.Entry<String, String>> entryIt = mapSet.iterator();
while(entryIt.hasNext()) {
Map.Entry<String, String> entry = entryIt.next();
System.out.println("key 값 : "+entry.getKey());
System.out.println("Value 값 : "+entry.getValue());
System.out.println();
}
}
}
// Iterator는 향상된 for문으로 대체될 수 있다
CRUD 해보자
package kr.ddiot.basic;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
/*
문제) 이름, 주소, 전화번호 속성을 갖는 Phone클래스를 만들고, 이 Phone클래스를 이용하여
전화번호 정보를 관리하는 프로그램을 완성하시오.
이 프로그램에는 전화번호를 등록, 수정, 삭제, 검색, 전체출력하는 기능이 있다.
전체의 전화번호 정보는 Map을 이용하여 관리한다.
(key는 '이름'으로 하고 value는 'Phone클래스의 인스턴스'로 한다.)
실행예시)
===============================================
전화번호 관리 프로그램(파일로 저장되지 않음)
===============================================
메뉴를 선택하세요.
1. 전화번호 등록
2. 전화번호 수정
3. 전화번호 삭제
4. 전화번호 검색
5. 전화번호 전체 출력
0. 프로그램 종료
번호입력 >> 1 <-- 직접 입력
새롭게 등록할 전화번호 정보를 입력하세요.
이름 >> 홍길동 <-- 직접 입력
전화번호 >> 010-1234-5678 <-- 직접 입력
주소 >> 대전시 중구 대흥동 111 <-- 직접 입력
메뉴를 선택하세요.
1. 전화번호 등록
2. 전화번호 수정
3. 전화번호 삭제
4. 전화번호 검색
5. 전화번호 전체 출력
0. 프로그램 종료
번호입력 >> 5 <-- 직접 입력
=======================================
번호 이름 전화번호 주소
=======================================
1 홍길동 010-1234-5678 대전시
~~~~~
=======================================
출력완료...
메뉴를 선택하세요.
1. 전화번호 등록
2. 전화번호 수정
3. 전화번호 삭제
4. 전화번호 검색
5. 전화번호 전체 출력
0. 프로그램 종료
번호입력 >> 0 <-- 직접 입력
프로그램을 종료합니다...
*/
public class T09_PhoneBookTest {
private Scanner scan;
private Map<String, Phone> phoneBookMap;
public T09_PhoneBookTest() {
scan = new Scanner(System.in);
phoneBookMap = new HashMap<String, Phone>();
}
// 메뉴를 출력하는 메서드
public void displayMenu(){
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(" 0. 프로그램 종료");
System.out.print(" 번호입력 >> ");
}
// 프로그램을 시작하는 메서드
public void phoneBookStart(){
System.out.println("===============================================");
System.out.println(" 전화번호 관리 프로그램(파일로 저장되지 않음)");
System.out.println("===============================================");
while(true){
displayMenu(); // 메뉴 출력
int menuNum = scan.nextInt(); // 메뉴 번호 입력
switch(menuNum){
case 1 : insert(); // 등록
break;
case 2 : update(); // 수정
break;
case 3 : delete(); // 삭제
break;
case 4 : search(); // 검색
break;
case 5 : displayAll(); // 전체 출력
break;
case 0 :
System.out.println("프로그램을 종료합니다...");
return;
default :
System.out.println("잘못 입력했습니다. 다시입력하세요.");
} // switch문
} // while문
}
// 새로운 전화번호 정보를 등록하는 메소드
// 이미 등록된 사람은 등록하지 않는다
private void insert() {
System.out.println();
System.out.println("새로 등록할 전화번호 정보를 입력하세요 ");
System.out.println("이름 >> ");
String name = scan.next();
// 이미 등록된 사람인지 검사
// get()으로 값을 가져올때 자료가 없으면 null을 반환한다
if(phoneBookMap.get(name)!=null) {
System.out.println(name+"씨는 이미 등록된 사람입니다");
return;
}
System.out.println("전화번호 >> ");
String tel = scan.next();
scan.nextLine(); //입력버퍼에 남아있는 엔터키값까지 읽어와 버리는 역할을 수행한다
System.out.println("주소 >> ");
String addr = scan.nextLine();
phoneBookMap.put(name, new Phone(name,tel,addr));
System.out.println(name+"씨 등록완료");
}
// 기존 전화번호 정보를 수정하는 메소드
private void update() {
System.out.println();
System.out.println("수정할 전화번호 정보를 입력하세요 ");
System.out.println("이름 >> ");
String name = scan.next();
// 이미 등록된 사람인지 검사
// get()으로 값을 가져올때 자료가 없으면 null을 반환한다
if(phoneBookMap.get(name)!=null) {
System.out.println(name+"씨 정보는 존재하지 않습니다");
return;
}
System.out.println("전화번호 >> ");
String tel = scan.next();
scan.nextLine(); //입력버퍼에 남아있는 엔터키값까지 읽어와 버리는 역할을 수행한다
System.out.println("주소 >> ");
String addr = scan.nextLine();
phoneBookMap.put(name, new Phone(name,tel,addr));
System.out.println(name+"씨 수정완료");
}
// 전화번호 정보를 삭제하는 메소드
private void delete() {
System.out.println();
System.out.println("삭제할 전화번호 정보를 입력하세요");
System.out.println("이름 >> ");
String name = scan.next();
if(phoneBookMap.remove(name)==null) {
System.out.println(name+"씨는 등록된 사람이 아닙니다");
} else {
System.out.println(name+"씨 정보를 삭제했습니다.");
}
System.out.println("삭제 완료");
}
// 이름을 이용한 전화번호 정보룰 검색하는 메서드
private void search() {
System.out.println();
System.out.println("검색할 전화번호 정보를 입력하세요");
System.out.println("이름 >> ");
String name = scan.next();
Phone p = phoneBookMap.get(name);
if(p == null) {
System.out.println(name+"씨의 전화번호 정보가 없습니다");
} else {
System.out.println(name+"씨의 정보");
System.out.println("이름: "+p.getName());
System.out.println("전화: "+p.getTel());
System.out.println("주소: "+p.getAddr());
}
System.out.println("검색작업 완료");
}
private void displayAll() {
Set<String> keySet = phoneBookMap.keySet();
System.out.println("============================================");
System.out.println("번호\t이름\t전화번호\t주소");
System.out.println("============================================");
if(keySet.size() ==0) {
System.out.println("등록된 전화번호 정보가 하나도 없습니다");
}else {
int cnt =1;
for(String key : keySet) {
Phone p = phoneBookMap.get(key);
System.out.println(" "+cnt+"\t"+p.getName()+"\t"+p.getTel()+"\t"+p.getAddr());
cnt++;
}
}
System.out.println("===============================================");
System.out.println("출력완료 ㅋㅋ");
}
public static void main(String[] args) {
new T09_PhoneBookTest().phoneBookStart();
}
}
// 전화번호 정보를 저장 할 수 있는 VO클래스
class Phone {
private String name;
private String tel;
private String addr;
public Phone(String name, String tel, String addr) {
super();
this.name = name;
this.tel = tel;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "Phone [name=" + name + ", tel=" + tel + ", addr=" + addr + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((addr == null) ? 0 : addr.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((tel == null) ? 0 : tel.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Phone other = (Phone) obj;
if (addr == null) {
if (other.addr != null)
return false;
} else if (!addr.equals(other.addr))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (tel == null) {
if (other.tel != null)
return false;
} else if (!tel.equals(other.tel))
return false;
return true;
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class T10_PropertiesTest {
public static void main(String[] args) throws IOException {
Properties prop = new Properties();
prop.setProperty("name","홍길동");
prop.setProperty("tel","010-1234-5678");
prop.setProperty("addr","대전");
String name = prop.getProperty("name");
String tel = prop.getProperty("tel");
System.out.println("이름: "+name);
System.out.println("전화번호: "+tel);
System.out.println("주소: "+prop.getProperty("addr"));
//내용 파일로 저장하기
prop.store(new FileOutputStream("src/kr/ddiot/basic/test.properties"), "코멘트입니다");
}
}