12.7 수학 클래스 (이어서)

random() 메소드는 0.0 ~ 1.0 사이의 double 타입 난수를 리턴.

→ API Document 검색, 생성자 부분 살펴보기

객체 생성 설명
Random() 현재 시간을 이용하여 종자값을 자동 설정
Random(long seed) 주어진 종자값을 사용

 

리턴값 메소드(매개변수) 설명
boolean nextBoolean() boolean 타입의 난수 리턴
double nextDouble() double 타입의 난수 리턴(0.0<= ~ <1.0)
int nextInt() int 타입의 난수 리턴(-2의32승<= ~ <=+2의32승
int nextInt(int n) int 타입의 난수 리턴(0<= ~ <n)

 

public class Arrays → 배열을 사용하는 정적 메소드를 모아놓은 클래스이다.

Arrays.sort(배열) → 항목 오름차순 정렬

> 로또번호 실습 예제

int[] selectNum = new int[6];
Random random = new Random(5);

for(int i=0; i<6; i++) {
    selectNum[i] = random.nextInt(45) + 1;
    System.out.print(selectNum[i] + " ");
}

 

12.8 날짜와 시간 클래스

● Date 클래스

클래스 설명
Date 날짜 정보를 전달하기 이해 사용
Calendar 다양한 시간대별로 날짜와 시간을 얻을 때 사용
LocalDateTime 날짜와 시간을 조작할 때 사용

 

예시) Date now = new Date();

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

Date now = new Date();
String strNow1 = now.toString();
System.out.println(strNow1);	// 요일, 월, 일, 시간, 분, 초, 국가시간?, 년도
        
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");	// 생성자. 날짜를 우리가 원하는 형태로 포멧
String strNow2 = sdf.format(now);
System.out.println(strNow2);

 

● Calendar 클래스

→ 현재 컴퓨터의 시간정보를 이용 (달력을 표현하는 추상 클래스)

 

특별한 역법을 사용하는 경우가 아니라면

→ Calendar now = Calendar.getInstance();

 

Calendar가 제공하는 날짜와 시간에 대한 정보를 얻기 위해 get() 메소드 이용

Calendar의 상수필드와 같이 사용

// API Document에서 사용법 확인해보자.

Calendar now = Calendar.getInstance();

int year = now.get(Calendar.YEAR);	// 년도
int month = now.get(Calendar.MONTH) + 1;	// 월
int day = now.get(Calendar.DAY_OF_MONTH);	// 일
int week = now.get(Calendar.DAY_OF_WEEK);	// 요일
int amPm = now.get(Calendar.AM_PM);	// 오전,오후
int hour = now.get(Calendar.HOUR);	// 시간
int minute = now.get(Calendar.MINUTE);	// 분
int second = now.get(Calendar.SECOND);	// 초

 

switch문으로 요일 setting하기

String strWeek = null;

switch(week) {
case Calendar.MONDAY: strWeek = "월";
    break;
case Calendar.TUESDAY: strWeek = "화";
    break;
case Calendar.WEDNESDAY: strWeek = "수";
    break;
case Calendar.THURSDAY: strWeek = "목";
    break;
case Calendar.FRIDAY: strWeek = "금";
    break;
case Calendar.SATURDAY: strWeek = "토";
    break;
default: strWeek = "일";
}

cf) Calendar.MONDAY 는 int를 반환한다. 범위 : 일요일(1) ~ 토요일(7)

 

타 지역에 맞는 시간대를 알고 싶을 때 TimeZone 객체를 얻어, getInstance() 메소드의 매개값으로 넘겨준다.

TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
Calendar now = Calendar.getInstance(timeZone);

int hour = now.get(Calendar.HOUR);
int minute = now.get(Calendar.MINUTE);
int second = now.get(Calendar.SECOND);	

System.out.println(hour + ":" + minute + ":" + second);

 

> America/Los_Angeles와 같은 시간대 ID를 알고 싶을 때

String[] availableIDs = TimeZone.getAvailableIDs();
for(String id : availableIDs) {
    System.out.println(id);
}

 

● 날짜와 시간 조작

Date, Calendar는 날짜와 시간을 조작할 수 없다.

java.time 패키지의 LocalDateTime 클래스의 메소드를 이용하면 날짜와 시간을 쉽게 조작할 수 있다.

 

→ LocalDateTime now = LocalDateTime.now();

메소드(매개변수) 설명 메소드(매개변수) 설명
minusYears(long) 년 빼기 plusDays(long) 일 더하기
minusMonths(long) 월 빼기 minusHours(long) 시간 빼기
minusDays(long) 일 빼기 minusMinutes(long) 분 빼기
minusWeeks(long) 주 빼기 minusSeconds(long) 초 빼기
plusYears(long) 년 더하기 plusHours(long) 시간 더하기
plusMonths(long) 월 더하기 plusMinutes(long) 분 더하기
plusWeeks(long) 주 더하기 plusSeconds(long) 초 더하기

 

