본문 바로가기

국비지원

[JAVA]122206 - Set , LinkedList, Queue, LinkedHashset, TreeSet, Map

반응형

Set

List와 비슷하지만 차이점은 Set에는 중복된 값을 넣을 수 없다.

동등하게 add를 통해 원소를 추가할 수 있지만 add는 boolean값을 반환하고, 존재하는 원소와 같은 값이 들어가려하면 false를 반환한다.또한 List는 추가한 순서대로 index를 채워넣지만 Set에는 순서가 없다.

// Collection > Set > HashSet
		Set<String> set = new HashSet<>();
		set.add("둘리");
		set.add("가나다");
		set.add("도우너");
		set.add("길동");
		set.add("둘리");
		set.add("둘리");
		set.add("둘리");
		set.add("둘리");
		set.add("둘리");
		set.add("둘리");
		// set에는 동등한 원소를 넣을 수 없다.
		// 추가가 되었는지 안되었는지 알고싶다면? => 중복된 값이 아니면 ? true : false
		System.out.println(set.add("둘리"));
		
		System.out.println(set.size());
		// List는 index를 갖고 있고 추가한 순서대로 index를 채워넣음
		// 반면 Set은 순서가 없다.
//		set.get(0);
		System.out.println(set.toString());

 

순서가 없는데 어떻게 원소를 가져올 수 있나요?

1.iterator를 활용하자

2.foreach문을 활용하자

원하는 꺼낼 것이 있는지 확인 후 원하는 값을 조건문을 통해 확인 할 수 있도록 하자

Set을 활용한 합집합, 교집합, 차집합 구하는 법

합집합 : addAll 활용

출력값 : [가, 다, 나, 마, 라]

교집합 : addAll과 retainAll 활용

출력값 : [다]

차집합 : addAll과 remove 활용

출력값 : [가, 다, 나]
Set에는 순서가 없기에 원소만 같다면 같은 집합으로 본다.

집합을 오름차순으로 정렬하고 싶을 때?

// 2.집합을 오름차순으로 정렬하고 싶을 때?
		Set<Integer> lotto = new HashSet<>();
		Random random = new Random();
		while(lotto.size() < 6) {
			int number = random.nextInt(45) + 1;
			lotto.add(number);
		}
		System.out.println(lotto);
		
		// 생성자에서도 add를 할 수 있음
		List<Integer> list = new ArrayList<>(lotto);
//		for (Integer n : list) {
//			list.add(n);
//		}
		list.addAll(lotto);
		
		Collections.sort(list);
		System.out.println(list);

Set원소들을 다채웠으면 List생성자에 집합을 넣어  List로 변환 후 sort로 정렬하면 된다.

 

Hash값이란?

동일한 입력에 대한 고유한 숫자 (특정한 정보 > 숫자로) 고유한 정체성 부여를 말한다.

package prac;
import java.awt.print.Book;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class Main4 {
	public static void main(String[] args) {
		System.out.println(Objects.hash("asd", "qwer", "zxcv"));
		System.out.println(Objects.hash("asd", "qwer", "zxcv"));
		Set<Book> books = new HashSet<>();
		
		// HashSet은 hash라는 값을 먼저 비교함
		// hash값이란 ? 동일한 입력에 대한 고유한 숫자 (특정한 정보 > 숫자로) 고유한 정체성 부여
		books.add(new Book("책1", 3000));
		books.add(new Book("책2", 4000));
		books.add(new Book("책2", 4000));
		books.add(new Book("책3", 2000));
		
		System.out.println(books);
	}
}

4000원 짜리 책2 두권은 같은 해쉬값을 가지게 된다.

 

LinkedList

List와 같은 동작을 하지만 추가 삭제 작업에서 유리한 상황을 만들어준다.

추가 제거 작업이 많을 땐 고려해볼만 하지만, 그 외의 상황에서는 ArrayList가 유리하다.

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

public class Main {
	public static void main(String[] args) {
		// LinkedList 추가 삭제 작업에 있어서 상대적으로 빠르다. 속도가 유의미하게 차이가 난다.
		// 추가 제거 작업이 많을 땐 LinkedList를 활용
		// 추가 제거 외 대부분의 동작에서는 ArrayList가 빠르다.
		List<String> list = new LinkedList<>();
		list.add("가");
		list.add("가");
		list.add("다");
		list.add("라");
		
		System.out.println(list);
		
		System.out.println(list.get(0));
		System.out.println(list.get(1));
		System.out.println(list.get(2));
		System.out.println(list.get(3));
		
		list.remove(1);
		System.out.println("삭제 후 : " + list);
		
		list.add(0, "젤처음추가");
		System.out.println("추가 후 : " + list);
		
	}
}

코드상으로는 차이가 없다.

 

Queue

Queue는 줄세우기로 보면된다. 순서를 활용한 집합이 필요할 때 사용하도록 한다.

