야나도 프로젝트

나도 개발자 될수있어

JAVA

Java Utility API / Geniric / Collection Framework

jmeen 2021. 8. 11. 10:03
728x90

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> {
	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<Integer> intBox = new GenericBox();
		intBox.setContent(2021);//OK
//		intBox.setContent("STIRNG");  // int로 고정되어서 변경 불가
		
		Integer i3 = intBox.getContent();  // 
		System.out.println(i3);
		
		GenericBox<String> 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<Integer> 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<Integer> 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<String> lst = new LinkedList<>();
		List<String> 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<String> 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<Integer> 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<Integer> 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);
		}

	}

}