Java 기본 API

김찬희·2023년 2월 24일
0

KH정보교육원

목록 보기
11/27

▶ String 관련 클래스

√ String 클래스
문자열 값 수정 불가능, immutable(불변)
수정 시 수정된 문자열이 새로 할당 되어 새 주소를 넘김
√ StringBuffer 클래스
문자열 값 수정 가능, mutable(가변)
수정, 삭제 등이 기존 문자열에 수정되어 적용
기본 16문자 크기로 지정된 버퍼를 이용하며 크기 증가 가능
쓰레드 safe기능 제공(성능 저하 요인)
√ StringBuilder 클래스
StringBuffer와 동일하나 쓰레드 safe기능을 제공하지 않음
√ StringTokenizer 클래스
String클래스에서 제공하는 split()메서드와 같은 기능을 하는 클래스로 생성 시 전달받은 문자열을 구분자로 나누어 각 토큰에 저장
√ 예시

import java.util.*;

public class TestStringTokenizer {
	public static void main(String[] args) {
    	String str = "AA|BB|CC";
        StringTokenizer st = new StringTokenizer(str, "|");
        while(st.hasMoreTokens()) {
        	System.out.println(st.nextToken());
        }
    }
}

▶ Wrapper 클래스

primitive Data Type을 객체화 해주는 클래스
-(proxy 패턴) 대신, 대체

√ String을 기본 자료형으로 바꾸기
casting : 같은 유형 끼리 변환
parsing : 다른 유형으로 변환

byte b = Byte.parseByte("1");
short s = Short.ParseShort("2");
int i = Integer.parseInt("3");
long l = Long.parseLong("4");
float f = Float.parseFloat("0.1");
double d = Double.parseDouble("0.2");
boolean bool = Boolean.parseBoolean("true");
char c = "abc".charAt(0);

√ 기본 자료형을 String으로 바꾸기
String b = Byte.valueOf((byte)1).toString();
String s = Short.valueOf((short)2).toString();
String i = Integer.valueOf(3).toString();
String l = Long.valueOf(4L).toString();
String f = Float.valueOf(0.1f).toString();
String d = Double.valueOf(0.2).toString();
String bool = Boolean.valueOf(true).toString();
String ch = Character.valueOf('a').toString();

▶ 날짜 관련 클래스

√ Date 클래스
시스템으로부터 현재 날짜, 시간 정보를 가져와서 다룰 수 있게 만들어진 클래스
생성자 2개와 몇 개의 메서드만 사용 가능하고 나머지는 모두 deprecatedCalendar 클래스 혹은 GregorianCalendar 클래스 사용 권장
√ 예시

Date today = new Date();
// 시스템으로부터 현재 날짜, 시간 정보를 가져와 기본 값으로 사용
Date when = new Date(123456789L);
// long형 정수 값을 가지고 날짜 시간 계산
// 1970년 1월 1일 0시 0분 0초를 기준으로 함

√ Calendar 클래스
Calendar클래스는 생성자가 protected이기 때문에 new연산자를 통해 객체 생성 불가능
getInstance() 메서드를 통해서 객체 생성
√ GregorianCalendar 클래스
GregorianCalendar클래스는 Calendar클래스의 후손 클래스
년, 월, 일, 시, 분, 초 정보를 필드를 이용하여 다룰 수 있음

▶ Format 관련 클래스

√ SimpleDateFormat 클래스
Date의 날짜, 시간 정보를 원하는 format으로 출력하는 기능 제공
java.text 패키지에 속해있음
√ 예시

Date today = new Date();
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
String ftToday = ft.format(today);
// today에 포맷을 적용한 결과를 문자열로 리턴
package edu.kh.api.run;

import edu.kh.api.view.APIView;

public class APIRun {

	public static void main(String[] args) {
		
		APIView view = new APIView();
		
		view.displayMenu();
	}
}
package edu.kh.api.dto;

public class Student {

	private int grade;
	private int classRoom;
	private int number;
	private String name;
	
