14. Thread

    1) Thread 클래스

        1. 쓰레드 프로그래밍을 적용하고 싶은 클래스를 작성시 Thread라는 클래스를 상속하도록 작성.(extends Thread)
        2. 쓰레드가 실행될때 run메소드가 호출되므로 실제 쓰레드 구현하고 싶은 처리흐름을 run에 작성.
        => void run()을 오버라이딩
        3. run메소드를 직접 호출하지않고 Thread클래스이 내부에서 제공하는 start메소드를 호출하여 run을 실행.

        (t1.start())

        => start 메소드를 호출하면 JVM내부의 스케쥴러에 의해서 적절한 시점에 run이 호출.

        (정확한 호출시점 알 수 없음)

class ThreadClass extends Thread{
	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
//main
ThreadClass t1 = new ThreadClass("t1");
t1.start();

 

    2) Runnable : 이미 다른 상위클래스를 상속하는 클래스를 쓰레드 프로그래밍을 적용하기 위해서 Runnable타입으로

    클래스를 작성.

        1. Runnable 인터페이스를 상속.(implements Runnable)
        2. run 메소드를 오버라이딩해서 쓰레드 프로그래밍으로 처리하고 싶은 내용을 구현.
        3. Runnable 객체를 이용해서 Thread클래스를 생성.

        (Thread t1 = new Thread(new Runnable을 상속한 클래스명()))
        4. 생성한 Thread객체의 start를 호출
        => Thread클래스에 오버라이딩한 run이 있으면 run을 실행. 
        => target객체(Runnable타입의 객체)의 run을 실행.

class Parent{
}
class 클래스명 extends Parent implements Runnable{
	public void run() {
		
			System.out.print(i+"("+Thread.currentThread().getName()+")");
			// 현재 실행중인 쓰레드의 getName()을 호출
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}
}
// main
// 1. Runnable을 상속해서 작성한 객체를 생성
Runnable obj1 = new RunnableDemo01();
// 2. 생성한 Runnable 객체를 이용해서 Thread객체를 생성
Thread t1 = new Thread(obj1);
Thread t2 = new Thread(new RunnableDemo01());

//3. 생성한 Thread객체의 start를 호출
t1.start();
t2.start();

 

    3) priority : JVM의 스케쥴러에 의해서 실행시킬 쓰레드가 여러 개 있다면 우선순위가 높은 쓰레드 부터 먼저 실행.

    1부터 10까지 우선수위를 지정가능 (default : 5)

t1.setPriority(6); // 우선순위 set
t1.getPriority(); // 우선순위 get
Thread.MAX_PRIORITY; // 10 return
Thread.MIN_PRIORITY; // 1 return

 

    4) yeild : yield 우선권이 동일한 쓰레드에게 실행을 양보하여 start()부터 재시작.

Thread.yield();

 

    5) join : 연결된 쓰레드 종료 후 메인 쓰레드가 종료하도록 하는 메소드.

try {
	t5.join();
} catch (InterruptedException e) {
	e.printStackTrace();
}

 

    6) thread 종료
        1. 임의의 변수(flag 변수)를 선언해서 종료하는 방법
        - 변수값에 따라서 작업을 처리할 수 있도록 구현

class testClass extends Thread{
	private boolean state = true;// 현재 상태값을 저장할 수 있는 변수
	
	public void run() {
		while(state) {
			// 실행문
		}
	}
	
	//쓰레드의 상태를 조절할 수 있도록 변수를 변경하는 메소드
	public void stopThread() {
		state = false;
	}
}
public class StopThreadTest01{
	public static void main(String[] args) {
		testClass t1 = new testClass();
		t1.start();
		t1.stopThread();
	}
}

 

        2. 인터럽트를 발생시키고 현재상태를 확인한 후 작업

class StopThread02 extends Thread{
	public void run() {
		try { // interupt이 발생해도 sleep문의 예외처리에 걸리지 않도록 try로 묶어준다.
		while(false == Thread.currentThread().isInterrupted()) { 
		// 현재상태가 인터럽트 상태면 종료하도록 구현.
			// 실행문
			Thread.sleep(500);
		}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		finally {
		}
	}
}

StopThread02 t1 = new StopThread02();
t1.start();
System.out.println("쓰레드 이름 : "+t1.getName());
System.out.println("인터럽트 상태 : "+t1.isInterrupted());
try {
	Thread.sleep(3000);
} catch (InterruptedException e) {
	e.printStackTrace();
}
t1.interrupt();
System.out.println("쓰레드 이름 : "+t1.getName());
System.out.println("인터럽트 상태 : "+t1.isInterrupted());

 

    7) 동기화

        1. synchronized 지정자

