1.Priority


Thread에 우선순위를 부여하여 실행하는 것이다.


너무 짧은 작업이라면 우선순위 부여에 의미가 없지만 작업이 커질수록 차이가 느껴질 것이다.



package chap10.exam04.priority;

public class WorkThread extends Thread {

	public WorkThread() {
		// TODO Auto-generated constructor stub
	}

	public WorkThread(String name) {
		setName(name);
	}

	@Override
	public void run() {
		System.out.println(getName() + "의 작업 시작");
		for(int i = 0; i < 100000; i++) {
			// 이 시간동안 작업이 있다고 가정
		}
		System.out.println(getName() + "의 작업 끝");
	}

}
package chap10.exam04.priority;

public class Main {

	public static void main(String[] args) {
		// 우선 순위는 1~10까지 줄 수 있다.
		// 우선 순위가 같거나 없으면 무조건 빠른놈이 먼저다.
		// 우선 순위는 상수로도 가능하다.
		
		for(int i = 1 ; i <= 5; i++) {
			Thread th = new WorkThread(i + "번째 스레드");
			th.setPriority(i);
//			th.setPriority(Threa[d.MAX_PRIORITY);
//			th.setPriority(Thread.MIN_PRIORITY);
//			th.setPriority(Thread.NORM_PRIORITY);
			th.start();
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 우선순위만으로는 완벽한 스레드 제어가 어렵다
		}
	}

}



2.Synchronized


Thread는 메모리를 공유하는 특성이 있기 때문에 데이터의 간섭이 일어날 수 있다.


두 개의 thread가 돌아갈 때에 같은 데이터를 수정한다면 작업의 순서도 예측하기 어렵고 값이 어떻게 바뀔지도 모르게 된다.


Synchronized는 코드를 { }괄호로 감싸서 thread가 그 부분을 읽을 때 다른 thread에서 읽지 못하게 잠궈버린다.


먼저 들어온 thread가 작업을 마치고 다음 thread가 작업을 실행하게 된다.



package chap10.exam05.sync;

public class Computer {
	private int score;

	// 동기화 이전
	//	public void setScore(int score) {
	//		this.score = score;
	//		try {
	//			Thread.sleep(2000); // 2초 슬립 (이 사이 다른 사용자가 정보 변경 가능)
	//		} catch (InterruptedException e) {
	//			// TODO Auto-generated catch block
	//			e.printStackTrace();
	//		} 
	//		System.out.println(Thread.currentThread().getName() + " : " + this.score);
	//	}

	// 동기화 메소드 방식 : 메소드 접근을 제한
	//	public synchronized void setScore(int score) {
	//		this.score = score;
	//		try {
	//			Thread.sleep(2000); // 2초 슬립 (이 사이 다른 사용자가 정보 변경 가능)
	//		} catch (InterruptedException e) {
	//			// TODO Auto-generated catch block
	//			e.printStackTrace();
	//		} 
	//		System.out.println(Thread.currentThread().getName() + " : " + this.score);
	//	}

	// 동기화 블록 방식 : 메소드 까지는 허용, 특정 구역에서 제한

	public void setScore(int score) {
		// 스레드 들이 들어와서 작동할 수 잇음
		synchronized (this) { // this는 현재 Computer 객체
			this.score = score;
			try {
				Thread.sleep(2000); // 2초 슬립 (이 사이 다른 사용자가 정보 변경 가능)
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			System.out.println(Thread.currentThread().getName() + " : " + this.score);
		}
	}
}
package chap10.exam05.sync;

public class User1 extends Thread{
	private Computer com;
	public User1(Computer com) {
		setName("user 1");
		this.com = com;
	}
	@Override
	public void run() {
		com.setScore(500); // user 1은 점수를 500으로 만든다.
	}
	

}
package chap10.exam05.sync;

public class User2 extends Thread {
	private Computer com;
	
	public User2(Computer com) {
		setName("user 2");
		this.com = com;
	}

	@Override
	public void run() {
		com.setScore(100); // user2는 점수를 100으로 만든다.
	}

}
package chap10.exam05.sync;

public class PcRoom {