	// 기본 생성자
	public Student() {}
	
	// 매개변수 생성자
	public Student(int grade, int classRoom, int number, String name) {
		this.grade = grade;
		this.classRoom = classRoom;
		this.number = number;
		this.name = name;
	}
	
	// getter / setter
	public int getGrade() {
		return grade;
	}
	public void setGrade(int grade) {
		this.grade = grade;
	}
	public int getClassRoom() {
		return classRoom;
	}
	public void setClassRoom(int classRoom) {
		this.classRoom = classRoom;
	}
	public int getNumber() {
		return number;
	}
	public void setNumber(int number) {
		this.number = number;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	// toString() 오버라이딩
	@Override
	public String toString() {
		return String.format("%d / %d / %d / %s", grade, classRoom, number, name);
	}
	
	// Object.equals() 오버라이딩
	// -> 현재 객체와 다른 객체가 동등(필드 값이 같은지) 비교
	// -> 필드를 가지고 있는 자식 클래스
	//    알맞은 형태로 재정의(오버라이딩)
	@Override
	public boolean equals(Object obj) {
		
		// 같은 객체를 참조할 경우
		if(this == obj) return true;
		
		// null인 경우 비교 자체가 불필요
		if(obj==null) return false;
		
		// 비교를 위해 전달받은 객체는 Student가 맞는가?
		// false인 경우 실행
		if(!(obj instanceof Student)) return false;
			
		// 필드 비교
		Student other = (Student)obj;  // obj 다운 캐스팅
		if(this.grade != other.grade) return false;
		if(this.classRoom != other.classRoom) return false;
		if(this.number != other.number) return false;
		if(!this.name.equals(other.name)) return false;
		
		
		return true;  // 모든 필드가 같을 경우
	}
	
	
	// Object.hashCode()
	// - 두 객체의 필드 값이 같다면 
	//   hashCode()도 똑같은 정수 값을 반환해야 한다.

	// - hash 함수 : 입력 받은 문자열/숫자를
	//               특정한 길이의 문자열/숫자로 변환
	//               --> 최대한 중복되지 않는 숫자를 만들어냄
	
	// hashCode() : 객체의 필드 값을 이용해서
	//              일정한 길이의 숫자를 만드는 함수
	
	// 왜 필요한가? Java 실행 시 내부에서 객체 검색하는 속도 증가
	
	// 어떻게 작성하는가?
	// 필드 값이 같다면 항상 같은 수가 나올 수 있도록 구현
	// + equals() 오버라이딩 시 필수적으로 같이 오버라이딩
	
	@Override
	public int hashCode() {
		int result = 1;
		final int PRIME = 31;  // 소수 (곱연산 시 속도가 빠름)
		
		result = result * PRIME + grade;
		result = result * PRIME + classRoom;
		result = result * PRIME + number;
		result = result * PRIME 
				+ (name==null ? 0 : name.hashCode());    
		
		return result;
	}
}
package edu.kh.api.service;

import edu.kh.api.dto.Student;

public class APIService {

	// API (Application Programming Interface)
	//         응용     프로그래밍    접점
	// -> 프로그래밍 언어가 이미 가지고 있는 클래스/기능/기술을
	//    사용자가 쉽게 사용할 수 있도록 제공하는 것
	
	private Student[] studentList = new Student[10];
	
	public APIService() {
		studentList[0] = new Student(1, 1, 1, "김영희");
		studentList[1] = new Student(2, 3, 4, "홍길동");
		studentList[2] = new Student(3, 5, 12, "박민지");
	}
	
