ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 컬렉션 프레임워크(List, Set, Map)
    JAVA 2022. 9. 24. 20:04

    collection frameworkcollection interface를 최상위로 하는 자료구조 interface이다.

     

     

    전체 구조

     

    컬렉션 프레임워크의 장점

    다양한 자료구조를 가지고 있고 가변적인 크기를 통해 유연한 사용을 할 수 있다.

     

    컬렉션 프레임워크 특징

    컬렉션 프레임워크에서 데이터 추가, 삭제, 검색 방법이 비슷하다

    왜냐하면 최상위의 컬렉션 프레임워크가 하위의 List, Set interface를 구현하기 때문이다.

    이 때 인터페이스 구현 시 장점은? 필수 method를 강제할 수 있다.

     

    ArrayList

    index를 사용한다는 점에서 Array와 비슷하다.

    가변적인 크기를 가지고 있어 크기가 무제한으로 늘어난다.

    값을 추가/삭제 하면 index1씩 당겨지거나 미뤄지게 된다.

    따라서 빈번한 값의 추가/삭제는 무리가 간다.

    배열은 같은 인덱스에 중복해서 값을 넣을 경우 값이 덮어쓰게 된다.

    반면에 ArrayList는 같은 인덱스에 중복해서 값을 넣을 경우 계속 밀리게 되어 덮어쓰지 않는다.

     

    list.size() : 크기를 반환한다.

    list.get(index) : 인덱스의 값을 반환한다.

    list.remove(index) : 인덱스의 값을 삭제하고 그 값을 반환한다.

    list.indexOf() : 특정한 값이 있는 인덱스를 반환한다.

    list.contains() : 값의 포함 여부를 참/거짓으로 반환한다.

    list.set(인덱스,) : 특정 인덱스의 값을 입력 값으로 변경한다.

    list.clear() : 리스트를 비운다.

    list.isEmpty() : 리스트가 비워져 있는지 참/거짓으로 반환한다.

     

    package chap09.ex01.arList;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ArrayList01 {
    
    	public static void main(String[] args) {
    
    		//ArrayList<String> list = new ArrayList<String>();
    		List<String> list = new ArrayList<String>(3); // 크기 지정 가능, 안 해도 상관 없음
    		String[] arr = new String[3];
    		
    		// 데이터 추가
    		arr[0] = "test";
    		
    		list.add("collection"); //0
    		list.add("thread"); //1
    		list.add("java IO"); //2
    		list.add("NETWORK"); //3 <- 배열 같았으면 Exception 발생
    		list.add(3, "lamda"); //배열같은 경우에는 덮어쓰게 된다. 그런데 리스트에서는 ([3]lamda [4]NETWORK)
    		
    		//리스트 개수 : list.size()
    		//특정 인덱스 값 꺼내오기 : list.get(index)
    		//이것들을 활용해서 리스트 안에 값을 하나씩 가져오기
    		
    		for(int i=0 ; i<list.size() ; i++) {
    			System.out.print(list.get(i) + "\t");
    		}
    		
    		System.out.println();
    		
    		System.out.println("삭제한 값 : " + list.remove(2)); // 인덱스로 삭제하면 삭제한 값을 반환한다.
    		System.out.println("삭제 성공 여부 : " + list.remove("collection")); // 값으로 삭제하면 성공 여부를 반환한다.
    		
    		for (String item : list) {
    			System.out.print(item + "\t");
    		}
    		
    		
    	}
    
    }

     

    Array에서 ArrayList로 변환하는 방법

    Array에 담겨져 있는 모든 값을 한 번에 저장하기 위해서 Array -> List -> ArrayList 형태로 변환한다.

    우선 List로 변환하기 위해서 Arrays.asList(배열)로 변환한다.

    이 때 List는 인터페이스이기 때문에 값을 확인하는 것은 가능하지만 추가/삭제가 불가능하다.

    추가/삭제를 하기 위해서 ArrayList로 변환해야 하는데 이 때 addAll(리스트)를 사용하면 모든 값을 한 번에 추가할 수 있다.

     

    package chap09.ex01.arList;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class ArrayList02 {
    
    	// array -> ArrayList 변환
    	public static void main(String[] args) {
    
    		// 가끔 배열을 ArrayList로 변환할 경우도 있다.
    		String[] arr = {"List","Set","Map"};
    		
    		// Array -> List -> ArrayList
    		//1. Array -> List (interface)
    		List<String> list = Arrays.asList(arr);
    		System.out.println(list.size());
    		System.out.println(list.get(1));
    		//list.add("collection"); // List는 인터페이스이기 때문에 보는 것만 가능하고, 쓰지는 못한다.
    		
    		//2. List -> ArrayList
    		// List에 있는 값을 뽑아서 ArrayList에 넣어줘야 한다.
    		ArrayList<String> arrList = new ArrayList<>();
    		arrList.addAll(list); // addAll로 List를 전부 한 번에 넣을 수 있다.
    		arrList.add("collection");
    		
    		for (String item : arrList) {
    			System.out.print(item+"\t");
    		}
    		
    	}
    
    }

     

    ArrayListVector의 차이점

    모든 기능은 똑같지만 ArrayList는 다중 유저의 사용을 허용하고 Vector는 다중 유저의 사용을 허용하지 않는다.

     

    package chap09.ex01.arList;
    
    import java.util.Vector;
    
    public class ArrayList03 {
    
    	public static void main(String[] args) {
    
    		Vector<Integer> score = new Vector<Integer>();
    		score.add(70); //0
    		score.add(50); //1
    		score.add(80); //2
    		score.add(90); //3
    		score.add(100); //4
    		score.add(90); //5
    		
    		// 검색
    		// indexOf() : 특정한 값을 찾아 인덱스를 반환
    		System.out.println(score.indexOf(90));
    		
    		// contains() : 포함 여부를 참/거짓으로 반환
    		System.out.println(score.contains(30));
    		
    		// 수정
    		score.set(3, 95); // 특정 인덱스를 특정 값으로 변경
    		
    		//리스트 비우기
    		//[10][20][30][4][5]
    		score.clear(); // 리스트를 깔끔하게 비운다.
    		
    		// 비워졌는지 확인
    		System.out.println(score.isEmpty()); // 리스트가 비워졌는지 참/거짓으로 반환
    		
    	}
    
    }

     

    ArrayListLinkedList의 차이점

    ArrayList는 배열 형식으로 저장이 되고 LinkedList는 각 노드에 데이터가 저장되고 다음 노드를 가리키는 포인터있어서 연결되어 있는 형식이다.

    저장된 데이터가 많아질수록 LinkedList가 더 빠르다. -> 데이터가 추가/삭제될 경우 포인터가 가리키는 값만 바꾸면 되기 때문에

     

    package chap09.ex02.link;
    
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    
    public class BenchMark {
    
    	public static void main(String[] args) {
    		// A와 B 달리기 측정
    
    		// 선수 준비
    		ArrayList<String> arr = new ArrayList<String>();
    		LinkedList<String> lnk = new LinkedList<String>();
    
    		// 장소 준비 (데이터 100개 채우기)
    		for (int i = 0; i < 100; i++) {
    			arr.add("data");
    			lnk.add("data");
    		}
    
    		// 시계 준비 (걸린 시간 = 도착 시간 - 출발 시간)
    		long startTime = 0;
    		long endTime = 0;
    
    		// ArrayList 의 출발 시간 기록
    		startTime = System.currentTimeMillis(); // 현재 시간을 1000/1 초로 환산
    
    		// 달리기
    		for (int i = 1; i <= 100000; i++) {
    			arr.add(55, "add data");
    		}
    		
    		// ArrayList 도착 시간 기록
    		endTime = System.currentTimeMillis();
    		System.out.println("ArrayList 걸린 시간 : " + (endTime - startTime) + " ms");
    
    		// LinkedList 의 출발 시간 기록
    		startTime = System.currentTimeMillis(); // 현재 시간을 1000/1 초로 환산
    
    		// 달리기
    		for (int i = 1; i <= 100000; i++) {
    			lnk.add(55, "add data");
    		}
    		
    		// LinkedList 도착 시간 기록
    		endTime = System.currentTimeMillis();
    		System.out.println("LinkedList 걸린 시간 : " + (endTime - startTime) + " ms");
    
    	}
    
    }

     

    HashSet

    Set은 중복된 값을 허용하지않고 값의 순서가 없다.

    따라서 검색 기능을 사용할 수 없기 때문에 iterator를 사용해야 한다.

    ArrayList와 마찬가지로 collection interface를 구현받기 때문에 사용하는 메소드가 거의 같다.

    iterator 시키면 next()를 통해 값을 꺼내올 수 있다.

    hasNext()를 통해 더 이상 꺼내올 값이 없는지 확인할 수 있다.

    향상된 for문을 사용하면 더 편하게 꺼내올 수 있다.

     

    package chap09.ex03.set;
    
    import java.util.Iterator;
    import java.util.Set;
    
    class Member{
    	
    }
    
    public class HashSet {
    
    	public static void main(String[] args) {
    		
    		// 현재 클래스와 사용할 클래스 이름이 동일하면 자동으로 패키지명을 포함한 클래스명이 나타난다.
    		// 가급적이면 겹치지 않는 클래스 이름을 사용해야 한다.
    		Set<String> set = new java.util.HashSet<>();
    		
    		/*데이터 추가 - java, jsp, oracle, mvc, java*/
    		set.add("java");
    		set.add("jsp");
    		set.add("oracle");
    		set.add("mvc");
    		set.add("java"); // 중복
    		
    		System.out.println(set.size());
    		
    		Set<Member> members = new java.util.HashSet<>();
    		
    		members.add(new Member());
    		members.add(new Member());
    		members.add(new Member());
    		System.out.println(members.size());
    		
    		// Set에서 하나씩 꺼내보기 - 순서가 없기 때문에 Set에서는 검색이 없다.
    		// 방법 1. set -> iterator화 시킨다. -> next()를 이용해서 꺼낸다.
    		Iterator<String> iter = set.iterator();
    		
    		while (iter.hasNext()) {
    			String item = iter.next();
    			System.out.print(item+" | ");
    		}
    		
    		System.out.println();
    		
    		// 방법 2. for -> 향상된 for문을 사용하면 iterator와 관련된 작업을 생략할 수 있다.
    		for (String item : set) {
    			System.out.print(item+" | ");
    		}
    	}
    }

     

    HashMap

    collection interface를 구현받지 않고 Map interface을 구현받기 때문에 조금 다른 메소드를 사용한다.

     

    package chap09.ex04.map;
    
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    public class HashMapMain {
    
    	public static void main(String[] args) {
    
    		// HashMap은 Map 인터페이스를 구현받고 있다.
    		Map<String, Integer> map = new HashMap<String, Integer>();
    
    		// 데이터 추가시 add가 아닌 put을 사용 -> collection interface를 구현받지 않기 때문에
    		map.put("kim", 63);
    		map.put("lee", 26);
    		map.put("park", 26); // 값의 중복은 허용
    		map.put("kim", 30); // 키의 중복은 허용하지 않는다. (중복 발생시 나중 것으로 덮어쓴다.)
    
    		// 크기
    		System.out.println("map : " + map.size());
    
    		// 특정 값 가져오기 : 키를 통해서 값을 찾는다.(Dictionary)
    		System.out.println("kim의 나이 : " + map.get("kim"));
    
    		// 특정 값 삭제하기 : 키를 통해서 값을 지운다. -> 어떤 값을 지웠는지 알려준다.
    		System.out.println(map.remove("kim"));
    
    		// 모든 값을 출력 1 : key를 Set으로 가져온다. -> iterator로 분리 -> key를 하나씩 가져와서 해당하는 value를
    		// 찾는다.
    		Set<String> keySet = map.keySet();
    		Iterator<String> keyIter = keySet.iterator();
    		while (keyIter.hasNext()) {
    			String key = keyIter.next();
    			System.out.print(key + " : " + map.get(key) + "\t");
    		}
    
    		System.out.println();
    
    		// 모든 값을 출력 2 : map을 entrySet으로 만든다. -> iterator로 분리(K,V) -> 키와 값을 각각 추출
    		Set<Entry<String, Integer>> entrySet = map.entrySet();
    		Iterator<Entry<String, Integer>> entry = entrySet.iterator();
    		while (entry.hasNext()) {
    			Entry<String, Integer> item = entry.next();
    			String key = item.getKey();
    			int val = item.getValue();
    			System.out.print(key + " : " + val + "\t");
    		}
    
    		System.out.println();
    
    		// 모든 값을 출력 3 : key를 Set으로 가져온다. -> key를 하나씩 가져와서 해당하는 value를 찾는다.
    		for (String key : map.keySet()) {
    			System.out.print(key + " : " + map.get(key) + "\t");
    		}
    
    		if (!map.isEmpty()) {
    			map.clear();
    		}
    	}
    
    }

     

    Entry

    Map 형태에서 키와 값 쌍으로 가져오는 형태를 엔트리라고 한다.

    entrySet()을 통해 엔트리 형태로 가져올 경우 Set타입이기 때문에 iterator를 해야 값을 가져올 수 있다.

     

    map.put(key,value) : 값을 추가한다.

    map.get(key) : 키를 통해 값을 찾는다.

    map.remove(key) : 키를 통해 값을 제거하고 값을 반환한다.

    map.entrySet() : 엔트리 형식으로 값을 가져온다.

     

    package chap09.ex04.map;
    
    import java.util.HashSet;
    import java.util.Hashtable;
    import java.util.Iterator;
    import java.util.Map.Entry;
    import java.util.Set;
    
    public class HashTableMain {
    
    	public static void main(String[] args) {
    
    		Hashtable<String, Integer> map = new Hashtable<>();
    		
    		//이름, 점수
    		map.put("홍길동1", 99);
    		map.put("홍길동2", 80);
    		map.put("홍길동3", 85);
    		map.put("홍길동4", 100);
    		map.put("홍길동5", 70);
    		map.put("홍길동6", 60);
    		map.put("홍길동7", 99);
    		map.put("홍길동8", 75);
    		map.put("홍길동9", 95);
    		map.put("홍길동10", 45);
    		
    		//홍길동4의 점수
    		System.out.println(map.get("홍길동4"));
    		
    		//홍길동4가 있는지 확인
    		System.out.println(map.containsKey("홍길동4"));
    		
    		//99점의 학생이 존재하는가?
    		System.out.println(map.containsValue(99));
    		
    		//특정 키를 가지고 해당 값을 찾는 법은 get()을 통해 가능
    		
    		//특정 값을 가지고 해당 키를 찾는 방법은?
    		//99점의 학생 이름을 찾으세요.
    		//1. 키의 값을 하나씩 뽑아서 값을 찾아 대조하는 방식
    		for (String item : map.keySet()) {
    			if(map.get(item)==99) {
    				System.out.print(item + "\t");
    			}
    		}
    
    		System.out.println();
    		
    		//2. 엔트리<키,값>를 뽑아서 값을 찾아 일치하는 값의 키를 가져오는 방식
    		Set<Entry<String, Integer>> entrySet = map.entrySet();
    		Iterator<Entry<String, Integer>> entry = entrySet.iterator();
    		while(entry.hasNext()) {
    			Entry<String, Integer> item = entry.next();
    			if(item.getValue()==99) {
    				System.out.print(item.getKey() + "\t");
    			}
    		}
    		
    	}
    
    }

     

    스택(stack)

    - LIFO(Last In First Out) 형태의 자료구조다.

    push()를 통해 값을 넣고 pop()을 통해 값을 뺀다.

    peek()을 통해 값만 확인하고 다시 넣을 수 있다.

     

    package chap09.ex05.stack;
    
    public class Towel {
    
    	private String color;
    	
    	public Towel(String color) {
    		this.color = color;
    	}
    
    	public String getColor() {
    		return color;
    	}
    
    }
    package chap09.ex05.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("navy"));
    		box.push(new Towel("purple"));
    		
    		System.out.println(box.size());
    		
    		while(!box.isEmpty()) {
    			//Towel towel = box.pop();
    			//System.out.println(towel.getColor()+"색 수건을 꺼낸다. " + box.size()+"장 남음");
    			//메소드 체이닝
    			System.out.println(box.pop().getColor()+"색 수건을 꺼낸다. " + box.size()+"장 남음");
    			//peek() : 뽑아서 확인하고 다시 넣는다.
    			//System.out.println(box.peek().getColor()+"색 수건을 꺼낸다. " + box.size()+"장 남음");
    		}
    	}
    
    }

     

    (queue)

    FIFO(First In First Out) 형태의 자료구조이다.

    자바에선 LinkedList로 구현되어 있다.

    offer()를 통해 값을 넣고 poll()을 통해 값을 뺀다.

     

    package chap09.ex06.queue;
    
    public class Job {
    
    	private String command;
    	private String to;
    	
    	public Job(String command, String to) {
    		this.command = command;
    		this.to = to;
    	}
    
    	public String getCommand() {
    		return command;
    	}
    
    	public String getTo() {
    		return to;
    	}
    
    }
    package chap09.ex06.queue;
    
    import java.util.LinkedList;
    import java.util.Queue;
    
    public class JobQueue {
    
    	public static void main(String[] args) {
    
    		Queue<Job> queue = new LinkedList<Job>();
    		
    		// 해야할 일을 큐에 넣어보자
    		queue.offer(new Job("send SMS", "Alice"));
    		queue.offer(new Job("send Mail", "Bryan"));
    		queue.offer(new Job("send SMS", "Criss"));
    		queue.offer(new Job("send Talk", "Denis"));
    		queue.offer(new Job("send SMS", "Erick"));
    		
    		try {
    			while(!queue.isEmpty()) {
    				//peek() : stack과 마찬가지로 빼서 확인 후 다시 넣는다.
    				Job job = queue.poll();
    				String command = job.getCommand();
    				String to = job.getTo();
    				System.out.println(command + " to " +to);
    				System.out.println("잔여 작업 : " + queue.size());
    			}
    		} catch (Exception e) {
    			System.out.println("객체 추출 구문을 확인해주세요.");		
    			e.printStackTrace();
    		} finally {
    			System.out.println("끝");
    		}
    		
    	}
    
    }

     

     

     

     

     

    'JAVA' 카테고리의 다른 글

    thread 2 (스레드 제어~스레드 풀)  (1) 2022.09.24
    thread - 1 (스레드 생성~join)  (1) 2022.09.24
    제너릭 (Generic)  (1) 2022.09.24
    문자열 (String)  (1) 2022.09.24
    예외 (Exception)  (0) 2022.09.24
Designed by Tistory.