예시)

LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy.MM.dd a "
				+ "HH:mm:ss");
System.out.println("현재 시간: " + now.format(dtf));
        
LocalDateTime result1 = now.plusYears(1);
System.out.println("1년 덧셈: " + result1.format(dtf));

 

● 날짜와 시간 비교

리턴 타입 메소드(매개변수) 설명
boolean isAfter(other) 이후 날짜인지?
isBefore(other) 이전 날짜인지?
isEqual(other) 동일 날짜인지?
long until(other, unit) 주어진 단위(unit) 차이 리턴

 

예시)

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy.MM.dd a"
				+ "HH:mm:ss");	// 포멧 형식
		
LocalDateTime startDateTime = LocalDateTime.of(2021, 1, 1, 0, 0, 0);
System.out.println("시작일: " + startDateTime.format(dtf));	// 포멧형식으로 출력
		
LocalDateTime endDateTime = LocalDateTime.of(2021, 12, 31, 0, 0, 0);
System.out.println("종료일: " + endDateTime.format(dtf));

if(startDateTime.isBefore(endDateTime)) {
			System.out.println("진행 중입니다.");
		} else if(startDateTime.isEqual(endDateTime)) {
			System.out.println("종료합니다.");
		} else if(startDateTime.isAfter(endDateTime)) {
			System.out.println("이미 종료했습니다.");
		}
        
long remainYear = startDateTime.until(endDateTime, ChronoUnit.YEARS);
long remainMonth = startDateTime.until(endDateTime, ChronoUnit.MONTHS);
long remainDay = startDateTime.until(endDateTime, ChronoUnit.DAYS);
long remainHour = startDateTime.until(endDateTime, ChronoUnit.HOURS);
long remainMinute = startDateTime.until(endDateTime, ChronoUnit.MINUTES);
long remainSecond = startDateTime.until(endDateTime, ChronoUnit.SECONDS);

System.out.println("남은 해: " + remainYear);
System.out.println("남은 월: " + remainMonth);
System.out.println("남은 일: " + remainDay);
System.out.println("남은 시간: " + remainHour);
System.out.println("남은 분: " + remainMinute);
System.out.println("남은 초: " + remainSecond);

 

→ 현재 시간으로부터 이번년도 크리스마스까지 남은 시간을 보여주는 프로그램 만들어보자!

LocalDateTime now = LocalDateTime.now();
LocalDateTime chrismas = LocalDateTime.of(now.getYear(), 12, 25, 0, 0, 0);

long dday = now.until(chrismas, ChronoUnit.DAYS);
System.out.println("현재로부터 크리스마스까지 남은 일 수: " + dday);

 

 

12.9 형식 클래스

→ Format(형식) 클래스 숫자 or 날짜를 원하는 형태의 문자열로 변환해주는 기능을 제공

Format 클래스 설명
DecimalFormat 숫자를 형식화된 문자열로 변환
SimpleDateFormat 날짜를 형식화된 문자열로 변환

  형식 패턴에 관해서는 외우지말고 이해하자!!

 

● DecimalFormat

double num = 1234567.89456;
DecimalFormat df;	// DecimalFormat 타입의 객체 생성

df = new DecimalFormat("#,###");	// 정수 3자릿수마다 (,)를 붙여 출력하는 형식
System.out.println(df.format(num));	// 형식에 맞춰 num을 출력한다.

 

● SimpleDateFormat

앞의 예시에서 다뤄봤다. 한번 더 연습

Date now = new Date();

sdf = new SimpleDateFormat("yyyy년 MM월 dd일");
System.out.println(sdf.format(now));

sdf = new SimpleDateFormat("현재시간: a h시 m분");
System.out.println(sdf.format(now));

sdf = new SimpleDateFormat("오늘은 E요일");
System.out.println(sdf.format(now));

 

 

12.10 정규 표현식 클래스

문자열이 정해져 있는 형식으로 구성되어 있는지 검증해야 하는 경우에 사용

이메일, 전화번호 등.. 형식을 맞춰야할 때 검증

예시)  외우지 말고, 이해하고 넘어가며 다음에 써보도록하자.

 

String regExp = "(02|010)-\\d{3,4}-\\d{4}";
String data = "010-123-4567";

boolean result = Pattern.matches(regExp, data);

if(result) {
    System.out.println("정규식과 일치합니다.");
} else {
    System.out.println("정규식과 일치하지 않습니다.");
}

 

 

12.11 리플렉션 (생략)

→ 이클립스과 같은 개발 tool에 유용한 지식

 

12.12 어노테이션 (생략)

→ 만들어진 어노테이션을 잘 쓰면 된다..

 

 

확인문제 풀기


13장 제네릭

→ '웹'개발자가 많이 사용하진 않지만 API 문서에서 보는 것에 한계가 생기기 때문에 학습해야한다.

 

13.1 제네릭이란?