	// alt + shift + j
	/**학생 추가 서비스
	 * @param grade
	 * @param classRoom
	 * @param number
	 * @param name
	 * @return 추가 성공 시 true / 실패 시 false
	 */
	public boolean addStudent(int grade, int classRoom, int number, String name) {
		int index = 0;  // 비어있는 index 저장
		for(Student s : studentList) {
			if(s==null) break;
			boolean check1 = s.getGrade() == grade;
			boolean check2 = s.getClassRoom() == classRoom;
			boolean check3 = s.getNumber() == number;
			boolean check4 = s.getName().equals(name);
			
			// 학생 배열에 입력 받은 학생이 존재 한다면
			if(check1&&check2&&check3&&check4) return false;
			
			index++;
		}
		// 학생 배열에 학생이 가득 찬 경우
		if(index == studentList.length) return false;
		
		// 지정된 index에 학생 추가
		studentList[index] = new Student(grade, classRoom, number, name);
		return true;
	}
	
	/**학생 추가 서비스2 (equals / hashCode 사용)
	 * @param grade
	 * @param classRoom
	 * @param number
	 * @param name
	 * @return 추가 성공 시 true / 실패 시 false
	 */
	public boolean addStudent2(int grade, int classRoom, int number, String name) {
		
		// 1. equals()를 이용한 비교
		
		// 1) 전달 받은 값을 임시 학생 객체 생성
		Student temp = new Student(grade, classRoom, number, name);
		
		// 2) 학생 배열을 순차 접근하면서 동등한 학생이 있는지 검사
		int index = 0;
		for(Student s : studentList) {
			if(s == null) break;
			
			// s가 참조하는 학생과
			// temp가 참조하는 학생의
			// 필드 값이 같을 경우(동등한 경우)
			// if(s.equals(temp)) return false;
			
			System.out.println(s.hashCode());
			System.out.println(temp.hashCode());
			System.out.println("-----------------------");
			
			// hashCode()가 같다 == 필드가 같다 == 중복되는 학생이다
			if(s.hashCode() == temp.hashCode()) return false;
			
			
			index++;
		}
		
		// 3) 학생 배열에 학생이 가득 찬 경우
		if(index == studentList.length) return false;
		
		// 4) 임시 학생 객체를 학생 배열에 추가
		studentList[index] = temp;
		
		
		return true;
	}
	
	
	/**학생 배열에서 이름 검색
	 * @param input
	 * @return 일치하는 학생이 있으면 Student[]
	 *         없으면 null
	 */
	public Student[] selectName(String input) {
								// 김영희
								// 손흥민,김영희,박민지
		
		// String.split([구분자]) : 문자열을 구분자를 기준으로 나누어
		//							String[] 형태로 반환
		
//		String[] names = input.split(",");
		String[] names = input.split(",|/");  // , 또는 / 를 기준으로 구분
		
		
		// 검색된 학생을 저장할 배열
		Student[] result = new Student[studentList.length];
		
		int index = 0;  // result 배열에 저장될 위치를 지정할 변수
		
		for(String n : names) {
			for(Student s : studentList) {
				if(s==null) break;
				
				// 입력받은 이름이랑 학생의 이름이 같다면
				if(s.getName().equals(n)) {
					result[index++] = s;
				}
			}
		}
		if(index==0) {
			return null;
		}
		// 검색된 학생이 있으면 검색 결과를 저장한 배열 반환
		return result;
	}
	
	
	/**모든 학생 이름을 하나의 문자열로 반환
	 * @return
	 */
	public String printName() {
		// [김영희, 홍길동, 박민지, null, null, null, null, null, null, null]
		
		int size = 0;
		
		// 현재 학생의 수 구하기
		for(Student s : studentList) {
			if(s==null) break;
			size++;
		}
		
		// 이름만 저장할 배열 생성
		String[] names = new String[size];
		
		for(int i=0;i<size;i++) {
			names[i] = studentList[i].getName();
		}
		// String.join("구분자", String[])
		// -> String[]의 요소를 하나의 문자열로 합침
		//    단, 요소 사이사이에 "구분자" 추가
		
		// ex) String[] arr = {"aaa", "bbb", "ccc"};
		//     Stirng.join("@", arr);
		//     -> "aaa@bbb@ccc"
		return String.join("<>", names);
	}
}
package edu.kh.api.view;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;

import edu.kh.api.dto.Student;
import edu.kh.api.service.APIService;

public class APIView {

