한가지 날짜정보를 얻을 땐 Calendar가 좋고 형식있는 전체를 얻을 땐 SimpleDateFormat이 좋음.
Calendar는 생성된 시점의 날짜 정보를 갖고 있다.
다른날의 날짜를 얻기 위해선 set을 사용
import java.util.Calendar;import java.util.GregorianCalendar;public class UseCalendar { public UseCalendar() { Calendar cal = Calendar.getInstance(); Calendar cal1 = new GregorianCalendar(); GregorianCalendar gc = new GregorianCalendar(); int year = cal.get(Calendar.YEAR); // 월, java에서는 월의 시작이 0월 int month = cal.get(Calendar.MONTH)+1; int day = cal.get(Calendar.DAY_OF_MONTH); // 올해 몇번째 날인지 int dayOfYear = cal.get(Calendar.DAY_OF_YEAR); System.out.printf("%d-%d-%d 오늘은 올해의 %d번째 날\n", year,month,day,dayOfYear); // 요일 : 일(1), 월(2), 화(3), 수(4), 목(5), 금(6), 토(7) int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); /*switch(dayOfWeek) { // case 1~7, 가독성이 낮다 case 1: System.out.println("일요일"); break; case 2: System.out.println("월요일"); break; case 3: System.out.println("화요일"); break; case 4: System.out.println("수요일"); break; case 5: System.out.println("목요일"); break; case 6: System.out.println("금요일"); break; case 7: System.out.println("토요일"); break; }*/ /*String week=""; // 상수 사용하여 가독성 향상 switch(dayOfWeek) { case Calendar.SUNDAY: week="일요일"; break; case Calendar.MONDAY: week="월요일"; break; case Calendar.TUESDAY: week="화요일"; break; case Calendar.WEDNESDAY: week="수요일"; break; case Calendar.THURSDAY: week="목요일"; break; case Calendar.FRIDAY: week="금요일"; break; case Calendar.SATURDAY: week="토요일"; break; } System.out.printf("%d요일 %s\n",dayOfWeek, week);*/ // 배열 활용하는 방식(권장) String[] weekTitle = { "일","월","화","수","목","금","토" }; System.out.printf("%d요일 %s요일\n",dayOfWeek, weekTitle[dayOfWeek-1]); // 오전(0) 오후(1) int amPm = cal.get(Calendar.AM_PM); // 상수 Calendar.AM, Calendar.PM을 이렇게 사용 /*switch(amPm) { case Calendar.AM: System.out.println("오전"); break; case Calendar.PM: System.out.println("오후"); break; }*/ // 배열로 String[] arrAmPm = { "오전", "오후" }; System.out.printf("%d %s\n",amPm, arrAmPm[amPm]); // 삼항연산자로 System.out.printf("%s\n", amPm == Calendar.AM ? "오전" : "오후"); // 시간 int hour = cal.get(Calendar.HOUR); // 12시간제 int hour24 = cal.get(Calendar.HOUR_OF_DAY); // 24시간제 System.out.printf("%d(%d)시\n", hour, hour24); int minute = cal.get(Calendar.MINUTE); int second = cal.get(Calendar.SECOND); System.out.printf("%d(%d):%d:%d\n",hour,hour24,minute,second); // Calendar는 생성된 시점의 날짜 정보를 가짐 // 다른 날짜를 얻기 위해선 set을 사용 System.out.println("-----------------------------------------------"); System.out.printf("설정 전 %d-%d-%d %s요일\n", cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH)+1, cal1.get(Calendar.DAY_OF_MONTH), "일,월,화,수,목,금,토".split(",")[cal1.get(Calendar.DAY_OF_WEEK)-1]); // 년 cal1.set(Calendar.YEAR, 2019); // 월 - 사람이 생각하는 월보다 1적게 설정 cal1.set(Calendar.MONTH, 4); // 일 - 해당월의 존재하지 않는 일자가 설정되면 자동으로 다음달로 넘어가 설정됨 cal1.set(Calendar.DAY_OF_MONTH, 32); System.out.printf("설정 후 %d-%d-%d %s요일\n", cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH)+1, cal1.get(Calendar.DAY_OF_MONTH), "일,월,화,수,목,금,토".split(",")[cal1.get(Calendar.DAY_OF_WEEK)-1]); System.out.println("-----------------------------------------------"); // 이번달의 마지막 날을 알 수 있는 getActualMaximum System.out.println(cal1.getActualMaximum(Calendar.DATE)); System.out.println(cal1.getActualMaximum(Calendar.DAY_OF_MONTH)); } public static void main(String[] args) { new UseCalendar(); }}
DecimalFormat
숫자 형식을 변경(1000(정수) -> 1,000(문자열))
java.text 패키지에 존재
패턴
오라클 0 - 자바 0
0으로 채우기
오라클 9 - 자바 #
존재하는 숫자만 출력
오라클보다 자바 format해주는게 좋은점은 오라클은 입력값이 패턴길이를 넘어가면 출력을 못하는 반면 자바는 입력값이 넘어가도 패턴을 적용시켜줌
// 1.생성DecimalFormat df = new DecimalFormat("패턴");// 2.사용df.format(패턴을적용할숫자);
public class UseDecimalFormat { public UseDecimalFormat() { int temp = 20181206; // 데이터가 없음 0을 채움 DecimalFormat df = new DecimalFormat("0,000,000,000"); // 데이터가 없으면 채우지 않음 DecimalFormat df1 = new DecimalFormat("#,###,###,###"); System.out.println("0사용 : "+df.format(temp)); // 0,020,181,206 System.out.println("#사용 : "+df1.format(temp)); // 20,181,206 DecimalFormat df2 = new DecimalFormat("#,###.00"); // 실수자릿수를 사용하면 마지막 뒷자리의 값이 // 반올림대상이라면 반올림한 결과를 보여준다. System.out.println("소수자리수 표현 : " +df2.format(201812.066)); // 201,812.07 } public static void main(String[] args) { new UseDecimalFormat(); }}
Random
java.util 패키지
다양한 난수를 뽑기 위해서 제작된 클래스
생성되면 모든 난수가 발생
패턴을 분석하면 다음 수 예측가능(보안에 취약)
// 1.생성Random r = new Random();// 2.난수얻기r.nextDouble(); // 실수난수(0~1 사이 실수)// 실수난수로 발생가짓수 내 정수난수를 얻을 때(int)(r.nextDouble()*발생가짓수); r.nextInt(); // 정수난수 (-2147483648~+2147483647 사이 랜덤값)// 발생가짓수 안에 랜덤한 값을 얻고자 할 때 아래와 같이하면// 음수도 나올 수 있다. 따라서 Math.abs()를 사용r.nextInt()%발생가짓수;Math.random(r.nextInt()%발생가짓수);// 오버로딩된 nextInt를 사용하면 발생가짓수-1의 // 임의의 양의 정수가 반환된다(권장)r.nextInt(발생가짓수);// 랜덤 Boolean값도 가질 수 있다.r.nextBoolean();
public class UseRandom { public UseRandom() { // 1.생성 Random r = new Random(); // 2.난수얻기 // 실수난수 double d = r.nextDouble(); System.out.println(d); System.out.println(d*5); System.out.println((int)(d*5)); System.out.println("-----------------------"); // 정수난수 int i = r.nextInt(); // 음수가 발생하므로 절대값처리 System.out.println(i); System.out.println(i%5); System.out.println(Math.abs(i%5)); // 양수처리 System.out.println("-----------------------"); int j = r.nextInt(5); // 음수가 발생하지 않는다. System.out.println(j); System.out.println("-----------------------"); // 불린난수 boolean b = r.nextBoolean(); System.out.println(b); } public static void main(String[] args) { new UseRandom(); }}
오토박싱 & 언박싱(autoboxing & unboxing)
jdk 1.5 이전에는 기본형과 참조형 간 연산 불가능했었음
래퍼 클래스로 기본형을 객체로 만들어 연산해야 했다.
jdk 1.5부터는 컴파일러가 자동으로 변환하는 코드를 넣어줌.
기본형 값을 래퍼 클래스의 객체로 자동변환해주는 것을 오토박싱(autoboxing), 반대로 변환하는 것을 언박싱(unboxing)이라 함
JCF(Java Collection FrameWork)
데이터를 다룰 때 사용(=자료구조)
java.util 패키지에서 제공
Collection 계열, Map
Collection 계열 = List, Set
가변길이형
데이터를 추가하면 크기가 늘어나고 삭제하면 크기가 줄어듦.
메모리를 효율적으로 사용
Generic과 같이 사용
Generic은 jdk 1.5에서 추가된 기능
jdk 1.4까지는 Object만 저장 가능했지만 jdk 1.5부터는 모든 값을 저장할 수 있다. (autoboxing, unboxing 지원)
Collection
List
1차원 배열처럼 생성, 사용
가변길이형
중복값 저장가능, 검색 기능이 있다
데이터가 순차적으로 입력됨
List 인터페이스를 구현한 클래스 존재
ArrayList, LinkedList, Vector
Set
1차원 배열처럼 생성, 사용
가변길이형
중복값 저장불가, 검색 기능이 없다
검색 기능이 없어 Iterator(포인터 객체)를 사용
데이터가 순차적으로 입력되지 않음
Set 인터페이스를 구현한 클래스 존재
HashSet
Map
2차원 배열처럼 생성
가변길이형
키와 값의 쌍(entry)으로 이루어진 데이터형
2차원 배열이지만 열은 2개
키는 중복될 수 없음, 값은 중복가능
데이터(<K,V>, entry)가 순차적으로 입력되지 않음
Map 인터페이스를 구현한 클래스 존재
Hashtable, HashMap
Generic (<>)
jdk 1.5부터 추가된 기능
JCF에서 입력데이터형의 제한을 설정할 때 사용
단일 데이터형으로 구성
Generic은 기본 데이터형으로는 설정할 수 없다
랩퍼클래스(wrapper class)로만 사용가능
기본형 데이터형을 객체로 생성하여 사용하는 클래스
값에 대해서 method를 호출하여 일을 더 할 수 있음
jdk 1.7부터는 객체 생성하는 쪽에 Generic은 데이터형을 생략가능
List arrList = new ArrayList();// 어떤 타입(기본형, 참조형)이든 담을 수 있다.arrList.add(12);arrList.add(12.32);arrList.add('A');arrList.add("문자열");arrList.add(new Date());// 일괄처리가능for(int i=0; i<arrList.size(); i++) { // 사용할 때 문제가 발생가능 => Generic 등장 배경 System.out.print(arrList.get(i)*10); //error!}// JCF클래스명<데이터형> 으로 Generic 사용// E - 해당 리스트에 저장할 elements 타입List<E> l = new ArrayList<>();
// Generic으론 참조형 데이터형만 들어올 수 있다// wrapper class를 이용하면 기본형데이터형을 담을 수 있음List<Integer> l = new ArrayList<>();// autoboxing (int -> Integer)// wrapper class로 생성 안해도 자동으로 참조형객체로 바꿔주는게 autoboxing// jdk 1.5이전 : l.add(new Integer(10)) // jdk 1.5+ : l.add(10); l.add(10); // unboxing (Integer -> int)// wrapper class의 값을 기본형데이터형 값으로 바꿔주는게 unboxing// jdk 1.5이전 :((Integer)l.get(0)).intValue()*10 // jdk 1.5+ : l.get(0)*10 으로 처리가능(generic을 썼기 때문에 형변환 불필요)System.out.println(l.get(0)*10);
List
상속 때문에 부모만 쓸 줄 알면 어떤 자식이든 사용이 가능해진다.
ArrayList 사용법만 알고도 Vector, LinkedList 모두 사용이 가능해짐
습득의 시간이 짧아진다.
// 1.생성// 객체다형성// List 공통 특징 - 데이터가 순차적으로 추가됨// ArrayList - Multi Thread에서 동시접근 가능(StringBuilder), 동기화 안됨List l = new ArrayList();// Vector - Multi Thread에서 동시접근 불가능(StringBuffer), 동기화 됨 List l1 = new Vector();// LinkedList - 데이터가 기존 데이터 사이에 추가되는 일이 많을 때 사용List l2 = new LinkedList();// 2.추가 add : 방의 개수가 증가l.add(값); // 속도가 가장 빠름(권장)l.add(인덱스, 값); // 원하는 인덱스에 추가(속도 느림)// 3.방의 개수 size (size !=여유공간(capacity))l.size();// 4.방의 값얻기 getl.get(인덱스);// 5.모든 방의 값for(int i=0; i<l.size(); i++) { System.out.println(l.get(i));}// 6.삭제 remove : 방의 개수가 감소l.remove(인덱스);l.remove(값);// 7.모든 방의 값 삭제 clearl.clear();// 8.리스트의 값을 배열로 복사 toArray (Generic이 된 경우만 복사가능)List<String> strList = new ArrayList<String>();strList.add("오");strList.add("영");strList.add("근");String[] strArr = new String[strList.size()];strList.toArray(strArr);
import java.util.List;import java.util.ArrayList;import java.util.Vector;import java.util.LinkedList;/*** List<br>* 중복값 허용하며 검색의 기능이 있고, 순서대로 값을 입력하는 가변길이형*/public class UseList { public UseList() { // jdk 1.4에서는 Generic이 제공되지 않고 객체만 저장됨 List list = new ArrayList(); // 값 추가 // jdk 1.5이하에서는 객체로만 값을 넣을 수 있음 list.add(new Integer(10)); list.add(new Short((short)10)); list.add(new String("공선의")); System.out.println("크기 "+list.size()); System.out.println(((Integer)list.get(0)).intValue()+10); // jdk 1.5+ 사용 : Generic, autoboxing, unboxing 사용가능 // Generic을 권장 List<Integer> list1 = new ArrayList<Integer>(); list1.add(10); // autoboxing list1.add(20); list1.add(new Integer(30)); // Generic으로 설정된 형이 아닌 데이터형은 추가할 수 없다. // list1.add("김건하"); System.out.println("크기 "+list1.size()); for(int i=0; i<list1.size(); i++) { System.out.print(list1.get(i)+" "); } System.out.println(); } // ArrayList 사용 : Multi Thread환경에서 동시 접근 가능(동기화 X) public void useArrayList() { // 1. 생성 ArrayList<String> al = new ArrayList<String>(); // capacity X(방 0개) List<String> al1 = new ArrayList<String>(100); // capacity O(방 100개) System.out.println(al+" / "+al1); // 값 추가 // 값은 순서대로 추가됨, 중복값 허용 al.add("이재현"); al.add("이재현"); al.add("김정윤"); al.add("노진경"); al.add("김정윤"); al.add("김정운"); al.add("공선의"); al.add("정택성"); System.out.println(al+" / "+al1); // size() : 데이터의 크기(size != capacity ) System.out.println("al 크기 : "+al.size()+" / al1 크기 : "+al1.size()); // 배열에 복사 String[] names = new String[al.size()]; al.toArray(names); // 복사된 배열 출력 System.out.println("---------- 복사된 배열 출력 ----------"); for(int i=0; i<names.length; i++) { System.out.printf("%s\t",names[i]); } System.out.println(); System.out.println("--------------------------------------"); // 방의 값 삭제 // -인덱스로 삭제 al.remove(5); System.out.println(al+" / "+al1); // -값으로 삭제 // 중복된 값이 존재 시 L->R로 진행하면서 // 일치하는 첫방의 값만 삭제 al.remove("김정윤"); System.out.println(al+" / "+al1); // 향상된 for문 출력 for(String name : al) { System.out.print(name+" "); } System.out.println(); // 모두 삭제 al.clear(); System.out.println("전체 삭제 후 size : "+al.size()+" / "+al); } // Vector, LinkedList는 같은 List를 구현했기 때문에 사용법 동일 public void useVector() { // 1. 생성 Vector<String> vec = new Vector<String>(); // capacity X(방 0개) List<String> vec1 = new Vector<String>(100); // capacity O(방 100개) System.out.println(vec+" / "+vec1); // 값 추가 // 값은 순서대로 추가됨, 중복값 허용 vec.add("이재현"); vec.add("이재현"); vec.add("김정윤"); vec.add("노진경"); vec.add("김정윤"); vec.add("김정운"); vec.add("공선의"); vec.add("정택성"); System.out.println(vec+" / "+vec1); // size() : 데이터의 크기(size != capacity ) System.out.println("vec 크기 : "+vec.size()+" / vec1 크기 : "+vec1.size()); // 배열에 복사 String[] names = new String[vec.size()]; vec.toArray(names); // 복사된 배열 출력 System.out.println("---------- 복사된 배열 출력 ----------"); for(int i=0; i<names.length; i++) { System.out.printf("%s\t",names[i]); } System.out.println(); System.out.println("--------------------------------------"); // 방의 값 삭제 // -인덱스로 삭제 vec.remove(5); System.out.println(vec+" / "+vec1); // -값으로 삭제 // 중복된 값이 존재 시 L->R로 진행하면서 // 일치하는 첫방의 값만 삭제 vec.remove("김정윤"); System.out.println(vec+" / "+vec1); // 향상된 for문 출력 for(String name : vec) { System.out.print(name+" "); } System.out.println(); // 모두 삭제 vec.clear(); System.out.println("전체 삭제 후 size : "+vec.size()+" / "+vec); } public void useLinkedList() { // 1. 생성 LinkedList<String> ll = new LinkedList<String>(); // LinkedList는 크기를 초기화 안함 List<String> ll1 = new LinkedList<String>(); System.out.println(ll+" / "+ll1); // 값 추가 // 값은 순서대로 추가됨, 중복값 허용 ll.add("이재현"); ll.add("이재현"); ll.add("김정윤"); ll.add("노진경"); ll.add("김정윤"); ll.add("김정운"); ll.add("공선의"); ll.add("정택성"); System.out.println(ll+" / "+ll1); // size() : 데이터의 크기(size != capacity ) System.out.println("ll 크기 : "+ll.size()+" / ll1 크기 : "+ll1.size()); // 배열에 복사 String[] names = new String[ll.size()]; ll.toArray(names); // 복사된 배열 출력 System.out.println("---------- 복사된 배열 출력 ----------"); for(int i=0; i<names.length; i++) { System.out.printf("%s\t",names[i]); } System.out.println(); System.out.println("--------------------------------------"); // 방의 값 삭제 // -인덱스로 삭제 ll.remove(5); System.out.println(ll+" / "+ll1); // -값으로 삭제 // 중복된 값이 존재 시 L->R로 진행하면서 // 일치하는 첫방의 값만 삭제 ll.remove("김정윤"); System.out.println(ll+" / "+ll1); // 향상된 for문 출력 for(String name : ll) { System.out.print(name+" "); } System.out.println(); // 모두 삭제 ll.clear(); System.out.println("전체 삭제 후 size : "+ll.size()+" / "+ll); } public static void main(String[] args) { UseList ul = new UseList(); System.out.println("************************ArrayList*************************"); ul.useArrayList(); System.out.println("************************Vector****************************"); ul.useVector(); System.out.println("************************LinkedList************************"); ul.useLinkedList(); }}
Stack
LIFO를 구현한 클래스
Last In First Out : 마지막으로 입력된 데이터가 마지막으로 나오는 자료구조.
Vector의 자식클래스
FIFO(First In First Out)
배열, List
부모의 기능을 사용하지 않는다.
사용하면 Stack이 아니게 된다(LIFO 특징을 잃게됨)
is-a 관계의 객체화를 하지 않는다.
상태를 저장할 때 (history기능) stack을 사용한다.
ctrl+z UNDO가 stack을 활용한 예
// stack 생성(is-a관계 객체화 안됨)Stack<String> stk = new Stack<String>();// 값넣기 push) 하나하나의 값을 item이라 함stk.push("정택성");stk.push("이재현");stk.push("김정운");stk.push("김정윤");// stack의 크기보다 많은 데이터를 넣으면 StackOverflow 예외가 발생// Vector클래스의 size()로 크기를 알 수 있다.// 값 얻기) 얻은 값은 stack에서 꺼내지기 때문에 두번 사용할 수 없다.stk.pop();// peek()을 사용하면 재사용 가능(삭제 안하고 가장 위에 값 얻어옴)stk.peek();// 비었는지 확인해서 boolean 반환stk.empty();// stack의 모든 item 꺼내기while(!stk.empty()) { System.out.println(stk.pop());}