원소추가를 할 때  add, offer를 사용하면 되고, 제거할 땐 remove, poll을 활용하면 된다.

제거할 값이 없을 때 remove는 예외를 발생시키고, poll은 null값을 반환하게 된다.

또한 맨앞 원소를 건드리지 않고 확인만 하고싶을 땐 element, 맨 뒤 원소는 peek로 확인하면 된다.

package prac;
import java.util.LinkedList;
import java.util.Queue;

public class Main2 {
	public static void main(String[] args) {
		// Queue : 줄세우기
		// Deque : Queue 인터페이스의 동작을 상속받은 인터페이스 (addLast 가장 마지막에 원소 추가, removeLast 마지막 제거, getLast 마지막 살펴보는것)
		// PriorityQueue : 넣은 순서대로 줄세우는 것이 아닌 중요한 것이 앞으로 정렬되도록 (중요함의 정도는 크기로 비교)
//		Deque<String> queue = new LinkedList<>();
		Queue<String> queue = new LinkedList<>();
		queue.add("첫번째대기");
		queue.offer("두번째대기");
		queue.add("세번째대기");
		queue.offer("네번째대기");
		
		System.out.println(queue);
		// 줄제거
		String first = queue.remove();
		String second = queue.poll();
		
		System.out.println(first);
		System.out.println(second);
		
		System.out.println("현재 대기 : " + queue);
		
		// remove는 줄 것이 없다면 예외를 발생시킴
//		queue.remove();
//		queue.remove();
//		queue.remove();
		
		// poll은 줄 것이 없다면 null값을 반환함
//		queue.poll();
//		queue.poll();
//		queue.poll();
		
		System.out.println("현재 대기 : " + queue);
		System.out.println("가장 앞 녀석 : " + queue.element());
		System.out.println("가장 앞 녀석 : " + queue.peek());
		System.out.println("현재 대기 : " + queue);
		
	}
}

Deque : Queue 인터페이스의 동작을 상속받은 인터페이스 (addLast 가장 마지막에 원소 추가, removeLast 마지막 제거, getLast 마지막 살펴보는것)

addLast, removeLast, getLast 기능을 활용하고 싶다면 Deque를 사용해보자

PriorityQueue : 넣은 순서대로 줄세우는 것이 아닌 중요한 것이 앞으로 정렬되도록 한다.(중요함의 정도는 크기로 비교)

 

LinkedHashset

hashset을 상속하는 LinkedHashSet

추가한 순서를 기억한느 것이 특징이지만 인덱스를 갖고 있는 것은 아니다.

중복 제거 및 가나다라 순서대로 추가 된 모습

TreeSet

원소를 집어넣어주면 크기순으로 정렬해준다.

그 외 자료형도 Comparator정의만 된다면 정렬 된다.

 

List  index활용 및 중복허용
ArrayList 일반적인 상황에서 사용
LinkedList 자료의 추가 삭제가 많이 일어날 때 활용
HashSet 중복 활용 (순서가 없음)
LinkedHashSet 추가한 순서대로 기억해주는 용도
TreeSet 자료의 정렬이 필요할 때 활용

 

Map

Map은 dictinary 사전의 단어와 뜻을 연결해놓은 것 처럼 key와 value가 한 쌍인 자료의 집합이다.

짝을 이루는 자료를 여러개로 관리해주며, key는 중복되면 안되고, 간단하면 간단할수록 좋다.

*맵에서 자료 꺼내는 법

get메소드 파라미터에 key값을 입력해야 해당 자료를 확인할 수 있다.

containsKey는 27이라는 값이 있는가?를 묻는 것이다.

주의 할 점은 put에 기존 키 값과 다른 value값을 넣으면 가장 최근에 선언된 value값으로 덮어씌워버리니 주의하자

// 맵에서 자료 꺼내는 법
		System.out.println(player.get(5));
		System.out.println(player.get(1));
		System.out.println(player.get(27));
		System.out.println(player.containsKey(27));

*2차원 맵

배열과 같이 2차원 맵또는 2차원 리스트도 만들 수 있다.

public class Main4 {
	public static void main(String[] args) {
		Map<String, Integer> map;
	
		Map<String, List<Integer>> map2;
		Map<String, Set<Integer>> map3;
		Map<String, Map<Integer, Integer>> map4;
		
		// 2차원 리스트
		List<List<Integer>> list2D;
	}
}

entrySet

<Integer, String>을 담고있는 <Entry>로 보면된다.

entry에는 Key, value 모두 존재하기에 접근이 가능하다.

LinkedHashMap

HashMap에도 LinkedHashMap이 존재한다.

HashMap에는  put을 통해 데이터나 객체를 넣을때 key의 순서가 지켜지지 않는다는 것이 단점인데,

LinkedHashMap을 활용하면 put을 통해 입력받은 순서를 기억해준다.

반응형