Generic이란 결정되지 않은 타입을 파라미터로 처리하고

실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능

 

public class Box{
	public object content;
}

Box는 다양한 내용물을 저장해야 하므로 특정 클래스 타입으로 선언할 수 없다.

Object 타입은 모든 클래스의 최상위 부모 클래스.

따라서 모든 객체는 자동 타입 변환 되므로 content 필드에는 어떤 객체든 대입 가능.

Box box = new Box();
box.content = 모든 객체;

여기서 문제는 Box 안의 내용물을 얻을 때, content는 Object 타입이므로 어떤 객체가 대입되어 있는지 확실하지 않다.

대입된 내용물의 타입을 안다면 강제 타입 변환해서 내용물을 얻는 식이다.

(강제 타입 변환도 하나의 연산이다)

String content = (String) box.content;

하지만 어떤 내용물이 저장되어 있는지 모른다면 instanceof 연산자로 타입을 조사할 순 있는데, 모든 종류의 클래스를 대상으로 하는 것은 불가능하다.

따라서 Object 타입으로 content 필드를 선언하는 것은 좋은 방법이 아니다!

 

Box를 생성할 때 저장할 내용물의 타입을 미리 알려준다면,

Box는 content에 무엇이 대입되고, 읽을 때 어떤 타입으로 제공할지를 알게 된다.

public class Box <T> {	// 결정되지 않은 content 타입을 T라는 타입 파라미터로 정의할 것이다
	public T content;	// Box 객체가 생성될 시점에 다른 타입으로 대체된다
}

T 대신 A부터 Z까지 어떤 알파벳을 사용해도 된다.

Box<String> box1 = new Box<String>();  // Box<String> box1 = new Box<>(); 이렇게 사용해도 된다.
box1.content = "안녕하세요";
String str = box1.content;	// 강제 타입 변환 필요없이 바로 얻을 수 있음

Box<Integer> box2 = new Box<>();
box2.content = 100;
int number = box.content;	// 강제 타입 변환 필요없이 바로 얻을 수 있음

 

※ 주의할 점

파라미터를 대체하는 타입은 클래스 or 인터페이스

따라서 <참조타입> 으로 해주어야 한다.

 

 

13.2 제네릭 타입

→ 결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스

public class 클래스명<A, B, ... > { ... }
public interface 인터페이스<A, B, ... > { ... }

→ 외부에서 제네릭 타입을 사용하려면 타입 파라미터에 구체적인 타입을 지정해야 함.

만약 지정하지 않으면 Object 타입이 암묵적으로 사용된다.

 

예시) 클래스의 필드와 메소드 활용하기

public class Product<K, M> {
    private K kind;
    private M model;
    
    public K getKind() { return this.kind; }
    public M getModel() { return this.model; }
    public void setKind(K kind) { this.kind = kind; }
    public void setModel(M model) { this.model = model; }
}

public class Tv{ }

// 사용 클래스 main문에서

// 제품1은 Tv에 맞게 설계, K는 Tv로 대체 M은 String으로 대체
Product<Tv, String> product1 = new Product<>();

// Setter 매개값은 반드시 Tv와 String을 제공
product1.setKind(new Tv());
product1.setModel("스마트 TV");

// Getter 리턴값은 Tv와 String이 됨
Tv tv = product1.getKind();
String tvModel = product1.getModel();

 

 

예시) 인터페이스 활용하기

// 인터페이스를 제네릭 타입으로 선언
// 다양한 대상을 렌트하기 위해 rent() 메소드의 리턴 타입을 타입 파라미터로 선언
public interface Rentable<P> {
	P rent();
}

public class Home {
	public void turnOnLight() {
    	System.out.println("전등을 켭니다");
    }
}

public class Car {
	public void run() {
    	System.out.println("자동차가 달립니다");
    }
}

// 타입 파라미터를 Home으로 대체
public class HomeAgency implements Rentable<Home> {
	@Override
    public Home rent() { 	// 리턴 타입은 반드시 Home
    	return new Home();
    }
}

// 타입 파라미터를 Car로 대체
public class CarAgency implements Rentable<Car> {
	@Override
    public Car rent() {		// 리턴 타입은 반드시 Car
    	return new Car();
    }
}


// main 메소드 내부에서의 사용
HomeAgency homeAgency = new HomeAgency(); 	
Home home = homeAgency.rent();
home.turnOnLight();

CarAgency carAgency = new CarAgency();
Car car = carAgency.rent();
car.turnOnLight();

→ 출력되는 결과를 예상해보자.

'JAVA' 카테고리의 다른 글

11일차 2024 - 3 - 12  (0) 2024.03.17
10일차 2024 - 3 - 11  (0) 2024.03.17
13일차 2024 - 3 - 14  (0) 2024.03.14
12일차 2024 - 3 - 13  (0) 2024.03.13
3일차 2024 - 2 - 28  (0) 2024.02.28

+ Recent posts