public class Shared {
	public synchronized void method() {
	// 한 쓰레드가 method 사용이 끝나기 전까지 다른 쓰레드가 method를 사용하지 못하도록 lock
	}
}
public class threadClass extends Thread{ // Thread
	Shared sh;
	threadClass(Shared sh){
		this.sh = sh
	}
	public void run() {
		Shared.method();
	}
}
// main
//쓰레드에서 공유할 객체 생성
Shared sh = new Shared();

//공유객체를 사용하는 쓰레드 생성
threadClass t1 = new threadClass(sh);
threadClass t2 = new threadClass(sh);

//쓰레드
t1.start(); // 한 쓰레드가 synchronized된 메소드를 사용중이면 사용이 끝난 후 사용할 수 있다.
t2.start();

 

        2. synchronized 블록

//공유객체
public class SharedObj {
	Account acc1;
	Account acc2;
}

// 기능1의 쓰레드
public class Thread1 extends Thread{
	SharedObj obj;
	public AccountSumThread(SharedObj obj) {
		this.obj = obj;
	}
	public void run() {
		for(int i=1;i<=5;i++) {
			long total = obj.acc1.getBalance()+obj.acc2.getBalance();
		}
	}
}

//기능2의 쓰레드
public class Thread2 extends Thread{
	SharedObj obj;
	public AccountTransferThread(SharedObj obj) {
		this.obj = obj;
	}
	public void run() {
		for(int i=1;i<=20;i++) {
			synchronized (obj) { // 메소드 전체가 아니라 명령문 일부에 lock을 적용할때 사용하는 synchronized블럭
								// ()안에 공유객체 명시.
				obj.acc1.withdraw(1000000);
				obj.acc2.deposit(1000000);
				
			}
		}
	}
}
// main
// 공유객체 생성
SharedObj obj = new SharedObj();
obj.acc1 = new Account();
obj.acc2 = new Account();

//쓰레드 생성
Thread1 t1 = new Thread1(obj); 
Thread2 t2 = new Thread2(obj);// 기능 2의 쓰레드의 동기화 블록이 실행 중에는 다른 쓰레드를 실행할 수 없다.

//쓰레드 start
t1.start();
t2.start();

 

 

 

15. Network

    1) InetAddress클래스 : IP주소를 모델링한 클래스. 로컬, 호스트네임을 통해서 IP주소를 가져올 수 있는 기능제공.

try {
	//InetAddress ia = InetAddress.getByName("www.naver.com");
	InetAddress ia = InetAddress.getByName(args[0]);
	ia.getHostName(); // Name 리턴
	ia.getHostAddress(); // ip주소 리턴
	InetAddress.getLocalHost(); // 로컬 ip 리턴
	
	InetAddress[] iaArr = InetAddress.getAllByName(args[0]); // 연결된 모든 ip 리턴
	for(int i=0;i<iaArr.length;i++) {
		iaArr[i].getHostName();
		iaArr[i].getHostAddress();
	}
} catch (UnknownHostException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

    2) URL클래스 : 웹상의 주소를 나타내는 클래스고 이를 통해서 네트워크 연결도 가능.
    웹상의 리소스를 가져올 수 있다. 웹페이지, 이미지, 동영상..

try {
	URL url = new URL("https://www.naver.com/");
	url.toString();
	url.getHost();
	url.getPath();
	url.getPort(); // 프로토콜에 등록되어 있는 기본 port로 접속 할 경우 -1 return
					// http프로토콜의 기본포트는 80번
	url.getProtocol(); // https
	url.getFile();
	
	// URL에 접속해서 자원정보를 읽는 작업을 수행
	InputStream is = url.openStream();
	InputStreamReader isr = new InputStreamReader(is);
	BufferedReader br = new BufferedReader(isr); 
	
	while(true) {
		String data = br.readLine();
		if(data == null) {
			break;
		}
		System.out.println(data);
	}
}catch (MalformedURLException e) {
	e.printStackTrace();
}catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

 

    3) URL 이미지 출력
    - BufferedInputStream : byte단위 입력
    - FileOutputStream : byte단위 파일 출력

BufferedInputStream bis =null;
FileOutputStream fos=null;

try {
	URL url = new URL("url 경로");
	bis = new BufferedInputStream(url.openStream());
	fos = new FileOutputStream("src/data/image.jpg");
	while(true) {
		int data = bis.read();
		if(-1 == data) {
			break;
		}
		fos.write(data);
	}
} catch (MalformedURLException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}
finally {
	try {
		if(bis != null)
			bis.close();
		if(fos != null)
			fos.close();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

 

    4) Socket 통신 - Server

try {
	
	ServerSocket server = new ServerSocket(50000);
	// 클라이언트와 통신하기 위해서 ServerSocket을 생성
	while(true) {
		Socket client = server.accept();
		// 클라이언트가 접속할때까지 대기하다가 (Litsen) 클라이언트가 접속하면 클라이언트와 통신
        // 할 수 있도록 클라이언트의 정보를 Socket객체로 만들어서 리턴
		InetAddress clientIp = client.getInetAddress();
		System.out.println("접속한 클라이언트 => "+clientIp.getHostAddress());
	}
	
} catch (UnknownHostException e){
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

 

    5) Socket 통신

try {
	//서버와 통신할 수 있는 소켓객체 생성
	//Socket 객체를 생성하면 서버에 접속한다.
	Socket serverInfo = new Socket("192.168.0.3",50000); // 서버 ip 및 port
} catch (IOException e) {
	e.printStackTrace();
}

 

    6) DataInputStream : 파일의 데이터를 읽는 클래스