	private Scanner sc = new Scanner(System.in);
	
	private APIService service = new APIService();
	
	public void displayMenu() {
		int input = 0;
		
		do {
			System.out.println("--- API 테스트 프로그램 ---");
			System.out.println("1. equals() + hashCode() ");
			System.out.println("2. String 클래스 제공 메서드1(split)");
			System.out.println("3. String 클래스 제공 메서드2(join)");
			System.out.println("4. String 클래스의 특징, 문제점");
			System.out.println("5. StringBuffer/Builder");
			System.out.println("6. 문자열을 계속 입력 받아 한번에 출력하기");
			System.out.println("7. Wrapper Class");
			System.out.println("8. Date 클래스");
			
			System.out.println("0. 프로그램 종료");
			
			System.out.print("메뉴 선택 : ");
			try {
				input = sc.nextInt();
				sc.nextLine(); // 버퍼에 남은 개행문자 제거
				
				switch(input) {
				case 1 : ex1(); break;
				case 2 : ex2(); break;
				case 3 : ex3(); break;
				case 4 : ex4(); break;
				case 5 : ex5(); break;
				case 6 : ex6(); break;
				case 7 : ex7(); break;
				case 8 : ex8(); break;
				case 0 : break;
				default: System.out.println("메뉴에 존재하는 번호만 입력 해주세요.");
				}
				
			} catch(InputMismatchException e) {
				// Scanner 입력이 잘못된 경우
				System.out.println("잘못된 형식을 입력 하셨습니다. 다시 시도해주세요.");
				
				sc.nextLine();  // 입력 버퍼에 남아있는 
								// 잘못 입력된 문자열을 읽어와 없앰
				
				input = -1;  // input값에 0이 아닌 값을 대입하여
							 // while이 종료되지 않게함
			}
		} while(input!=0);
	}
	
	private void ex1() {
		
		// 한 학생의 정보를 입력받아 Service의 학생 배열에 추가 
		// 단, 중복되는 학생은 제외
		System.out.println("\n--- 학생 정보 입력---\n");
		System.out.print("학년 : ");
		int grade = sc.nextInt();
		System.out.print("반 : ");
		int classRoom = sc.nextInt();
		System.out.print("번호 : ");
		int number = sc.nextInt();
		sc.nextLine();  // 입력 버퍼에 남아있는 개행문자 제거
		System.out.print("이름 : ");
		String name = sc.nextLine();
		
		
		if(service.addStudent2(grade, classRoom, number, name)) {
			System.out.println("[추가되었습니다]");
		} else {
			System.out.println("중복되는 학생이 존재하거나 배열이 가득 찼습니다.");
		}
		
		
		
	}
	
	public void ex2() {
		// 이름을 여려명을 한 줄로 입력 받아
		// 학생 배열에 같은 이름의 학생이 있다면 출력
		System.out.println("\n--- 학생 검색 ---\n");
		
		System.out.println("검색할 이름(여러 명 검색 시 / 또는 , 로 구분) : ");
		// 손흥민,김영희,박찬호
	
		Student[] result = service.selectName(sc.nextLine());
		
		if(result == null) {
			System.out.println("[검색 결과가 없습니다]");
		}else {
			for(Student s : result) {
				if(s==null) break;
				System.out.println(s.toString());
			}
		}
	}
	
