2023. 3. 29. 20:41ㆍjava
1. Collection의 AddressBook.java
private을 붙인 멤버 변수를 생성
한 명의 이름/나이 주소/생일 저장하는 address클래스 생성
Comparable 인터페이스 구현- 인자 한 개짜리 Collections.sort(List컬랙션) 사용
Collections.sort(리스트 한 개짜리)를 적용하려면 그 리스트 컬렉션에 저장된 객체는 반드시 Comparable 해야 된다.
compareTo(Address target) 메소드를 오버라이딩할 때
오른 차순은 return부분에서 멤버변수name - 매개변수.name 이런식으로 앞에서 뒤에껄 빼면 디폴트인 오른차순
뒤의 target.name(매개변수)에서 앞(멤버변수 name)을 빼면 내림차순
두 가지 방법으로 구현
AddressBook.java
package collection20;
import java.sql.Date;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
//한 명의 이름/나이/주소/생일을 저장하는 클래스]
//방법1. Comparable인터페이스 구현- Collections.sort(List컬렉션) 인자 하나짜리 사용
// Collections.sort(리스트컬렉션)를 적용하려면 리스트 컬렉션에 저장된 객체(타입)은 반드시 Comparable을 구현해야한다
class Address /* implements Comparable<Address>//방법1을 할때 주석풀기*//{
//[멤버변수]
private String name;
private int age;
private String addr;
private Date birthday;
//정렬시 사용할 상수
public static final int SORT_BY_NAME=1;//디폴트
public static final int SORT_BY_AGE=2;
public static final int SORT_BY_ADDRESS=3;
public static final int SORT_BY_BIRTHDAY=4;
//방법1일때-정렬시 구분자로 사용할 정적 필드(디폴트는 이름으로 정렬)
//public static int sortField =SORT_BY_NAME;
//[인자 생성자]
public Address(String name, int age, String addr, Date birthday) {
this.name = name;
this.age = age;
this.addr = addr;
this.birthday = birthday;
}//////////////////
@Override
public String toString() {
return String.format("[이름:%s,나이:%s,주소:%s,생일:%s]",name,age,addr,birthday);
}///////////////////////
/*
//방법1일때
@Override
public int compareTo(Address target) {
switch(sortField) {
case SORT_BY_NAME:
return name.compareTo(target.name);//오름차순
case SORT_BY_AGE:
return age - target.age;
case SORT_BY_ADDRESS:
return addr.compareTo(target.addr);
default:return birthday.toString().compareTo(target.birthday.toString());
}
}*/
//방법2 일때 게터 추가
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getAddr() {
return addr;
}
public Date getBirthday() {
return birthday;
}
}///////////////////
public class AddressBookApp {
/*
방법2. 정렬용 메소드 정의해서 사용.
1.리스트컬렉션에 저장할 객체인 Address가 Comparable인터페이스를 구현할 필요가 없다.
2.정렬시 구분자로 사용할 정적 필드(sortField)도 필요없다
정렬시 Collections.sort(List컬렉션,Comparator타입) 인자 두개 짜리 사용
*/
public static void sort(int sortField,List<Address> values) {
Collections.sort(values, new Comparator<Address>() {
@Override
public int compare(Address src, Address target) {
switch(sortField) {
case Address.SORT_BY_NAME:
return src.getName().compareTo(target.getName());//오름차순
case Address.SORT_BY_AGE:
return src.getAge() - target.getAge();
case Address.SORT_BY_ADDRESS:
return src.getAddr().compareTo(target.getAddr());
default:return src.getBirthday().toString().compareTo(target.getBirthday().toString());
}
}
});
}///////////////////
public static void main(String[] args) {
/*
1]자음을 Key값-String 혹은 Character
List계열 컬렉션을 Value값-List<String>
Map계열 컬렉션-Value에는 자음에 해당하는 이름들 저장
*/
Map<Character, List<String>> nameAddresses = new HashMap<>();
//1-1]이름 저장용 List계열 컬렉션 객체 생성 및 이름 저장]
List<String> kieyeok = Arrays.asList("고길동","곽길동","가길동","강길동");
List<String> nieoun = Arrays.asList("노길동","나길동","남길동");
//1-2]Map컬렉션(nameAddresses)에 이름이 저장된 List계열 컬렉션 저장
nameAddresses.put('ㄱ', kieyeok);
nameAddresses.put('ㄴ', nieoun);
System.out.println("[키값을 알때]");
List<String> values=nameAddresses.get('ㄱ');
for(String value:values) System.out.println(value);
System.out.println("[키값을 모를때]");
//1]keySet()으로 Set컬렉션 얻기
Set<Character> keys= nameAddresses.keySet();
//2]Set컬렉션에 확장 for문 적용
for(Character key:keys) {
System.out.println(String.format("[%c로 시작하는 명단]",key));
//3]get(키값)으로 value얻기
values=nameAddresses.get(key);
for(String value:values) System.out.println(value);
}////////
/*
2] 초성을 Key값-String 혹은 Character
List계열 컬렉션을 Value값-List<Map<String,Object>>
Map계열 컬렉션-Value에는 초성에 해당하는 이름,주소,전화번호,나이들 저장
*/
Map<Character,List<Map<String,Object>>> address = new HashMap<>();
//2-1]이름/전번/주소/나이가 저장된 맵 컬렉션을 저장할 리스트계열 컬렉션 객체 생성.
List<Map<String,Object>> kie = new Vector<>();
List<Map<String,Object>> nie = new Vector<>();
Map<String,Object> k= new HashMap<>();
k.put("name", "고길동");
k.put("age",20);
k.put("addr", "가산동");
k.put("birthday", new Date(new java.util.Date().getTime()));
kie.add(k);
k= new HashMap<>();
k.put("name", "곽길동");
k.put("age",30);
k.put("addr", "서초동");
k.put("birthday", new Date(new java.util.Date().getTime()));
kie.add(k);
Map<String,Object> n= new HashMap<>();
n.put("name", "나길동");
n.put("age",25);
n.put("addr", "나산동");
n.put("birthday", new Date(new java.util.Date().getTime()));
nie.add(n);
n= new HashMap<>();
n.put("name", "노길동");
n.put("age",35);
n.put("addr", "방배동");
n.put("birthday", new Date(new java.util.Date().getTime()));
nie.add(n);
//주소록 저장하는 맵컬렉션에 리스트 저장]
address.put('ㄱ', kie);
address.put('ㄴ', nie);
/*
객체 꺼내올때]
Set/List계열(Collection계열) 무조건 확장 for문 사용
Map계열은 keySet()으로 키값들이 저장된
Set계열 반환 받은 후 확장 for문 사용
*/
System.out.println("[키값을 알때]");
List<Map<String,Object>> lists=address.get('ㄴ');
for(Map<String,Object> map:lists) {
Set<String> sets= map.keySet();
for(String key:sets) {
Object value = map.get(key);
System.out.println(String.format("%s:%s",key,value));
}
}
System.out.println("[키값을 모를때]");
keys=address.keySet();
for(Character key:keys) {
System.out.println(String.format("[%c로 시작하는 명단]",key));
lists=address.get(key);
for(Map<String,Object> map:lists) {
Set<String> sets= map.keySet();
for(String ky:sets) {
Object value = map.get(ky);
System.out.println(String.format("%s:%s",ky,value));
}
}
}/////////////////
//3]Address클래스를 사용해서 2]번 처럼 구현
Map<Character,List<Address>> addressBook = new HashMap<>();
//3-1]주소를 저장할 리스트 계열 컬렉션 생성
List<Address> kiec = new Vector<>();
List<Address> niec = new Vector<>();
//3-2]주소 저장
long epochTime =new java.util.Date().getTime();
kiec.add(new Address("곽길동", 40, "가산동", new Date(epochTime)));
kiec.add(new Address("고길동", 20, "청담동", new Date(epochTime)));
kiec.add(new Address("가길동", 35, "사당동", new Date(epochTime)));
niec.add(new Address("노길동", 45, "가산동1", new Date(epochTime)));
niec.add(new Address("나길동", 25, "청담동1", new Date(epochTime)));
niec.add(new Address("남길동", 35, "사당동1", new Date(epochTime)));
//3-3]키값으로 리스트 컬렉션 객체를 맵(addressBook)에 저장
addressBook.put('ㄱ', kiec);
addressBook.put('ㄴ', niec);
System.out.println("[한 사람의 정보를 저장하는 클래스를 사용해서 구현]");
keys=addressBook.keySet();
for(Character key:keys) {
System.out.println(String.format("[%c로 시작하는 명단]",key));
List<Address> vals=addressBook.get(key);
//출력전 정렬
//[방법1으로 정렬시]
//디폴트인 이름으로 정렬시
//Collections.sort(vals);
//나이로 정렬시
//Address.sortField=Address.SORT_BY_AGE;
//Collections.sort(vals);
//[방법2으로 정렬시]
sort(Address.SORT_BY_ADDRESS,vals);
for(Address val:vals) {
System.out.println(val);
}
}
}////////////main
}//////////////class
sol)
추가)
2. 만들었던 메뉴 프로그램에서 자음, 오름차순, 내림차순으로 학생, 선생을 출력하기 위한 샘플 코드
AddressProjectSample.java
package collection20;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.Vector;
import common.utility.CommonUtil;
public class AddressProjectSample {
public static void main(String[] args) {
Map<Character,List<Address>> addressBook = new HashMap<>();
Scanner sc = new Scanner(System.in);
//1]밸류 타입을 null로 초기화
List<Address> valueList=null;
while(true) {
System.out.println("이름을 입력하세요?(종료시 EXIT)");
String name = sc.nextLine().trim();
if(name.equalsIgnoreCase("EXIT")) break;
//2]입력한 이름에서 자음 (ㄱ,ㄴ,ㄷ,.....ㅎ)얻기
char jaeum= CommonUtil.getJaeum(name);
//System.out.println(jaeum);
if(jaeum=='0') {
System.out.println("한글명이 아닙니다");
continue;
}
System.out.println("주소를 입력하세요?");
String addr = sc.nextLine().trim();
System.out.println("나이를 입력하세요?");
int age = Integer.parseInt(sc.nextLine().trim());
Date birthday = new Date(new java.util.Date().getTime());
//맵컬렉션(addressBook)에 jaeum 키값이 존재하는지 판단
if(!addressBook.containsKey(jaeum)) {//키값이 없는 경우.즉 맵컬렉션에 해당 키값이 저장이 안되어 있는 경우
valueList = new Vector<>();//value타입인 List<Address>객체 생성
}
else {//키값이 존재한다면
valueList=addressBook.get(jaeum);
}
//입력한 정보로 Address타입 생성후 맵의 value에 추가
valueList.add(new Address(name, age, addr, birthday));
//4]맵 컬렉션에 jaeum키값으로 저장
addressBook.put(jaeum,valueList);
}/////////////while
//출력]
Set<Character> keys= addressBook.keySet();
for(Character key:keys) {
System.out.println(String.format("[%c로 시작하는 명단]",key));
List<Address> values= addressBook.get(key);
for(Address value:values) System.out.println(value);
}/////////////////////////
/*
문]찾고자 하는 사람의 이름을 입력받아
위 맵 컬렉션(addressBook)에 저장된 사람의 정보를 출력하자.
만약 해당하는 사람이 없으면 "해당하는 사람이 없어요"라고 출력하여라.
찾을때까지 계속 입력받도록 하여라.
*/
while(true) {
System.out.println("찾는 사람의 이름을 입력하세요?");
String name = sc.nextLine().trim();
boolean isExist = false;
for(Character key:keys) {
List<Address> values= addressBook.get(key);
for(Address value:values) {
if(value.getName().equals(name)) {
System.out.println(value);
isExist=true;
break;
}
}
if(isExist) break;
}
if(isExist) break;
else System.out.println("해당하는 사람이 없어요");
}
}////////////////main
}///////////////////class
sol)
//2] 입력한 이름에서 자음 (ㄱ,ㄴ,ㄷ,.....ㅎ) 얻기
char jaeum= CommonUtil.getJaeum(name); 를 하기 위한
이름에서 자음을 구하여 반환하는 메소드
common.utility 패키지에서 CommonUtil.java
package common.utility;
public class CommonUtil {
//이름에서 자음을 구해 반환 하는 메소드]
public static char getJaeum(String name) {
//김길동->ㄱ,박길동->ㅂ, 홍길동->ㅎ
//방법1]
char[] jaeum=name.toCharArray();
/*
if(jaeum[0] >='가' && jaeum[0] < '나') return 'ㄱ';
else if(jaeum[0] >='나' && jaeum[0] <'다') return 'ㄴ';
else if(jaeum[0] >='다' && jaeum[0] <'라') return 'ㄷ';
else if(jaeum[0] >='라' && jaeum[0] <'마') return 'ㄹ';
else if(jaeum[0] >='마' && jaeum[0] <'바') return 'ㅁ';
else if(jaeum[0] >='바' && jaeum[0] <'사') return 'ㅂ';
else if(jaeum[0] >='사' && jaeum[0] <'아') return 'ㅅ';
else if(jaeum[0] >='아' && jaeum[0] <'자') return 'ㅇ';
else if(jaeum[0] >='자' && jaeum[0] <'차') return 'ㅈ';
else if(jaeum[0] >='차' && jaeum[0] <'카') return 'ㅊ';
else if(jaeum[0] >='카' && jaeum[0] <'타') return 'ㅋ';
else if(jaeum[0] >='타' && jaeum[0] <'파') return 'ㅌ';
else if(jaeum[0] >='파' && jaeum[0] <'하') return 'ㅍ';
else if(jaeum[0] >='하' && jaeum[0] <='힣') return 'ㅎ';
*/
//방법2]
char[] startChar= {'가','나','다','라','마','바','사','아','자','차','카','타','파','하'};
char[] endChar= {'낗','닣','띻','맇','밓','삫','앃','잏','찧','칳','킿','팋','핗','힣'};
char[] returnChar= {'ㄱ','ㄴ','ㄷ','ㄹ','ㅁ','ㅂ','ㅅ','ㅇ','ㅈ','ㅊ','ㅋ','ㅌ','ㅍ','ㅎ'};
for(int i=0;i<startChar.length;i++) {
if(jaeum[0] >=startChar[i] && jaeum[0]<=endChar[i])
return returnChar[i];
}
return '0';//자음이 아닌 경우
}
}
3. AcademyCollectionLogic.java에서 printPerson() 메소드에서
학생과 교사를 출력하는데 가나다.... 오름차순으로, 내림차순으로 정렬하여 출력하기
(코드 3줄 추가)
private void printPerson() {
//먼저 정렬하기
//Collections.sort(person);//Comparable구현시
//person.sort(Comparator.naturalOrder());//오름 차순
person.sort(Comparator.reverseOrder());//내림 차순
StringBuffer student = new StringBuffer("[학생 목록]\r\n");
StringBuffer teacher = new StringBuffer("[교사 목록]\r\n");
for(Person p:person)
if(p instanceof Student)
student.append(p.get()+"\r\n");
else
teacher.append(p.get()+"\r\n");
System.out.println(student.toString()+teacher);
}
4. 예외처리
컴파일 에러
-컴파일이 발생하는 에러는
1. 문법(syntax) 에러
2. IOException(예외 클래스)
3. SQLException(예외 클래스) 등등
4. Checked Exception(컴파일 에러)
컴파일러가 판단할 수 있는 에러. 실행 전에 체크가 가능한 에러
IOException( IO = nputOutput )
2번은 ex) System.read()가 있는데
이건 예전에 입력을 받을 때 썼었다. 입력을 사용자가 키보드로 받는데 이때 자바에서는 외부자원으로 판단.
이 키보드는 JVM에서 들어있는가 그렇지 않기 때문
자바는 외부 자원을 예외를 발생시키고 본다(빨간 줄)
해결방법)
호출한 메소드(예로 main) throws 예외클래스를 해주거나
try ~catch를 해주면 됨.
5. 런타임 에러(UnChecked Exception)
컴파일 시 체크가 안되는데 실행하면 콘솔에 에러 발생
ex) RuntimeException계열
NullPointerException => 예로 null값으로 무언가 참조할 때
ArithmeticException => 나누기 0으로 했을 때
ArrayIndexOutOfBoundsException => 배열의 크기를 벗어난 인덱스 사용 시 (배열의 자리가 없는데 값을 넣으려 할 때)
main메서드에서는 throws해도 오류 발생 => 직접 처리 try~catch문 써야 된다
예외 발생 시 JVM은 해당 예외클래스를 인스턴스화해서 예외 객체를 프로그램 쪽에 전달함
ExceptionBasic.java
package exception21;
import java.io.IOException;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;
public class ExceptionBasic {
public static void main(String[] args) /*방법1 throws IOException */ {
/*
1]컴파일 에러(Checked Exception):
- 컴파일시 발생하는 에러
- Syntax에러(문법오류) ,IOException(예외 클래스),SQLException(예외클래스)등
- 컴파일이 안되면 실행이 안됨.
- 컴파일 에러(외부 자원 사용시 발생하는 컴파일에러:IOException,SQLException)는
던지거나(throws)
직접 처리(try~catch절) 할 수 있다
단,Syntax오류(문법오류)는 직접 수정해야 함
*/
//1-1]Syntax에러
//Int num;//[x]해결책 I를 i로
int num;//[o]
if(true); {}
//else {}//[x]else는 항상 if 와 짝을 이루어야 한다.
/*
※자바에서는 외부에 있는 자원을 사용하고자 할때는
무조건 예외를 발생시킨다.(컴파일 에러의 한 종류)
read()는 IOExcpetion을 던진다.
read()메소드를 호출한 쪽에서는
예외를 다시 던지거나 try~catch절로 직접
예외를 처리해야 한다.
방법1]예외 던지기
호출한 메소드() throws 예외클래스{
}*/
//방법1]예외를 또 던진다
//System.in.read();
//방법2]try~catch절로 직접 예외 처리
/*
try {
System.in.read();
}
catch (IOException e) {e.printStackTrace();}*/
/*
2]런타임 에러(UnChecked Exception)
- 컴파일시에는 체크가 안됨.실행시에만 발생되는 에러
- RuntimeException계열(
NullPointerException,ArithmeticException,
ArrayIndexOutOfBoundsException등)
- main메소드에서는 throws해도 오류발생.
즉 직접 처리(try~catch절)해야만 한다
※예외 발생시 JVM은 해당 예외클래스를 인스턴스화 해서
예외 객체를 프로그램쪽에 전달한다.
*/
//[ArrayIndexOutOfBoundsException]:
// 배열의 크기를 벗어난 인덱스 사용시.
try {
int[] array = new int[2];
array[0]=100;
System.out.println("array[0]:"+array[0]);
array[1]=200;
System.out.println("array[1]:"+array[1]);
array[2]=300;
System.out.println("array[2]:"+array[2]);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("예외가 발생했어요");
System.out.println("관리자에게 문의하세요");
}
//[NumberFormatException]:숫자형식의 문자열을
//int형으로 변환시 해당 문자열이 숫자형식이 아닐때.
Scanner sc = new Scanner(System.in);
System.out.println("나이를 입력하세요?");
try {
//nextInt()으로 나이받기
//int age=sc.nextInt();
//nextLine()으로 나이받기
String stringAge = sc.nextLine();
int age = Integer.parseInt(stringAge);
System.out.println("당신의 10년후 나이:"+(age+10));
}
catch(InputMismatchException | NumberFormatException e) {
System.out.println("나이는 숫자만...");
}
/*
[NullPointerException]:
인스턴스 변수에 해당 객체의 메모리 주소가
저장이 안된 경우에 .으로 객체의 멤버에 접근할때 발생
*/
System.out.println(today);
try {
today.getTime();
}
catch(NullPointerException e) {
System.out.println("today는 널입니다.포인터 할수 없어요");
}
/*
"":빈 문자열,null아님
null:null값. null이다
*/
String empty="";
System.out.println("빈 문자열의 길이:"+empty.length());
String nullStr= null;
try {
System.out.println("nullStr 문자열의 길이:"+nullStr.length());
}
catch(NullPointerException e) {
System.out.println("nullStr은 널입니다");
}
/*
* [ArithmeticException]:
* 0으로 나눌때 발생
*/
int result=100;
try {
result/=0;
System.out.println("0으로 나눈 결과:"+result);
}
catch(ArithmeticException e) {
//예외 메시지 출력방법]
//1.사용자 임의 예외 메시지
System.out.println("0으로 나눌 수 없어요");
//2.예외 클래스의 인스턴스 변수 이용:e.toString()
// "예외클래스 : 예외메시지" 형태를 문자열로 반환
//System.out.println(e);
//3.e.getMessage():예외메시지만 출력
//System.out.println(e.getMessage());
//4.e.printStackTrace();//개발시 주로 사용
//e.printStackTrace();
}
}//////////main
static Date today;
}/////////////class
sol)
'java' 카테고리의 다른 글
18일차 2023-03-31 (0) | 2023.03.31 |
---|---|
17일차 2023-03-30 (0) | 2023.03.30 |
15일차 2023-03-28 (0) | 2023.03.28 |
14일차 2023-03-27 (0) | 2023.03.27 |
13일차 2023-03-24 Java (0) | 2023.03.24 |