DataInputStream dis = new DataInputStream(new FileInputStream("src/data/dos.txt"));
// IO작업 직접하는 것이 아니라 추가된 기능을 표현해 놓은 스트림 클래스로
// 직접 원시데이터와 연결하지 못한다.
int data1 = dis.readInt();
double data2 = dis.readDouble();
String data3 = dis.readUTF();
System.out.println(data1);
System.out.println(data2);
System.out.println(data3);
dis.close();

 

    7) DataOutputStream : 파일의 데이터를 쓰는 클래스

FileOutputStream fos = new FileOutputStream("src/data/dos.txt");
DataOutputStream dos = new DataOutputStream(fos);
// FileOutputStream과 같은 스트림객체를 먼저 생성한 후 작업해야한다.
dos.writeInt(100);
dos.writeDouble(10.5);
dos.writeUTF("문자열");
fos.close();
dos.close();

 

    8) Echo Server : 클라이언트가 전송한 데이터를 받아서 그대로 클라이언트에게 전송

public static void main(String[] args) {
Socket client = null;
BufferedReader in = null;
PrintWriter out = null;
// InputStream is =null; // 클라이언트와 input통신을 할 수 있는 스트림
// DataInputStream dis = null; // 최종적으로 클라이언트와 DataInputStream을 통해서 통신
// OutputStream os =null; // 클라이언트와 output통신을 할 수 있는 스트림
// DataOutputStream dos = null; // 최종적으로 클라이언트와 DataOutputStream을 통해서 통신
try {
	ServerSocket server = new ServerSocket(7777);//서버소켓을 열고 대기
	while (true) { // 클라이언트와 통신할 수 있는 input/output스트림을 소켓으로 부터 생성
		client = server.accept(); // 클라이언트 접속을 기다리다가 클라이언트가 접속하면 이용해서 Socket객체를 생성
		
		// 클라이언트와 통신할 수 있는 input/output스트림을 소켓으로 부터 생성
		in = new BufferedReader(new InputStreamReader(client.getInputStream()));
		out = new PrintWriter(client.getOutputStream(), true);
		// autoflush속성을 true로 설정하면 println메소드가 호출될때 자동으로 flush호출.
		out.println("문자열");
		String msg = in.readLine();
		
		//클라이언트가 전송하는 데이터를 읽기 위한 스트림 객체를 소켓으로 부터 생성한다.(accept 했을 때 만든 소켓)
		//is = client.getInputStream();
		//dis = new DataInputStream(is);
		// 클라이언트로 전송할 데이터를 출력하기 위한 스트림 객체를 소켓으로 부터 생성
		//os = client.getOutputStream();
		//dos = new DataOutputStream(os);
		//dos.writeUTF("문자열");
		//dos.writeInt(20000);
		//dis.readUTF()
		//dis.readint()
		
		/*
		out = new PrintWriter(client.getOutputStream());
		out.println("문자열");
		out.flush();// flush는 버퍼를 비우는 명령 - 출력버퍼의 내용을 실제로 출력하라는 의미
		// 출력버퍼에 임시로 보관되어 스트림으로 출력될때까지 대기중인 데이터를 스트릠으로 내보내는 작업을 하는 것이 flush
		*/
		
		//클라이언트가 보내오는 데이터를 지속적으로 읽어서 클라이언트로 다시 보내주는 작업 - 예측불가
		String reMsg = "";
		while(true) {//한 클라이언트와 지속으로 대화하기 위해서 사용하는 while
			//1. 서버<-클라이언트(클라이언트가 보내는 데이터를 지속적으로 읽기)
			reMsg = in.readLine();
			if(reMsg == null) {
				break;
			}
			//2. 서버 -> 클라이언트
			out.println(reMsg");
		}
	}
} catch (IOException e) {
	e.printStackTrace();
}

 

    9) Echo Client

Socket server = null;
BufferedReader in =null;//소켓통신
PrintWriter out =null;//소켓통신
BufferedReader keyin = null; // 서버에게 데이터를 내보내기 위해서 키로브로 입력하는 것을 읽기 위한 입력 스트림

try {
	server = new Socket("192.168.0.3",7777);
	System.out.println("Client Accept to server.");
	while(true) {
		in = new BufferedReader(new InputStreamReader(server.getInputStream()));
		keyin = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(server.getOutputStream(), true);
		
		//키보드로 입력하는 내용이 지속적으로 서버에 전달되도록 구현
		String sendMsg=""; // 서버로 보낼 메시지
		String reMsg=""; // 서버에서 받는 메시지
		while(true){
			//1. 클라이언트 -> 서버 (키보드로 입력하는 데이터 서버로 보내기)
			sendMsg = keyin.readLine();
			out.println(sendMsg);
			//2. 클라이언트 <- 서버
			reMsg = in.readLine(); // 네트워크로 입력되어 들어오는 데이터 읽기
			System.out.println("서버에서 전송된 메시지 : "+reMsg);
		}
	}
} catch (UnknownHostException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}

10. 중요 메소드 
    ① toString() : 오버라이딩을 통한 사용자 정의 toString()

public String toString(){
	String 변수 = 출력하고 싶은 문자열+...
	return 변수;
}
Object obj1= new Object(); // 최상위 객체
System.out.println(obj1.getClass()); // 클래스 이름
System.out.println(obj1.hashCode()); // 객체가 갖는 고유한 값 - 주소(10진수)
System.out.println(obj1.toString()); // 클래스 이름 @ 16진수의 hash code
				     // java.lang.Object@123a439b
System.out.println(obj1);    // toString()과 동일


String s = new String("str");    // String과 Date는 toString()이 오버라이딩된 값이 출력됨
Date   d = new Date();
System.out.println(s);    // s.toString이 호출.(toString() 기본 메소드로 생략됨)
System.out.println(d);    // d.toString이 호출.(toString() 기본 메소드로 생략됨)

Random r = new Random();    // 그외 Random, 사용자 정의함수는 주소값을 리턴한다.
Person p = new Person();
System.out.println(r);
System.out.println(p);

 

    ② equals() : 오버라이딩을 통한 사용자 정의 equals(). 

                    사용자 정의 객체의 경우 주소값을 비교함으로 equals 비교시 false를 리턴

class Person{
	...
	public boolean equals(Object obj) { // Person객체끼리 비교
		if(obj != null & obj instanceof Person) {
			// obj가 Person이라고 하더라도 타입이 Object이므로 Object의 멤버만 사용할 수 있으므로
			// obj를 Person으로 캐스팅하여 Person.equals를 사용한다.
			Person p = (Person) obj;
			if(this.name.equals(p.getName()) & this.addr.equals(p.getAddr())) {
				return true;
			}
		}
		return false;
	}
}

Person obj1 = new Person();
Person obj2 = new Person();

if(obj1.equals(obj2)){ // 사용자 정의된 equals() 비교
}

 

 

 

11. 중요 클래스

    ① String : 문자열 생성은 2가지 방법 존재.
        1) String 생성