	public void ex3() {
		System.out.println("\n--- 모든 학생 이름 출력 ---\n");
		
		System.out.println(service.printName());
	}
	
	
	public void ex4() {
		// String 특징, 문제점
		
		// 1. String 객체 생성 방법
		String s1 = new String("abc");  // Heap 메모리 영역에 String 객체 생성
		
		String s2 = "abc";  // String은 사용 빈도가 높기 때문에
							// 별도의 리터럴 표기법을 부여하여 쉽게 객체 생성
							// -> Heap 영역 중 String Pool에 객체 생성

		String s3 = "abc";
		
		// hashCode() : 필드값이 같으면 같은 수
//		System.out.println(s1.hashCode());
//		System.out.println(s2.hashCode());
//		System.out.println(s3.hashCode());
		
		// System.identityHashCode(객체주소)
		// -> 객체 주소를 이용해서 만든 정수를 반환
		System.out.println("s1 : " + System.identityHashCode(s1));
		System.out.println("s2 : " + System.identityHashCode(s2));
		System.out.println("s3 : " + System.identityHashCode(s3));
		
		// "abc"
		s3 += "def";  // "abcdef"
		
		System.out.println("-----------------------");
		System.out.println("s2 : " + System.identityHashCode(s2));
		System.out.println("s3 : " + System.identityHashCode(s3));
		// 왜 값이 달라졌을까??
		
		// String은 불변성(한 번 저장된 값은 변할 수 없음) 특징 때문에
		// String 값을 변경할 경우
		// 기존 객체가 변경되는 것이 아닌
		// 새 객체를 생성해서 참조하게 된다.
	}
	
	private void ex5() {
		System.out.println("\n--- StringBuffer/Builder ---\n");
		
		// StringBuffer, StringBuilder 두 클래스는 제공하는 메서드가 동일하다
//		StringBuffer sb = new StringBuffer();
		StringBuilder sb = new StringBuilder();
		
		// StringBuffer.capacity() : 현재 버퍼의 크기
		System.out.println(sb.capacity());
		
		System.out.println("현재 주소 : " + System.identityHashCode(sb));
		
		// StringBuffer.append(문자열)
		// StringBuffer 객체에 문자열을 기존 데이터 뒤에 붙임
		sb.append("abc");
		
		// StringBuffer.toString()
		// - StringBuffer에 저장된 문자열을 String 형태로 반환
		System.out.println("sb에 저장된 문자열 : " + sb.toString());
		
		System.out.println("abc 추가 후 주소 : " + System.identityHashCode(sb));
		
		sb.append("def");
		System.out.println("sb에 저장된 문자열 : " + sb.toString());
		System.out.println("abc 추가 후 주소 : " + System.identityHashCode(sb));
		
		// 새로운 문자열이 추가되어도
		// 객체의 주소는 변하지 않음 == 가변성(mutable)
		// -> 문자열 수정 시 새로운 객체를 생성하지 않아
		//    메모리 소비를 절약할 수 있다.
		
		// insert(인덱스, 문자열) : 중간 삽입
		
		sb.insert(2, "@");
		System.out.println(sb.toString());
		
		// delete(int start, int end) : 삭제(start 이상 end 미만) 
		sb.delete(3, 5);  // ab@ cd ef
		System.out.println(sb.toString());
		
		System.out.println(sb.length());
		
		// replace(int start, int end, String str)
		// - start 이상 end 미만을 str로 변경
		sb.replace(0, 2, "AB");
		System.out.println(sb.toString());
	}
	