	public static void main(String[] args) {
		// 공용 컴퓨터 만들기
		Computer com = new Computer();
		//user1에게 컴 사용 하게 해줌
		User1 user1 = new User1(com);
		user1.start();
		//user2에게 컴 사용 하게 해줌
		User2 user2 = new User2(com);
		user2.start();
	}

}


'개념 및 코딩 > 08.Thread 스레드' 카테고리의 다른 글

[JAVA]08-07.Thread Pool, Pool Block  (0) 2018.09.06
[JAVA]08-05.Demon Thread  (0) 2018.09.06
[JAVA]08-04.Thread State, Control  (0) 2018.09.06
[JAVA]08-02.Runnable, Thread  (0) 2018.09.04
[JAVA]08-01.Thread  (0) 2018.09.04

1.Runnable, Thread


쓰레드는 전에 설명했듯이 작업을 병렬적으로 수행할 때에 사용하는데


실제로는 두개가 나란히 작동되는게 아니고 라운드로빈이라는 스케줄링 기법을 사용한다.


라운드로빈을 사용하기에 매번 똑같은 결과를 얻을 수 없고 작업 순서가 매번 다르게 실행된다.


CPU의 계산을 최대한 효율적이고 모든 프로그램에 공평하게 할당하기 위해 만들어낸 여러가지 기법들 중 하나이다.


Java에서는 Runnable인터페이스나 Thread 클래스를 상속 받아 멀티 스레드를 구현할 수 있다.


Runnable의 경우는 run메소드 작업을 정의 한 후 Thread 생성 시 안에 집에 넣는다.


Runnable로 따로 정의하지 않고 Thread의 오버라이드 된 run에 바로 정의를 하여도 문제가 없어 보통은 Thread만 단독으로 자주 쓴다.


익명객체를 사용하여 객체 선언과 동시 메소드를 1회용으로 만들수 있다.


다음 예제를 확인해보자.






package chap10.exam01.runnable;

public class Job implements Runnable {