String str = new String("문자열"); // new 이용
String str = "문자열"; // 리터럴 이용

        - new를 이용 시 동일한 문자열이 존재하여도 새로 생성.
        - 리터럴을 이용 시 동일한 문자열이 존재할 경우 기존 문자열 재사용. 상수풀(constant pool)에 저장되어 불변성

          을 가짐.
        - String 객체의 문자열이 어떤 방법으로 할당되는지 상관없이 문자열을 비교하고 싶은 경우 equals()사용

 

        2) String 생성자

byte[] data = {65,66,67,69,70};
		char[] data2 = new char[] {'0','1','0','-','1','2','3'};
		
		String str1 = new String(data); // ABCEF
		String str2 = new String(data2); // 010-123
		String str3 = new String(data2,2,2); // data2의 2번 index 부터 2개의 문자열. "1-"

        - String클래스를 사용하는 경우 다양한 타입의 입력데이터를 문장열로 만들 수 있도록 하기 위해

          다양한 형태의 생성자가 오버로딩 되어있음.

 

        3) String - final

class MyClass extends String{
}

        - String은 final class로 상속할 수 없음.

 

        4) String 메소드 : String 객체는 원본이 변경되지않고 메소드 실행결과로 새로운 String객체가 만들어짐.
                              : 문자열 조작이 많은 곳에서 String을 사용하는 것은 프로그램을 무겁게 함.

String str1 = new String("java programming");
String str2 = new String("입니다.");