	private void ex6() {
		System.out.println("\n--- 문자열을 계속 입력 받아 한번에 출력하기 ---\n");
		
		StringBuffer sb = new StringBuffer();
		
		System.out.println("문자열 입력 (종료를 원할 경우 !wq 입력)");
		
		String str = null;
		while(true) {
			// sc.nextLine(); : 한 줄을 입력 받아 String 반환
			// sb.append(String str) : 기존 문자열 뒤에 추가
			str = sc.nextLine();
			
			// 입력 종료를 원하는 경우
			if(str.equals("!wq")) {
				break;
			}
			sb.append(str);
			sb.append("\n");  // \n : 개행문자 (new line)
		}
		
		// delete()를 이용해 마지막 문자열 제거
		sb.delete(sb.length()-1, sb.length());
		
		System.out.println("----- 입력 받은 내용 -----");
		System.out.println(sb.toString());
	}
	
	
	private void ex7() {
		System.out.println("\n--- Wrapper Class ---\n");
		
		/* Wrapper Class
		 * - 기본 자료형을 객체로 다룰 수 있도록 포장하는 클래스
		 * 
		 * 왜 포장이 필요한가?
		 * 1) 기본 자료형이 제공하지 않는 추가 필드, 메서드 제공하기 위해
		 * 2) 기본 자료형을 객체로 다뤄야 하는 경우가 있기 때문에
		 *    (컬렉션)
		 * */
		
		// Integer(+ 모든 Wrapper 클래스) 제공 상수 필드
		System.out.println(Integer.BYTES);  // byte 단위 크기 
		System.out.println(Integer.SIZE);  // bit 단위 크기
		System.out.println(Integer.MAX_VALUE);  // 자료형 최대값
		System.out.println(Integer.MIN_VALUE);  // 자료형 최소값
		System.out.println(Integer.TYPE);  // Wrapper 클래스 대상 타입
		
		// String을 기본자료형으로 변환
		int i = Integer.parseInt("100") + 50;
		System.out.println("i = " + i);
		
		long l = Long.parseLong("10000000000") + 10_000_000_000L;
		System.out.println("l = " + l);
		
		double d = Double.parseDouble("3.1415926534") + 10.0;
		System.out.println("d = " + d);
		
		// 기본 자료형 -> String 변환
		String str1 = Integer.valueOf(123).toString();
		String str2 = 999 + "";
		// "" : 빈 문자열 (내용이 없는 길이 0짜리 String)
		
		// Wrapper Class를 이용하여 객체 생성
		Integer iNum1 = new Integer(10);
		
		int iNum2 = iNum1;
		// (int)  = (Integer) -> (int)  [AutoUnboxing]
		System.out.println("iNum2 : " + iNum2);
		
		Integer iNum3 = 50;
		// (Integer) = (int) -> (Integer)  [AutoBoxing]
		
		/* Boxing / Unboxing
		 * Boxing : 기본 자료형 -> Wrapper Class 객체
		 * Unboxing : Wrapper Class 객체 -> 기본 자료형
		 * 
		 * AutoBoxing / AutoUnboxing
		 * - 사용자가 신경쓰지 않아도 
		 *   상황에 따라 기본 자료형 <-> Wrapper Class 객체로 
		 *   자동으로 변하는 기술
		 * */
	}
	
	private void ex8() {
		System.out.println("\n--- Date Class ---\n");
		
		// java.util.Date
		Date d1 = new Date();  // 기본 생성자
							   // 객체 생성 시점의 시간 저장
		System.out.println(d1.toString());
		
		Date d2 = new Date(0L);  // Date(long date)
								 // Date 기준 시간으로 부터
								 // ms 단위로 지난 시간을 계산해서 저장
		System.out.println(d2.toString());
		// Thu Jan 01 09:00:00 KST 1970
		
		Date d3 = new Date(1000L); 
		System.out.println(d3.toString());
		
		// System.currentTimeMillis()
		// -> 기준 시간으로 부터 지난 시간 (ms)
		System.out.println("현재시간 - 기준시간 (ms) : " + System.currentTimeMillis());
		
		// 현재 시간으로 부터 1시간 후를 저장
		long temp = 60 * 60 * 1000;  // 3600000 ms == 1시간
		//          분   초    ms
		Date d4 = new Date(System.currentTimeMillis() + temp);
		System.out.println(d4.toString());
		
		// SimpleDateFormat : 간단하게 날짜 형식을 지정하는 객체
		// java.text 패키지에서 제공
		SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sdf2 = new SimpleDateFormat("G yyyy년 MM월 dd일 HH시 mm분 ss초");
		SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy년 MM월 dd일 E요일 a HH시 mm분 ss초");
		
		System.out.println(sdf1.format(d4));
		System.out.println(sdf2.format(d4));
		System.out.println(sdf3.format(d4));
	}
}
profile
김찬희입니다.

0개의 댓글