on
21.07.28 DAY10 Java Utility API / Geniric / Collection Framework
21.07.28 DAY10 Java Utility API / Geniric / Collection Framework
Wrapper Class
기본 데이터형을 객체로 다루기 위한 포장 클래스
사용 이유
- 자바에서는 객체를 대상으로 처리하는 경우가 많음
- 특정 클래스는 객체만을 다루기 때문에 기본 데이터 형을 사용할 수 없음
- 문자열을 기본 타입값으로 변환할 때도 유용
- 그외, 다른 타입으로부터의 변환 등 유용한 유틸리티 메서드 제공
- new를 이용한 Wrapper 클래스 객체 생성은 Deprecated 되었음
- Java 9 이후부터는 내부의 static 메서드 valueOf를 이용하여 생성
타입간 변환, 대부분 static 메서드
문자열을 기본 데이터 값으로 변환 또는 그 반대
public static void main(String[] args) { // 기본타입과 1:1 매칭되는 포장클래스 Integer i = new Integer(2021); Character c = new Character('C'); // new 방식의 포장은 JDK 9 이후로 Deprecated // 앞으론 . vlaueof() 메서드르 사용해 포장 float f = f = Float.valueOf(3.14159F); Boolean b = Boolean.valueOf(true); // 문자열을 해당 데이터 타입으로 변환 하기 Integer i1 = Integer.valueOf(10); Double d1 = Double.valueOf(3.14159); Boolean b2 = Boolean.valueOf("false"); // 문자열의 형태가 해당 기본형의 형태를 갖추고 있어야함. // Float f2 = Float.valueOf("a123.456f"); // error // 자동 boxing Integer i2 = 10; // Integer i2 = Integer.valueOf(10); // parse 계열 메소드 : 변환 메소드 System.out.println(Integer.parseInt("-123")); // 문자열을 정수형으로 System.out.println(Integer.parseInt("FF", 16)); // 16진수 문자열을 정수형으로 System.out.println(Integer.toBinaryString(2021)); // 정수를 2진수 문자열 System.out.println(Integer.toHexString(2021)); // 정수를 16진수 문자열로 // 형변환 메서드 System.out.println(i2.doubleValue()); // 내부 데이터를 double로 변환 Integer i3 = Integer.valueOf(2021); Integer i4 = Integer.valueOf(2021); System.out.println(i3 == i4); // 다른 객체임을 주의 System.out.println(i3.equals(i4)); // 내부 값의 비교 System.out.println(i3.intValue() == i4.intValue()); // 언박싱 비교
Wrapper 클래스 – 박싱(boxing)과 언박싱(unboxing)
박싱 (boxing) : 기본 데이터를 Wrapper 클래스에 담는 것
- 언박싱 (unboxing) : 박싱의 반대
JDK 1.5부터는 박싱과 언박싱이 자동으로 수행됨
public class WapperClassTest { public static void main(String[] args) { Integer i = 10; System.out.println(i); int n = i + 10; System.out.println(n); } }
Java Utility API
자바 프로그램에서 필요로 하는 편리한 기능을 모아둔 클래스들의 패키지
- 클래스 이름 앞에 패키지 이름을 사용하지 않았다면, import를 명시적으로 해야하는 패키지
- 패키지 명은 java.util로 시작한다
Date 클래스
날짜와 시간에 관한 정보를 표현
- 많은 메서드들이 deprecated (폐지 예정)되고 Calendar 클래스에서 지원
- 현재는 Date() 생성자만 주로 사용하고, 날짜에 관련된 기능들은 Calendar 클래스를 이용한다.
- 만약 특정 포맷을 얻고 싶다면, DateFormat 클래스나 SimpleDateFormat 클래스를 임포트하여 사용한다.
Date Format String
SimpleDateFormat 클래스에 Time Format을 지정하여 원하는 형식의 날자 문자열을 얻을 수 있다
private static void dateEx() { // 날짜를 얻어온다. Date now = new Date(); // 현재 날짜와 시간 System.out.println(now); // 포매터 : 형식화 출력 DateFormat df = DateFormat.getDateInstance(DateFormat.FULL); System.out.println("FULL : " + df.format(now)); df = DateFormat.getDateInstance(DateFormat.LONG); System.out.println("Long :" + df.format(now)); // TODO: Datafornat을 midium, shor로 바꿔서 출력 포맷을 해보자 DateFormat dfm = DateFormat.getDateInstance(DateFormat.MEDIUM); System.out.println("MIDIUM : " + dfm.format(now)); DateFormat dfs = DateFormat.getDateInstance(DateFormat.SHORT); System.out.println("Short : " + dfs.format(now)); // simple data format SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("SDF : " + sdf.format(now)); }
Calendar 클래스
날짜와 시간에 관한 정보를 표현
- new로 객체를 생성할 수 없고, getInstance() 메서드를 이용, Calendar 객체를 얻어 사용
- 날짜와 시간 표현을 위한 다양한 상수 제공
Calendar 클래스의 주요 상수
Calendar 클래스 주요 메서드
private static void calenderEx() { Calendar now = Calendar.getInstance(); Calendar custom = Calendar.getInstance(); // 주의 월정보는 0부터 싲가 custom.set(1999, 11, 31); System.out.println("현재 :" + now); System.out.println("사용자 정의 : " + custom); // 캘린더에어 현재년도, 월, 일 // 캘린더 상수 사용 int year = now.get(Calendar.YEAR); int month = now.get(Calendar.MONTH) + 1; int date = now.get(Calendar.DATE); System.out.printf("오늘은 %d년 %d월 %d일 입니다.%n", year, month, date); // 100D일 후로 이동 Calendar future = Calendar.getInstance(); future.add(Calendar.DATE, 100); System.out.printf("100d일 후 : %d년 %d월 %d일 입니다", future.get(Calendar.YEAR), future.get(Calendar.MONTH) + 1, future.get(Calendar.DATE)); // 이날은 무슨 요일? int dow = future.get(Calendar.DAY_OF_WEEK); System.out.println(dow); String dowStr = null; switch (dow) { case Calendar.SUNDAY: dowStr = " 일요일"; break; case Calendar.MONDAY: dowStr = " 월요일"; break; case Calendar.TUESDAY: dowStr = " 화요일"; break; case Calendar.WEDNESDAY: dowStr = " 수요일"; break; case Calendar.THURSDAY: dowStr = " 목요일"; break; case Calendar.FRIDAY: dowStr = " 금요일"; break; case Calendar.SATURDAY: dowStr = " 트요일"; break; } System.out.println(dowStr);}
Generic class
클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법
(클래스 내부에서 사용할 데이터 타입을 나중에 인스턴스를 생성할 때 확정하여사용)
제네릭을 사용해야 하는 이유
- 객체의 타입을 컴파일시에 강하게 체크할 수 있음
- 형변환의 번거로움이 줄어든다
// generic 이용 public class GenericBox { T content; // 타입 미정 상태 public T getContent() { return content; } public void setContent(T content) { this.content = content; } } public class BoxApp { public static void main(String[] args) { IntegerBox iBox = new IntegerBox(); iBox.setContent(2021); System.out.println("iBox : "+iBox.getContent()); StringBox sBox = new StringBox(); sBox.setContent("String Box"); System.out.println("sBox : "+sBox.getContent()); // 모든 객체를 담을 수 있는는 상자 // 1.캐스팅을 반드시 해야함. //2. 캐스팅을 잘못하면 심각한 예외 발생 ObjectBox oBox = new ObjectBox(); oBox.setContent(2021); Integer i = (Integer) oBox.getContent(); System.out.println("Content : "+i); oBox.setContent("Sting Obj"); String s = (String) oBox.getContent(); // Integer i2 = (Integer) oBox.getContent(); // 캐스팅 오류 // generic // 설계시에 타입을 미정상태로 두고, 객체 생성시 실제 타입을 결정한다. GenericBox intBox = new GenericBox(); intBox.setContent(2021);//OK // intBox.setContent("STIRNG"); // int로 고정되어서 변경 불가 Integer i3 = intBox.getContent(); // System.out.println(i3); GenericBox strBox = new GenericBox(); strBox.setContent("String blabla"); // strBox.setContent(2021); // 컴파일러가 타입을 체크할 수 잇다. String s3 = strBox.getContent(); System.out.println(s3); // generic을 사용하면 생기는 장점: // 1. data type을 여러 타입에 대응하는 단일 클래스 를 설계할 수 있다. // 2. Type check를 컴파일러에게 맡길수 있다. 안전성의 확보 // 3. 불필요한 캐스팅을 피할 수 있다. } }
파라매터 갯수는 제한이 없다.
많이 사용되는 파라미터 관례:
T : type
R : Return type
K : key
V : value
Collection Framework
컬렉션 (Collection)
- 다수의 데이터, 즉 데이터 그룹을 의미( List + Set)
프레임워크 (Framework)
- 표준화, 정형화된 체계적인 프로그래밍 방식
컬렉션 프레임워크
- 컬렉션을 저장하는 클래스들을 표준화한 설계
- 다수의 데이터를 쉽게 처리할 수 있는 방법을 제공하는 클래스들로 구성
- JDK 1.2부터
컬렉션 클래스 (Collection Class)
- 다수의 데이터를 저장할 수 있는 클래스
- Vector, ArrayList, HashSet 등
Map : 사전 - 색인 / 키(key) - 값 (value) (key,value)쌍
배열 (Array) vs 리스트 (List)
Vector
객체만 저장할 수 있음
- Vector의 참조 결과는 항상 Object 타입 -> 적절한 Type으로 변환 후 사용
- Generics로 지정하지 않으면 여러 타입을 동시에 저장 가능
- 꺼낸 객체의 타입을 알고 있어야 함
- 혹은 instanceof 연산자로 확인 후 사용
Vector 클래스 메서드 (Method) 생성자 Vector() / Vector(int capacity) 개체 추가 addElement(Object o) / insertElementAt(Object o, int index) 개체 참조 elementAt(int index) 역개체참조 indexOf(Object o) 개체 변경 setElementAt(Object o, int index) 개체 삭제 remove(Object o) / remove(int index); 객체 검색 contains(Object o) 크기와 용량 size() / capacity() 비우기 clear() 복사 clone()
Vector 반복자
Enumeration : 벡터와 해시테이블에 존재하는 요소들에 대한 접근방식을 제공해주는 인터페이스
- 자바에서 제공하는 컬렉션에 대해 각 컬렉선의 항목들을 순차적으로 접근하는데 사용
- hasMoreElements()와 nextElement() 두 개의 메서드 제공
- Vector::elements()
- Hashtable::keys()
- Hashtable::values()
public class VectorEx { public static void main(String[] args) { // 벡터 생성 // 벡터 - 버퍼기반 Vector v = new Vector<>(); // 기본 버퍼 용량 10 // new Vector<>(용량) System.out.printf("Size : %d, Capacity : %d%n", v.size(), v.capacity()); for (int i = 1; i <= 10; i++) { v.addElement(i); // 항목 추가 } System.out.printf("Size : %d, Capacity : %d%n", v.size(), v.capacity()); v.addElement(11); // 허용량 초과 -> 버퍼 자동 증가 System.out.printf("Size : %d, Capacity : %d%n", v.size(), v.capacity()); System.out.println("v:" + v); // 중간에 값넣기 v.insertElementAt(100, 7); System.out.println("v:" + v); // 객체 조회 : 찾는 인덱스으 객체를 반환한다. int value = v.elementAt(7); System.out.println("인덱스7의 객체:" + value); // 객체의 인덱스 조회 System.out.println("7의 인덱스 :" + v.indexOf(7)); System.out.println("0의 인덱스 :" + v.indexOf(0)); // 없는 객체의 인덱스는 - 1); // 객체 포함 여부 System.out.println("100을 포함? " + v.contains(100)); // 객체 삭제 v.removeElement(100); // 객체 삭제 System.out.println("v:" + v); v.removeElementAt(7); // 인덱스 7의 요소 삭제 System.out.println("v:" + v); v.setElementAt(100, 4); // 인덱스 4의 요소를 변경 System.out.println("v:" + v); for (int i = 0; i < v.size(); i++) { Integer item = v.elementAt(i); System.out.print(item + " "); } System.out.println(); // enhanced for for (Integer item : v) { System.out.print(item + " "); } System.out.println(); // Enumeration : 반복자 // 순서대로 요소를 받아오고자 할때 반복자가 더 효율적이다. Enumeration e = v.elements(); // 반복자 획득 while (e.hasMoreElements()) { // 뒤에 요소가 남아있는지 확인, 뒤에 없으면 false Integer item = e.nextElement(); System.out.print(item + " "); } System.out.println(); } }
Linked List
링크(Link)로 연결된 노드(Node)의 집합
- java.util.LinkedList
- 임의의 객체를 리스트로 저장하는 기능을 제공
- Index를 통한 참조 접근은 불가
- Head로부터 링크를 따라가면서 접근
- 각 노드는 자신이 나타내는 데이터와 다음 노드(Node)로의 링크(Link)를 가지고 있음
새로운 노드 추가
기존 노드 제거
Iterator: Collection Framework로 확장하면서 도입 (List, Set 등)
자바에서 제공하는 컬렉션에 대해 각 컬렉선의 항목들을 순차적으로 접근하는데 사용
Iterator
- hasNext(), next(), remove() 제공
- Set::iterator()
- List::iterator()
Array List
java.util.ArrayList에 구현
- Vector, LinkedList, ArrayList 모두 추상 클래스 AbstractList를 상속받은 동적 자료 구조
- 배열을 다루는 것과 유사한 방식으로 동적 자료 구조를 사용할 수 있게 함
- add(int index, E element), set(int index, E element), get(int index), remove(intindex) methods
- Vector vs List : 항목 삽입, 삭제 동작이 동기화(synchronization) 여부의 차이
- Vector : 동기화된 삽입 삭제 동작 제공
- List : 삽입과 삭제가 동기화 되어 있지 않음 – 외부적 동기화 필요
ArrayList는 LinkedList와 동작 방식은 같으나 내부 구현 방식이 다르다
- ArrayList는 중간에 객체가 삭제되면 뒤의 객체들을 당겨, 인덱스를 재구성한다.
- 따라서 마지막 인덱스에 객체가 추가되는 속도는 LinkedList보다 빠르지만 중간에 객체의 추가, 삭제가 빈번하게 일어나는 경우는 속도 저하가 일어나게 된다.
하고자 하는 작업에 적합한 자료구조를 택해 개발!
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListEx { public static void main(String[] args) { // 3ktue5je // List lst = new LinkedList<>(); List lst = new ArrayList<>(); // 객체추가 :add - 맨 뒤에 새 요소 추가 lst.add("Java"); lst.add("C"); lst.add("C++"); lst.add("Python"); lst.add("Java"); System.out.println("lst : " + lst); // List 는 순서가 있고, 중복 요소를 허용한다. lst.add(3, "C#"); // insert System.out.println("insert : " + lst); // 요소의 갯수 System.out.println("size : " + lst.size()); // capacity는 없다. // 요소의 삭제 lst.remove(3);// 인덱스로 삭제 System.out.println("remove : " + lst); lst.remove("Python"); // 객체로 삭제 System.out.println("remove : " + lst); // 반복자 : List에서는 Iterator이용 Iterator iter = lst.iterator(); while (iter.hasNext()) { String item = iter.next(); System.out.print(item + " "); } System.out.println(); // 리스트 비우기 lst.clear(); System.out.println("lst : " + lst); } }
Stack
java.util.Stack 클래스로 제공, Vector 클래스를 상속받아 구현
- 한쪽 끝점에서만 새로운 항목을 삽입, 기존 항복을 제거할 수 있음
- Last In First Out (LIFO)
- 쌓여있는 접시 : 새로운 접시를 위에 쌓거나 가장 위의 접시부터 사용 가능
- 스택에서의 메서드들
- push() – 스택에 객체를 넣음
- pop() – 스택에서 객체를 추출(top은 삭제)
- peek() – pop과 같지만, top 값을 삭제하지 않는다
- empty() – 스택이 비었는지 확인
import java.util.Stack; public class StackEx { public static void main(String[] args) { // Stack 생성 // Last in - Fisrt out Stack stack = new Stack<>(); for (int i = 0; i < 5; i++) { stack.push(i); System.out.println("Stack" + stack); } // 가장 위쪽 데이터 확인 System.out.println(stack.peek()); // while (true) { while (!stack.empty()) { System.out.println("POP:" + stack.pop()); // 가장 마지막 입력 데이터 추출 System.out.println("Stack" + stack); } } }
Queue
- java.util.Queue 클래스로 제공 (interface)
- 목록의 가장 마지막에 새로운 항목이 추가
- 기존 항목의 제거는 리스트의 처음에서 일어남
- First In First Out (FIFO)
- 큐에서의 메서드들
- offer()
- poll()
- peek()
import java.util.LinkedList; import java.util.Queue; public class QueueEx { public static void main(String[] args) { // queue : 선입 선출 First in First o Queue qu = new LinkedList<>(); // 데이터 제공하기 for (int i = 0; i < 5; i++) { qu.offer(i); // enqueue System.out.println("QUEUE : " + qu); } // 가장 먼저 입력된 데이터 확인 System.out.println("PEEK : " + qu.peek()); System.out.println("QUEUE : " + qu); while (!qu.isEmpty()) { System.out.println("Poll : "+qu.poll());// dequeue System.out.println("QUEUE : " + qu); } } }
from http://jaemin-lim.tistory.com/32 by ccl(A) rewrite - 2021-08-11 10:26:26