str1.charAt(1); // str1에서 1번 index의 문자
str1.concat(str2); // str1과 str2를 연결
str1.indexOf('a'); // str1에서 가장 왼쪽의 'a'의 index
str1.indexOf("합"); // 문자가 없을 경우 -1 리턴
str1.lastIndexOf('a'); // str1에서 가장 오른쪽의 'a'의 index
str1.length(); // str1의 길이
str1.equalsIgnoreCase("java programming");
str1.equalsIgnoreCase("JAVA programming"); // 대소문자 구분하지않고 문자열 비교
str1.startsWith("java")); // str1이 "java"로 시작하면 true아니면 false 리턴
str1.endsWith("amming")); // str1이 "amming"로 끝나면 true아니면 false 리턴
str1.toUpperCase(); // 대문자 변환값 리턴
					// 원본 문자열 변화 없음. 새로운 객체를 생성하여 리턴.
str1.toLowerCase()); // 소문자 변환값 리턴
str1.substring(4); // 4번째 문자열부터 끝까지의 문자열 추출. programming
str1.substring(4,8); // 4번째 문자열부터 8-1번까지의 문자열 추출. pro
str1.replace('a','A')); // 'a' 문자를 'A'로 변경. jAvA progrAmming

 

        5) String 의 데이터 타입 변환과 관련된 메소드

String str1 = new String("java programming");
String str2 = new String("java servlet spring bigdata");

//1) getBytes() : String -> byte[] 변환
byte[] data1 = str1.getBytes();
for(int i=0;i<data1.length;i++) {
	System.out.print(data1[i]+" ");
}

//2) toCharArray() : String -> char[] 변환
char[] data2 = str1.toCharArray();
for(int i=0;i<data2.length;i++) {
	System.out.print(data2[i]+" ");
}

//3) split(" ") : String -> String[] 변환
String[] data3 = str2.split(" ");
for(int i=0;i<data3.length;i++) {
	System.out.print(data3[i]+" ");
}

//4) valueOf(x) : 기본형 -> String 변환
int i =1000;
double d = 10.5;
test(String.valueOf(i));
test(String.valueOf(d));

test(i+"");
test(d+"");

public static void test(String data) {
	System.out.println("변환된 데이터 "+data);
}

        6) StringBuffer : String의 불변성으로 메모리 사용이 많아 대안으로 원본 배열이 변경되는
                             StringBuffer사용하기도 함.

           StringBuffer와 StringBuilder의 차이

               StringBuffer  : thread 고려 무겁다 안전. JDK 1.0이상
              StringBuilder : thread 비고려 가볍다 웹서버에서 처리함으로 무관. JDK 5.0이상

 

           StringBuffer 사용

StringBuffer sb = new StringBuffer("java programming");

sb.append("입니다."); // 맨뒤에 추가
sb.insert(2, "자바"); // 지정한 위치에 문자열 삽입
sb.delete(2, 6); //start~end-1 위치의 문자열 삭제 
sb.reverse(); // 문자열 반전

           ③ String과 StringBuffer의 비교

public static void stringCheck(int count) {
	// 시작할때 현재 시간을 측정 - nano초
	long start = System.nanoTime();
	String str = new String("java");
	for(int i=1; i<=count;i++) {
		str+="java";
	}
	long end = System.nanoTime();
	System.out.print("str+='java' ");
	System.out.println("수행시간\t: "+(end-start)+" ns");

}
public static void stringBufferCheck(int count) {
	long start = System.nanoTime();
	StringBuffer sb = new StringBuffer("java");
	for(int i=1; i<=count;i++) {
		sb.append("java");
	}
	long end = System.nanoTime();
	System.out.print("sb.append('java') ");
	System.out.println("수행시간\t: "+(end-start)+" ns");
		
}
public static void main(String[] args) {
	int count = 10000;
	System.out.println("실행횟수 : "+count);
	stringCheck(count);
	stringBufferCheck(count);
}

 

    ② Math

Math.PI;          // PI
Math.abs(-1);     // 절대값
Math.ceil(10.5);  // 올림
Math.round(10.5); // 반올림
Math.floor(10.5); // 버림
Math.max(100,10); // 최대값
Math.min(100,10); // 최소값
Math.random();    // 난수

 

    ③ Wrapper 클래스

        1) 5.0 이전(기본형 -> 참조형)

int num =100; 
Integer obj = new Integer(num); // 기본형 -> 참조형 
run(obj); 

public static void run(Object obj) { // Integer -> Object 
Integer inObj = (Integer)obj;    // Object -> Integer 
int num = inObj.intValue();      // Interger -> int (참조형->기본형) 
} 


        2) 5.0 이후 (기본형 -> 참조형)

int num = 1000; // 5.0 이후 버전의 jdk에서는 컴파일러가 자동으로 변환해준다. 
run(num); // 참조형으로 매개변수가 정의되어 있어도 기본형을 전달하는 경우 자동으로  
// 컴파일러가 Integer in = new Integer(num) 이 코드를 실행해서  
// Integer타입으로 변환해준다. 이를 오토박싱이라 한다. 
public static void run(Object obj) { 
Integer inObj = (Integer)obj; 
int i = inObj; // (참조형->기본형) 

int j = (Integer)obj; // 오토 언박싱 
// int형 변수에 참조형 변수를 전달하는 경우 컴파일러가 자동으로 객체를  
// int로 바꾸는 코드를 만든다. 
// int j = obj.intValue(); 
}

 

    ④ Calendar 클래스 : 날짜 시간