	@Override
	public void run() {
		for(int i = 0; i < 5; i++) {
			System.out.println("워크 스레드 실행");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
package chap10.exam01.runnable;

public class MainThread {

	// Main Thread를 main에서 발생 시킨다.
	// 굉장히 중요
	public static void main(String[] args) {
		
		// 함께 일해줄 WorkThread 생성(Runnable)
		// 1. work thread가 해야할 일 생성
		Runnable job = new Job();
		// 2. 일 해줄 스레드 생성
		Thread thread = new Thread(job);
		// 3. 일을 시킨다. (무조건 start로 시작함)
		thread.start();
		// 동시 실행 테스트
		for(int i = 0; i < 5; i++) {
			System.out.println("메인 스레드 실행");
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}



익명객체를 이용한 스레드


package chap10.exam01.runnable;

public class AnonyMain {

	public static void main(String[] args) {
		// 스레드 생성(할 일) 과 같이 생성
		// 익명객체, 따로 java파일을 만들 필요가 없음
		Thread thread = new Thread() {			
			@Override
			public void run() {
				for(int i = 0; i < 5; i++) {
					System.out.println("워크 스레드 실행");
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		// 스레드 실행
		thread.start();
		
		// 메인에서 실행할 작업
		for(int i = 0; i < 5; i++) {
			System.out.println("메인 스레드 실행");
			try {
				Thread.sleep(400);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

}


'개념 및 코딩 > 08.Thread 스레드' 카테고리의 다른 글

[JAVA]08-07.Thread Pool, Pool Block  (0) 2018.09.06
[JAVA]08-05.Demon Thread  (0) 2018.09.06
[JAVA]08-04.Thread State, Control  (0) 2018.09.06
[JAVA]08-03.Priority, Synchronized  (0) 2018.09.06
[JAVA]08-01.Thread  (0) 2018.09.04

1.Thread


스레드는 작업을 수행하는 단위로 단순하게 cpu의 코어가 2개, 듀얼 코어라면 2개의 작업(스레드)을 동시에 할 수 있다.


지금까지의 작업은 싱글 스레드, 하나의 작업을 돌린것이다.


이 스레드를 이용하면 여러가지의 작업들 동시에, 병렬적으로 처리 할 수 있다.


public static void main(String[] args)가 있는 스레드를 메인 스레드라고 하고


스레드를 추가하여 병렬작업을 하는것을 멀티 스레딩이라고 한다.


멀티 스레딩의 장단점으로는 아래와 같다.


 - 장점


CPU 이용률 향상

효율적인 자원 활용

수행 기능별로 분리하여 코드가 간결해짐

어플리케이션의 응답성 향상


 - 단점


같은 프로세스의 자원을 공유하므로 동기화가 필요

동기화 처리에 관한 이슈 처리 필요(교착상태, 기아상태 등)

CPU환경이나 OS의 스케줄러를 고려해야 함

'개념 및 코딩 > 08.Thread 스레드' 카테고리의 다른 글

[JAVA]08-07.Thread Pool, Pool Block  (0) 2018.09.06
[JAVA]08-05.Demon Thread  (0) 2018.09.06
[JAVA]08-04.Thread State, Control  (0) 2018.09.06
[JAVA]08-03.Priority, Synchronized  (0) 2018.09.06
[JAVA]08-02.Runnable, Thread  (0) 2018.09.04

1.스택(Stack)


스택과 큐는 자료구조를 공부한다면 바로 접할 수 있는 그 스택과 큐다.


스택은 LIFO(Last in First Out)으로 마지막으로 들어온 자료가 처음으로 나온다. 의미 그대로의 자료 구조를 가지고 있다.


수건을 예로 든다면 잘 개어진 수건을 사용한다고 할 때에 수건을 개어서 쌓아서 보관을 한다.


1. 쌓아서 차곡차곡 위에 올려서 보관하고


2. 꺼내 쓸 때에는 맨 위부터 하나씩 빼게 된다.


스택의 자료구조도 이와 같은 느낌이다.


Java에서도 사용 할 수 있게 구현이 되어있다 다음 예를 통해 메소드 활용과 함께 확인해보자



package chap09.exam05.stack;

public class Towel {
	
	private String color;

	public Towel(String color) {
		this.color = color;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}	

}
package chap09.exam05.stack;

import java.util.Stack;

public class TowelBox {

	public static void main(String[] args) {

		// 수건통
		Stack<Towel> box = new Stack<Towel>();
		
		// 넣기(push)
		box.push(new Towel("red"));
		box.push(new Towel("orange"));
		box.push(new Towel("yellow"));
		box.push(new Towel("green"));
		box.push(new Towel("blue"));
		box.push(new Towel("blush violet"));
		box.push(new Towel("purple"));
		System.out.println(box.size());
		
		// 수건 빼기
		Towel towel = box.pop();
		System.out.println(towel.getColor());
		System.out.println(box.size());
		
		// 타올을 뺀 다음 색상 확인(메소드 체이닝)
		System.out.println(box.pop().getColor());
		System.out.println(box.size());
		
		// 남아있는 수건을 하나씩 뽑아서 모두 색상을 확인
		int number = box.size();
		for(int i = 0; i < number; i++) {
			System.out.println(box.pop().getColor());
			System.out.println(box.size());
		}
		// for문이나 while문 셋 중 두개만 주석(ctrl + /)처리해서
		// 테스트 해보면 같은 결과를 얻을 수 있음
		while(box.size() > 0) {
			// pop은 값을 확인하고 버림
			System.out.println(box.pop().getColor());
			// peek은 값을 확인만 함
//			System.out.println(box.peek().getColor());
			System.out.println(box.size());
		}
		// 향상된 for에서 내부적으로 pop을 사용하지 않고 있음
		for(Towel item:box) {
			System.out.println(item.getColor());
			System.out.println(box.size());
		}
	}

}



2.큐(Queue)


큐는 스택과 마찬가지로 대표적인 자료구조로 FIFO구조로 이루어진다.


First In First Out이고 처음 들어온 자료가 처음부터 나가는것이다.


마찬가지로 예를 든다면


1. 가게에 물건을 사러 1~5번 손님이 번호에 맞춰 순서대로 계산대에 서게 된다면


2. 1번 손님이 먼저 왔으니 먼저 계산하는 구조


이와 같이 큐는 들어온 순서대로 나가는 구조이다.



package chap09.exam06.queue;

public class Job {

	private String command;
	private String to;
	
	public Job(String command, String to) {
		this.command = command;
		this.to = to;
	}
	
	//command와 to의 수정을 허용하지 않으므로 getter만 만듬

	public String getCommand() {
		return command;
	}

	public String getTo() {
		return to;
	}
	

}
package chap09.exam06.queue;

import java.util.LinkedList;
import java.util.Queue;

public class JobList {

	public static void main(String[] args) {
		// Queue 생성 - 내부구조는 링크드 리스트
		Queue<Job> list = new LinkedList<Job>();
		// 값을 넣을 때 offer
		list.offer(new Job("Send SMS", "A"));
		list.offer(new Job("Send Mail", "B"));
		list.offer(new Job("Send SMS", "C"));
		list.offer(new Job("Send Kakao", "D"));
		list.offer(new Job("Send Call", "E"));
		
		// 등록된 해야할 일(누구에게 무얼 하는지)을 모두 확인 하기
		// 값을 뺄 때 poll
		// peek 확인만 할 때
		// size를 통해 크기 확인
		// isEmpty
//		System.out.println(list.isEmpty());
//		System.out.println(list.size());
//		System.out.println(list.poll().getTo() + "의 다음 사람에게 할 일 : " + list.poll().getCommand());
//		System.out.println(list.poll().getTo() + "의 다음 사람에게 할 일 : " + list.poll().getCommand());
//		System.out.println(list.peek().getTo() + "에게 할 일 : " + list.poll().getCommand());
//		System.out.println(list.size());
//		System.out.println(list.isEmpty());
		
		while(list.size() > 0) {
			System.out.println("남은 작업 개수 : " + list.size());
			Job j = list.poll();
			System.out.println(j.getCommand() + " to " + j.getTo());
		}
	}

}


주석문은 직접 지웠다가 다시 붙였다가 하며 테스트를 해보자(Ctrl+/)

'개념 및 코딩 > 07.Collection Framework' 카테고리의 다른 글

[JAVA]07-04.HashMap, HashTable  (0) 2018.09.04
[JAVA]07-03.Hashset  (0) 2018.09.04
[JAVA]07-02.ArrayList, LinkedList  (0) 2018.09.04
[JAVA]07-01.Collection, Map  (0) 2018.09.04

1.HashMap, HashTable


해쉬 맵과 해쉬 테이블은 Key와 Value를 저장하는데 Key는 데이터를 구분할 이름이라 이해하고


Value는 내용인 값이 저장될 자리이다.


해쉬의 값은 key값을 알아야만 Value값을 추출 할 수 있고 key값을 알 경우에는 상관 없지만


모를 경우에는 Iterator을 이용해 key값을 추출 할 수 있다.


만약 key value값을 둘 다 빼내고 싶다면 Entry와 Iterator을 같이 이용하면 된다. 아래 예제를 확인해보자


맵과 테이블의 차이점은 동기화의 유무이다. 다중 스레드(동시 작업)을 이용 할 경우 맵의 경우는 동기화를 하지 않고


테이블의 경우는 동기화를 해준다.


테이블은 동기화를 하기 때문에 맵에 비해서 자원의 소모가 조금 더 있는 편이다.



package chap09.exam04.map;

import java.util.Map.Entry;
import java.util.HashMap; // <- impor문 정리하는 방법
import java.util.Iterator;
import java.util.Set;
									// Ctrl + shift + O

public class HashMapEx {

	public static void main(String[] args) {
		// HashMap = Key - Value  << 중요, 많이 쓰임
		HashMap<String, Integer> map = new HashMap<String, Integer>();
		
		map.put("kim",  23); // value의 Type을 반환하게 되어있다.
		map.put("lee",  26);
		map.put("park",  26);
		map.put("kim",  37); // 키가 중복인 경우 덮어쓴다.
		System.out.println(map.size());
		// 맵에서 값 꺼내기(키를 이용하여 빼온다)
		System.out.println(map.get("lee"));
		
		// map의 모든 값을 출력 1 : 키 값만 이용하여 추출
		// key 만 가져온다.
		Set<String> keySet = map.keySet();
		// key를 조각 낸다.
		Iterator<String>iter = keySet.iterator();
		//key로 value를 하나씩 가져온다.
		while(iter.hasNext()) { // 값이 존재 하는가?
			String key = iter.next(); // 있으면 뽑아온다.
			System.out.println(map.get(key));
		}
		System.out.println();
		for(String key : keySet) {
			System.out.println(map.get(key));
		}
		
		// map의 모든 값을 출력 2 : 키-값 단위로 가져온 후 추출
		// map에서 entry를 뽑아옴 : entry (key-value 한 쌍으로 잘라줌)
		Set<Entry<String, Integer>> entry = map.entrySet();
		// 가져올 수 있도록 잘라줌
		Iterator<Entry<String, Integer>> iterlator = entry.iterator();
		// 하나씩 꺼내옴(키-값 한 쌍)
		while(iterlator.hasNext()) {
			Entry<String, Integer> item = iterlator.next();
			// entry로 부터 키와 값을 뽑아냄
//			String key = item.getKey();
//			int value = item.getValue();
			System.out.println(item.getKey() + " : " +  item.getValue());
		}
	}

}
package chap09.exam04.map;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class HashTableEx {

	public static void main(String[] args) {
		// 사용법은 HashMap과 동일
		Map<String, Integer> map = new Hashtable<String, Integer>();
		map.put("a", 70);
		map.put("b", 80);
		map.put("c", 60);
		map.put("d", 90);
		map.put("e", 75);
		map.put("f", 45);
		map.put("g", 30);
		map.put("h", 50);
		map.put("i", 55);
		map.put("j", 99);
		
		// 찾는 키가 있으면 키의 값을 보여주고, 없으면 없다고 알림
		// 찾는 이름 : d
		if(map.containsKey("d")) {
			System.out.println("d의 점수 : " + map.get("d"));
		} else {
			System.out.println("찾으시는 값은 없어염");
		}
		
		// 99점 학생이 존재 하는지?
		if(map.containsValue(99)) {
			System.out.println("99점이 있었네...");
		} else {
			System.out.println("찾으시는 분은 안계세yo");
		}
		
		// 99점 학생은 누구인가?(값으로 키를 찾는 방법)
		
		// 키셋 방법
		Set<String> keySet = map.keySet();
		// key를 조각 낸다.
		Iterator<String>iter = keySet.iterator();
		//key로 value를 하나씩 가져온다.
		while(iter.hasNext()) { // 값이 존재 하는가?
			String key = iter.next(); // 있으면 뽑아온다.
			int value = map.get(key);
			if(value == 99) {
				System.out.println("99점인 사람 : " + key + ", " + value);
			}
		}
		
		// 엔트리 방법
		// 1. map의 entry(키-값)을 set으로 반환
		Set<Entry<String, Integer>> entries = map.entrySet();
		// 2. 잘라낼 수 있도록 Iterator 화
		Iterator<Entry<String, Integer>> iter2 = entries.iterator();
		// 3. 하나씩 뽑아내서 값을 비교
		while(iter2.hasNext()) {
			Entry<String, Integer> item = iter2.next();
			if(item.getValue() == 99) {
				System.out.println("99점 학생 : " + item.getKey());
			}
		}
		
		// 번외 향상된 for문 가능?
		for(Entry<String, Integer> item : entries) {
			System.out.println(item.getKey() + " : " + item.getValue());
		}
	}

}


'개념 및 코딩 > 07.Collection Framework' 카테고리의 다른 글

[JAVA]07-05.Stack, Queue  (0) 2018.09.04
[JAVA]07-03.Hashset  (0) 2018.09.04
[JAVA]07-02.ArrayList, LinkedList  (0) 2018.09.04
[JAVA]07-01.Collection, Map  (0) 2018.09.04

1.HashSet


HashSet은 하나씩 저장되고 중복을 혀용하지 않는 컬렉션이다.


HashSet부터는 자료를 입력할 때에는 상관없으나 꺼내올 때에는 따로 Iterator라는 인터페이스를 사용해야 한다.


다음 예제를 작성하여 눈에 익혀보자


예제의 클래스 파일을 HashSet이라 명명하고 사용 할 경우 사용할 HashSet과 이름이 겹치게 된다.


그러므로 구분을 위해서 java.util.HashSet처럼 표시되지만 이러한 클래스 파일 명명은 쓰지 않는것이 좋다.



package chap09.exam03.hashset;

import java.util.Iterator;
import java.util.Set;

public class HashSet {

	public static void main(String[] args) {
		
		// 사용하는 클래스와 현재의 클래스 명이 같으면 객체화 시
		// 경로까지 표시된다.
		Set<String> set = new java.util.HashSet<String>();
		Set<Member> member = new java.util.HashSet<Member>();
		
		set.add("JAVA");
		set.add("ORACLE");
		set.add("MVC");
		set.add("JSP");
		set.add("JAVA"); // 중복이라서 입력되지 않음
		System.out.println(set.size());
		member.add(new Member());
		member.add(new Member()); // 중복이지만 객체는 복사본으로 중복으로 보지 않음
		System.out.println(member.size());
		
		
		
		// 하나씩 뽑아 오기 1번
		// set -> iterator : 조각내기 -> next() : 뽑아오기
		Iterator<String> iter = set.iterator();
		while(iter.hasNext()) {
			String item = iter.next();
			System.out.println(item);
		}
		
		// 삭제
		set.remove("ORACLE");
		
		// 하나씩 뽑아 오기 2번
		for(String item : set) {
			System.out.println("향상된 for : " + item);
		}

		// 비우기
		set.clear();
		// 비어있는지 확인
		System.out.println("비어있을까? : " + set.isEmpty());
	}

}

class Member{
	
}



'개념 및 코딩 > 07.Collection Framework' 카테고리의 다른 글

[JAVA]07-05.Stack, Queue  (0) 2018.09.04
[JAVA]07-04.HashMap, HashTable  (0) 2018.09.04
[JAVA]07-02.ArrayList, LinkedList  (0) 2018.09.04
[JAVA]07-01.Collection, Map  (0) 2018.09.04

1.ArrayList


어레이 리스트는 배열과 똑같이 0번방부터 시작해서 자료가 들어오는대로 1, 2, 3, ~ 늘어나는 구조이다.


배열을 쓰다가 ArrayList를 배운다면 배열을 잘 쓰지 않게 될 것이다.


배열과 달리 크기를 따로 지정할 필요 없고 add를 통해 언제든지 값을 추가 또는 삽입할 수 있다.


하지만 메모리 저장 구조상 어레이 리스트는 삽입과 삭제를 남발한다면 자원이 낭비될 수 있다.


만약 메모리에 ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ와 같이 저장되 있다고 할 때에


'ㅂ'자리에 자료를 추가한다면 뒤에 있는 자료를 하나씩 순서를 다 밀어줘야 하기 때문에 느려지게 된다.


ArrayList는 다양한 기능을 가지고 있는데 아래의 예제를 통해 확인해보자



package chap09.exam01.arrList;

import java.util.ArrayList;

public class ArrayList01 {

	public static void main(String[] args) {
		// ArrayList는 크기 지정을 할 필요가 없다.
//		ArrayList<String>list = new ArrayList<String>();
		// 방 크기를 지정한다면 메모리 공간 확보에 좋음
		ArrayList<String>list = new ArrayList<String>(3);
		list.add("collection"); // 0번 인덱스
		list.add("thread"); // 1번 인덱스
		list.add("java io"); //2번 인덱스
		list.add("network"); // 배열 같으면 예외가 발생
		list.add(3, "lambda"); // [3] = lambda, [4] = network로 밀림
		// bool값 반환은 값이 성공적으로 삽입됫다는 뜻
		
		
		// 크기 반환
		System.out.println(list.size());
		
		// 특정 인덱스의 값 확인
		System.out.println(list.get(3));
		System.out.println(list.get(4));
		
		System.out.println("--------------------------------");
		
		// for문을 이용하여 모든 값 출력
		for(int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		
		System.out.println("--------------------------------");
		
		// 삭제하기
		// 중간의 인덱스 삭제 삽입은 메모리 사용에 비효율적이라 남발하는건 안좋음
		System.out.println(list.remove("thread"));
		System.out.println(list.size());
		System.out.println(list.remove(2));
		System.out.println(list.size());
		
	}

}
package chap09.exam01.arrList;

import java.util.ArrayList;
import java.util.Arrays;

public class ArrayList02 {

	// 배열의 값을 ArrayList로
	public static void main(String[] args) {
		// 배열
		String[] arr = {"list", "set", "map"};
		// array -> List : 조회는 되지만 변경은 불가능
		java.util.List<String> list = Arrays.asList(arr);
		System.out.println(list.size());
		System.out.println(list.get(1));
		
		// ArrayList.addAll은 Collection 타입을 인자로 받음
		// List -> ArrayList : 일괄적으로 List의 값을 ArrayList에 부어줌
		ArrayList<String> arrlist = new ArrayList<String>();
		arrlist.addAll(list);
		arrlist.add("collection");
		System.out.println();
		for(String item : arrlist) {
			System.out.println(item);
		}
		
	}

}
package chap09.exam01.arrList;

import java.util.ArrayList;

public class ArrayList03 {

	public static void main(String[] args) {
		ArrayList<Integer> score = new ArrayList<Integer>();
		
		score.add(70);  // 0
		score.add(80);  // 1
		score.add(50);  // 2
		score.add(90);  // 3
		score.add(100);// 4
		score.add(90);  // 5
		
		// 데이터 갯수 반환
		System.out.println(score.size() + "\n");
		// 데이터 수정 : 특정 인덱스의 값을 변경
		score.set(3, 95);
		System.out.println(score.get(3) + "\n");
		// 값 유무 확인 : 해당 값의 유무를 참/거짓으로 반환
		System.out.println(score.contains(30) + "\n");
		// 위치 확인
		System.out.println(score.indexOf(90) + "\n");
		// 비우기
		score.clear();
		// 비움상태 확인
		System.out.println(score.isEmpty());;
		System.out.println(score.size());

	}

}




2.LinkedList


링크드 리스트는 어레이 리스트와 매우 유사하다.


하지만 메모리 저장 방법이 어레이 리스트와 다르다.


자료마다 전에 저장한 자료, 다음 자료의 위치가 저장되고 어레이 리스트의 단점인 중간에 자료를 넣을 경우


앞의 자료와 뒤의 자료의 저장 위치만 살짝 수정하면 해결되기 때문에 훨씬 빠르다.


다음 예제를 직접 실행해보아 시간 차이를 확인해보자.



startTime = System.currentTimeMillis(); 을 통해서 작업 시작했을 때의 시간을 넣고


endTime = System.currentTimeMillis();을 통해서 작업이 끝났을 때의 시간을 넣는다.


그리고 endTime - startTime으로 시간 차를 비교하여 출력


Mill은 1초를 1000으로 나눈 값이다.

package chap09.exam02.linkList;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ListBenchMark {

	public static void main(String[] args) {

		// 선수 준비
		List<String> arr = new ArrayList<String>();
		List<String> link = new LinkedList<String>();
		// 조건
		for(int i = 1; i <= 100; i++) {
			arr.add("datadatadatadatadata");
			link.add("datadatadatadatadata");
		}
		// 초시계(걸린시간 = 도착시간 - 출발시간)
		long endTime = 0;
		long startTime = 0;

		// 측정  // 어떤 구현이든 구현에는 순서를 생각해 놓는게 중요
		/*ArrayList 체크*/
		// 타임워치 시작
		// 현재시간을 1/1000초로 환산
		startTime = System.currentTimeMillis();
		// 선수 달리기
		for(int i = 1; i < 1000000; i++) {
			// 중간에 넣는 실험
			// 뒤로 넣는 것을 시험하고 싶으면 index 값을 지운다.
			arr.add(55, "Add Data");
		}
		// 타임워치 스톱
		endTime = System.currentTimeMillis();
		// 결과 확인
		System.out.println("결과 : " + (endTime - startTime) + "mil");

		/*LinkedList 체크*/
		// 타임워치 시작
		// 현재시간을 1/1000초로 환산
		startTime = System.currentTimeMillis();
		// 선수 달리기
		for(int i = 1; i < 1000000; i++) {
			link.add(55, "Add Data");
		}
		// 타임워치 스톱
		endTime = System.currentTimeMillis();
		// 결과 확인
		System.out.println("결과 : " + (endTime - startTime) + "mil");
	}

}



'개념 및 코딩 > 07.Collection Framework' 카테고리의 다른 글

[JAVA]07-05.Stack, Queue  (0) 2018.09.04
[JAVA]07-04.HashMap, HashTable  (0) 2018.09.04
[JAVA]07-03.Hashset  (0) 2018.09.04
[JAVA]07-01.Collection, Map  (0) 2018.09.04

1.Collection Framework, Map (컬렉션 프레임워크, 맵)


컬렉션은 배열의 상위 버젼들이라고 생각하면 편하다.


아래와 같은 그림과 같이 Collection의 자식인 List Set Map이 있고 각자 특징과 사용처가 따로 있다.


전부 제네릭으로 타입을 정하여 원하는 자료형을 받아서 사용할 수 있다.



특징으로는 다음과 같다.


 인터페이스 분류

특징 

구현 클래스 

 Collection

List 

순서를 유지하고 저장

중복 저장 가능

ArrayList

Vector

LinkedList

Set

순서를 유지하지 않고 저장

중복 저장 안됨

HandSet

TreeSet 

 Map

키와 값의 쌍으로 저장

키는 중복 안 됨

값은 중복 저장 가능

HashMap

Hashtable

TreeMap

LinkedHashMap



처음 봤을때는 이해가 가지 않을거지만 뒤에 나오는 ArrayList부터 Hashtable


추가로 Stack과 Queue를 보고오면 이해가 갈 것이다.

'개념 및 코딩 > 07.Collection Framework' 카테고리의 다른 글

[JAVA]07-05.Stack, Queue  (0) 2018.09.04
[JAVA]07-04.HashMap, HashTable  (0) 2018.09.04
[JAVA]07-03.Hashset  (0) 2018.09.04
[JAVA]07-02.ArrayList, LinkedList  (0) 2018.09.04

1.Generic 메소드


메소드 안에서 객체화


package chap08.exam08.gmethod;

public class Gmethod {
	
	// 매개변수에 T 사용
	// 인자값의 타입에 따라 제너릭에 영향을 준다.
	// 들어오는 타입에 따라 대응이 된다.
	public <T> void method1(T t) {
		System.out.println("입력 값 : " + t);
	}
	
	// 받은 값을 그대로 반환
	public<T> T method2(T a) {
		return a;
	}
	
	// 매개변수를 이용한 반환타입 설정
	public <T> Box<T> method3(T t){ // 1. 100이 들어온다.
													// 2. T의 타입이 Integer가 된다.
		Box<T> box = new Box<T>();   // Integer 형태로 객체화
													// 객체에 100이 들어간다.
		box.setValue(t);
		return box;								// 이 객체를 반환 한다.
	}
}
package chap08.exam08.gmethod;

public class Box<T> {
	// 아직 뭔지는 모르나 어떤 타입이 설정 될 예정
	// 타입이 설정되면 클래스 모든 타입이 통일 된다.
	// 클래스 선언/객체화 될 때 타입을 설정함.
	// T 자리에는 쓰고싶은거 써도 됨
	private T value;

	public T getValue() {
		return value;
	}

	public void setValue(T value) {
		this.value = value;
	}
}
package chap08.exam08.gmethod;

public class Main {

	public static void main(String[] args) {
		Gmethod test = new Gmethod();
		
		test.method1("ㅎㅇ");
		
		String str = test.method2("고길동 재산 : ");
		int money = test.method2(Integer.MAX_VALUE);
		System.out.println(str + money);
		
		Box<Integer> box1 = test.method3(100);
		System.out.println(box1.getValue());
		Box<String> box2 = test.method3("hong");
		System.out.println(box2.getValue());
		
		// Method의 return type과 Reference type이
		// 상황에 따라 유연하게 변경가능
	}

}






2.Generic 상속


Generic 역시 상속이 가능하다.



package chap08.exam09.inheritance; public class BasicInfo <N, A> { private N name; private A age; public N getName() { return name; } public void setName(N name) { this.name = name; } public A getAge() { return age; } public void setAge(A age) { this.age = age; } }

package chap08.exam09.inheritance;

public class DetailInfo<N, A, H> extends BasicInfo<N, A> {
	private H hobby;

	public H getHobby() {
		return hobby;
	}

	public void setHobby(H hobby) {
		this.hobby = hobby;
	}
	
}
package chap08.exam09.inheritance;

public class Main {

	public static void main(String[] args) {
		//
		DetailInfo<String, Integer, String> info = new DetailInfo<String, Integer, String>();
		
		info.setName("둘리");
		info.setAge(56);
		info.setHobby("호잇");
		
		System.out.println(info.getName() + ", 나이는 " + info.getAge() + "\n" + "취미는 " + info.getHobby());
	}

}



'개념 및 코딩 > 06.기타' 카테고리의 다른 글

[JAVA]06-06.Generic  (0) 2018.09.03
[JAVA]06-05.Object  (0) 2018.09.03
[JAVA]06-04.String  (0) 2018.09.03
[JAVA]06-03.Throw 예외처리, 커스텀 예외처리  (0) 2018.09.03
[JAVA]06-02.예외처리 instance of, try catch  (0) 2018.09.03

1.Generic


Generic은 클래스의 인자를 유동적으로 사용하기 위해 만들어진 개념이다.


클래스 생성자나 메소드 그리고 변수의 자료형은 상황에 따라서 유동적일 필요가 있기 때문이다.


사용법은 [접근제한자] class [이름] [<A, B, C, .....>] 와 같이 사용할 자료형 갯수만큼 <> 안에 넣어두면 된다.


기본적인 예제



package chap08.exam04.generic;

public class Box<T> {
	// 아직 뭔지는 모르나 어떤 타입이 설정 될 예정
	// 타입이 설정되면 클래스 모든 타입이 통일 된다.
	// 클래스 선언/객체화 될 때 타입을 설정함.
	// T 자리에는 쓰고싶은거 써도 됨
	private T value;

	public T getValue() {
		return value;
	}

	public void setValue(T value) {
		this.value = value;
	}
}
package chap08.exam04.generic;

public class Main {

	public static void main(String[] args) {
		// 객체화 할 때 타입을 지정
		Box<Integer> box = new Box<Integer>(); // 뒤에 인티져는  생략 가능
		box.setValue(1234);
		int val = box.getValue();
		System.out.println(val);
	}

}



제네릭 선언시에는 다음과 같이 인자를 무한히 사용 할 수 있다.


하지만 getter와 setter 설정과 선언, 객체화 시 번거로움이 생긴다.



package chap08.exam05.multi;
// 복수의 파라미터는 , 로 구분
public class MultiBox<K, V> {
	
	private K key;
	private V value;
	public K getKey() {
		return key;
	}
	public void setKey(K key) {
		this.key = key;
	}
	public V getValue() {
		return value;
	}
	public void setValue(V value) {
		this.value = value;
	}
}
package chap08.exam05.multi;

public class Main {

	public static void main(String[] args) {
		MultiBox<String, Integer> box = new MultiBox<String, Integer>();
		
		// 추천 메소드 항목에서도 반환타입이 바뀐걸 확인 할 수 있다.
		// 데이터 넣기
		box.setKey("홍길동");
		box.setValue(90);
		
		// 데이터 빼기
		String name = box.getKey();
		int score = box.getValue();
		System.out.println(name + " : " + score);
	}

}



제네릭 응용


제네릭의 요소가 너무 많을경우 코드 길이가 길어지고 작성하는데도 오래 걸리지만 다음과 같이 사용하면 된다.



package chap08.exam07.classtype;

public class Employee <T> {
	
	private T t;

	public T getT() {
		return t;
	}

	public void setT(T t) {
		this.t = t;
	}
}
package chap08.exam07.classtype;

public class Info {
	
	private int emp_no;
	private String name;
	private int age;
	private long salary;
	private long asset;
	private float commision;
	private boolean married;
	private String hobby;
	public int getEmp_no() {
		return emp_no;
	}
	public void setEmp_no(int emp_no) {
		this.emp_no = emp_no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public long getSalary() {
		return salary;
	}
	public void setSalary(long salary) {
		this.salary = salary;
	}
	public long getAsset() {
		return asset;
	}
	public void setAsset(long asset) {
		this.asset = asset;
	}
	public float getCommision() {
		return commision;
	}
	public void setCommision(float commision) {
		this.commision = commision;
	}
	public boolean isMarried() {
		return married;
	}
	public void setMarried(boolean married) {
		this.married = married;
	}
	public String getHobby() {
		return hobby;
	}
	public void setHobby(String hobby) {
		this.hobby = hobby;
	}
}
package chap08.exam07.classtype;

public class Main {

	public static void main(String[] args) {
		Employee<Info> emp = new Employee<Info>();
		// 넣는 과정 info에다가 값 넣음 -> Employee에 저장
		Info info = new Info();
		
		info.setEmp_no(123);
		info.setName("Kim");
		info.setSalary(1000000);
		info.setHobby("movie");
		emp.setT(info);
		// emp에서 info를 빼옴 -> info에서 개별값을 꺼내옴
		info = emp.getT();
		System.out.println(info.getEmp_no());
		System.out.println(info.getName());
		System.out.println(info.getSalary());
		System.out.println(info.getAge());
	}

}


+ Recent posts