//java.util.date : 시스템의 기본 날짜와 시간
//java.sql.date : DBMS(오라클)에서 date타입으로 전의한 칼럼값을 다루기 위해서 사용하는 타입

//Date 객체는 deplecate
//GregorianCalendar는 Calendar의 자식 클래스

import java.util.Calendar;

Calendar cal = new GregorianCalendar(); // 오늘 날짜기간 정보
cal.get(Calendar.YEAR);
cal.get(Calendar.MONTH)+1;
cal.get(Calendar.DATE);
cal.get(Calendar.HOUR);
cal.get(Calendar.MINUTE);
cal.get(Calendar.SECOND);
cal.getTimeInMillis();
cal.set(2020,11,30);

 

    ⑤ SimpleDateFormat 클래스 : 출력되는 데이터의 형식을 변경할 수 있는 API

SimpleDateFormat sdf = new SimpleDateFormat("yyyy년MM월dd일");
Calendar today = new GregorianCalendar();
sdf.format(today.getTime()); //getTime() : Calendar객체를 Date로 변환

 

    ⑥ DecimalFormat 클래스 : 출력되는 데이터의 형식을 변경할 수 있는 API

import java.text.DecimalFormat;

DecimalFormat df = new DecimalFormat("#,###.##");
df.format(1234567);
df.format(1234567.48);
String data = "25465.174";
df.format(Double.parseDouble(data);
try {
	double data3 = (double) df.parse(data);
	String num3 = df.format(data3);
}
catch(ParseException e) {
	
}

 

    ⑦ 어노테이션

@Override

 

     StringTokenizer : String클래스의 split()을 사용하는것과 비슷한 개념. token화.

import java.util.StringTokenizer;
StringTokenizer st = new StringTokenizer("java:servlet:jdbc:spring:hadoop",":");

System.out.println(st.countTokens());//토근의 개수 리턴
while(st.hasMoreTokens()) { // StringTokenizer 내부 저장소에 token이 있으면 true 없으면 false 리턴
	String token = st.nextToken(); // token을 리턴.
	System.out.println(token);
}

 

    Arrays

import java.util.Arrays;

int[] arr = {10,20,30,40,50};
Arrays.fill(arr,100); // 배열 요소를 특정 값으로 채우기
Arrays.equals(arr, arr2); // 배열값이 같은지 비교
Arrays.sort(arr); // 배열의 데이터 정렬(default : 오름차순)
Arrays.binarySearch(arr,50); // 배열에서 특정 값이 저장된 요소의 index

 

    향상된 for문

for(요소의 타입 요소를 저장할 변수:컬렉션을 참조하는 변수){
}

 

 

 

12. 컬렉션 : List, Map, Set을 생성하기 전에 저장될 요소의 타입을 미리정의
                컬렉션 클래스<요소의 타입> 변수 = new 컬렉션 클래스<요소의 타입>();
                 <요소의 타입> : Generic

    ① List : 배열과 동일한 구조, 중복 가능. 주로 ArrayList 사용.
        1) Vector : 무겁 Thread에 안전

import java.util.Vector;

Vector v = new Vector(); // 다른 타입도 저장가능. 5.0이전 사용
//=> Vector안에 저장되는 데이터의 타입을 제한(요소타입이 기본형인 경우 Wrapper타입으로 명시)

Vector<Integer> v = new Vector<Integer>(); // Generic으로 Vector의에 저장되는 요소의 타입을 명시
v.add(10); // 값 추가.
v.size(); // 현재벡터에 저장된 요소의 개수
v.capacity(); // 현재 벡터의 용량
v.get(0) // 값 read

Vector<String> v2 = new Vector<String>();
v2.add("aa");

for(String s:v2) {
	System.out.print(s+" ");
}

        2) ArrayList : 가볍 thread에 unsafe

import java.util.ArrayList;

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10); // 값 추가.
list.size(); // 저장된 요소의 개수
list.get(0) // 값 read

        3) 2차원 배열

import java.util.ArrayList;

ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> row = new ArrayList<Integer>();

for(int i=0;i<3;i++) {
	row.add(i);
}

ArrayList<Integer> row2 = new ArrayList<Integer>();
for(int i=3;i<7;i++) {
	row2.add(i);
}

ArrayList<Integer> row3 = new ArrayList<Integer>();
for(int i=7;i<9;i++) {
	row3.add(i);
}
list.add(row);
list.add(row2);
list.add(row3);

for(int i=0;i<list.size();i++) {
	for(int j=0;j<list.get(i).size();j++) {
		System.out.print(list.get(i).get(j)+"\t");
	}
}

    ② Set : 집합. 합집합, 교집합가능. 중복이 불가능. 주로 HashSet 사용.
        1) HashSet

import java.util.HashSet;

HashSet<String> set = new HashSet<String>(); // 생성
set.add("aa"); // 데이터 추가
set.add("bb");
set.add("cc");
set.add("dd");
set.add("ee");
set.add("aa"); // 중복불가
System.out.println("요소의 개수: " + set.size()); //5 

// 데이터 추출
// set은 선형구조가 아니라 순서대로 읽어올 수 없다.
// 여러종류의 자료구조에 저장된 데이터를 내부에서 Iterator로 변환해서 읽을 수 있도록 지원
// HashSet -> Iterator
Iterator<String> it = set.iterator();
while(it.hasNext()) { // iterator안에 데이터가 있는 지 확인. boolean리턴
	String element = it.next(); // Iterator에 저장된 요소 꺼내기
	System.out.println("set에 저장된 요소 : "+element);
}

 

        2) HashSet 교집합, 합집합

HashSet<String> set = new HashSet<String>();
set.add("aa");
set.add("bb");
set.add("cc");
set.add("dd");
set.add("ee");
set.add("ff");

//합집합 - Set을 생성할때 매개변수로 다른 Set을 전달
HashSet<String> set2 = new HashSet<String>(set);
set2.add("zz");
set2.add("yy");
set2.add("xx");
set2.add("aa");

//교집합
HashSet<String> set3 = new HashSet<String>();
set3.add("aa");
set3.add("dd");
set3.add("zz");
set.retainAll(set3); // 두 set의 교집합이 set에 새로 저장된다.


        3) SortedSet

    ③ Map : key와 value. 주로 HashMap사용.
        1) HashMap : Thread에 비안전, 빠름

HashMap<Integer,String> map1 = new HashMap<Integer, String>();
// key가 중복되면 마지막 작업한 내용으로 덮어쓴다.
map1.put(1, "aa");
map1.put(1, "bb");
map1.put(1, "cc");

System.out.println(map1.get(1)); //cc 마지막 값 리턴.
System.out.println(map1.size()); //1

HashMap<String, String> map2 = new HashMap<String, String>();
map2.put("a001", "aa");
map2.put("a002", "bb");
map2.put("a003", "cc");
map2.put("a004", "dd");
map2.put("a005", "ee");
map2.put("a006", "ff");
map2.put("a007", "gg");
map2.put("a008", "hh");

System.out.println(map2.size());
System.out.println(map2.get("2"));

//map에 저장된 데이터를 꺼내기
//1. map이 갖고 있는 키들을 set으로 변환
Set<String> keyList = map2.keySet();

//2. set에 저장된 key목록을 iterator로 변환하고
Iterator<String> it = keyList.iterator();

//3. iterator에서 key를 하나씩 꺼내서 get
while(it.hasNext()) {
	String key = it.next();
	String value = map2.get(key);
	System.out.println(key+":"+value);
}

 

        2) HashTable : Thread에 안전, 느림
        3) Properties

 

 

 

13. I/O

    Input용클래스  - _____InputStream     (byte단위)
                          _____Reader            (문자단위)
    Output용클래스 - _____OutputStream (byte단위)
                            _____Writer           (문자단위)

 

    1) InputStream, PrintStream : byte 단위 입출력 처리

class System{
	public static final InputStream in;
	public static final PrintStream out;
}
InputStream myin = System.in;
PrintStream myout = System.out;
try {
	while(true) {
		int data = myin.read(); // 키보드로 입력한 단어를 읽어서 리턴.
		myout.print((char)data+" "); // 입력받은 데이터는 int로 문자로 변환하여 출력.
		//System.out.print((char)data+" "); // System.out = myout
		if(data==13) // 개행문자가 오면 종료.
			break;
		
	}
}
catch(IOException e) { // read()는 예외처리가 필요.
	e.printStackTrace();
}

 

    2) InputStreamReader : 문자 단위 입출력 처리. 사용방법이 InputStream와 동일

InputStreamReader myin = new InputStreamReader(System.in); // 객체 생성만 다르다.
PrintStream myout = System.out;

try {
	while(true) {
		int data = myin.read();
		myout.print((char)data);
		if(data==13)
			break;
	}
}
catch(IOException e) {
	e.printStackTrace();
}

 

    3) File 클래스

File dir = new File("C:/java/test"); //액세스 하고 싶은 폴더나 파일의 경로 - 절대경로, 상대경로
//File dir = new File("C:\\java\\test");
File file = new File("test.txt"); // ROOT

System.out.println(file1); // toString()
System.out.println(file2); // 생성자에 입력값 출력.
file.canRead(); // 해당 파일을 읽을 수 있으면 true, 아니면 false 리턴.
file.canWrite(); // 해당 파일을 쓸 수 있으면 true, 아니면 false 리턴.
file.getAbsolutePath(); // 절대 경로 리턴
file.getName(); // 파일의 확장자를 포함한 이름 리턴
file.getParent(); // 파일 또는 폴더의 상위 경로 리턴
file.getPath(); // 상대경로 리턴
dir.isDirectory(); // 디렉토리이면 true, 아니면 false 리턴.
file.isDirectory();
dir.isFile(); // 파일이면 true, 아니면 false 리턴.
file.isFile();
dir.lastModified(); // 마지막 수정일자 리턴
// 폴더의 기본사이즈 : 4096
dir.length(); // 폴더 or 파일 크기 리턴
file.length();
file.setReadOnly(); // 읽기전용으로 변경.
file.setWritable(true); // 쓰기가능으로 변경.

File[] fileArr = file.listFiles(); // 파일객체 내부의 파일에 대한 파일객체 배열을 리턴
String[] fileName = file.list; // 파일객체 내부의 파일이름 배열 리턴

 

    4) FileInputStream : byte 단위 파일 액세스

FileInputStream fis = null; // 인스턴스를 try안에서 생성 시 {}안에서만 사용할 수 있어
							// 인스턴스만 생성 후 파일열기는 try 내부에서 진행. 
try {
	fis = new FileInputStream("src/data/test.txt");//1. 파일 열기 - FileNotFoundException 처리 필요
	while(true) {
		int data = fis.read(); // IOException 처리 필요
		if(data == -1) { // 파일읽기가 끝나면 -1을 리턴한다.
			break;
		}
		System.out.print((char)data);
	}
} catch (FileNotFoundException e) {
	e.printStackTrace();
}
catch(IOException e) {
	e.printStackTrace();
}
finally {
	// 3. 파일 닫기 - 자원반납
	//IO 작업을 하다가 오류가 발생하거나 정상적으로 처리된다고 하더라도 모두 자원을 반납해야하므로 finally 블럭에서 처리.
	// input은 오류가 없는 output은 close를 안하면 파일에 output한 데이터가 write되기 전에 파일을 내부에서 종료한다.
	try {
		if(fis!=null) // 파일이 null로 파일열기에 실패할 경우 file close를 진행하면 안되므로 예외처리 진행.
			fis.close(); // IO Exception 처리 필요.
	}
	catch(IOException e) {
		e.printStackTrace();
	}	
}

 

    5) FileReader : 문자 단위 파일 액세스. FileInputStream과 동일.

FileReader fr = null;
try {
	fr = new FileReader("src/data/test.txt");
	
	while(true) {
		int data = fr.read();
		if(data == -1) {
			break;
		}
		System.out.print((char)data);
	}
} catch (FileNotFoundException e) {
	e.printStackTrace();
}
catch(IOException e) {
	e.printStackTrace();
}
finally {
	try {
		if(fr!=null)
			fr.close();
	}
	catch(IOException e) {
		e.printStackTrace();
	}
	
}

 

    6) FileWriter : 문자 단위 파일 쓰기. 파일이 존재하지 않으면 새로 만들어서 출력한다.

FileWriter fw = new FileWriter("src/data/output.txt");
// 두번째 매개변수가 없을 경우 default로 덮어쓰기을 진행한다.
FileWriter fw = new FileWriter("src/data/output.txt",true);
// 생성자에 두번째 매개변수가 true를 두면 apped모드 활성화된다.
fw.write(97);
fw.close();

 

    7) BufferedReader : 버퍼를 이용하여 파일의 한 라인씩 읽을 수 있어 실행속도가 빨라 FileReader보다 많이 사용된다.

BufferedReader br = null;
// BufferedReader는 생성자 인자로 FileReader객체를 매개변수로 받는다.
// FileReader fr = null;

try {
	br = new BufferedReader(new FileReader("src/io/InputStreamTest.java"));
	// fr = new FileReader("src/data/test.txt");
	// br = new BufferedReader(fr);
	// FileReader 객체를 따로 생성해서 BufferedReader 매개변수에 전달할 수 있으나
	// 코드를 줄이기 위해 한줄에 사용
	while (true) {
		String line = br.readLine(); // 한줄씩 읽는다.
		if (line == null) { // 읽을 라인이 없다면 null을 리턴.
			break;
		}
		System.out.println(line);
	}
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
} finally {

	try {
		if (br != null) {
			br.close();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}

 

 

 

<tip>

* toString 자동 생성: Source - Generate toString

* API 문서에서의 Deprecated : 미사용 권고

+ Recent posts

1