Java TreeSet 이진 트리 구조





결과

결과






코드

package pk;

import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeSet;

public class Test {

	public static void main(String[] args) {
		TreeSet<Integer> ts = new TreeSet<Integer>();
		
		ts.add(8); ts.add(8); ts.add(3);
		ts.add(6); ts.add(7); ts.add(2);
		ts.add(9); ts.add(1); ts.add(5);
		
		// 이진 트리 : 부모보다 작은것은 왼쪽, 큰 것은 오른쪽에 저장 
		System.out.println("가장 작음 : " + ts.first());	// 가장 왼쪽
		System.out.println("가장 큼 : " + ts.last());	// 가장 오른쪽
		System.out.println("10이하 가장 가까움 : " + ts.floor(10));	// 미만은 lower 메소드
		System.out.println("10이상 가장 가까움 : " + ts.ceiling(10)); // 초과는 higher 메소드
		
		System.out.println("가장 작은 값 삭제 : " + ts.pollFirst());
		System.out.println("가장 큰 값 삭제 : " + ts.pollLast());
		
		
		Iterator<Integer> it = ts.iterator();
		System.out.print("\n오름차순 정렬 : ");
		while(it.hasNext()) System.out.print(it.next() + " ");
		
		it = ts.descendingIterator();
		System.out.print("\n내림차순 정렬 : ");
		while(it.hasNext()) System.out.print(it.next() + " ");
		
		
		System.out.print("\n\n=== 특정 범위 값들 가져오기 ===");
		NavigableSet<Integer> nav = ts.headSet(5, true); // true : 이하, false : 미만
		it = nav.iterator();
		System.out.print("\n5 이하 값들 : ");
		while(it.hasNext()) System.out.print(it.next() + " ");
		
		
		nav = ts.tailSet(5, false); // true : 이상, false : 초과
		it = nav.iterator();
		System.out.print("\n5 초과 값들 : ");
		while(it.hasNext()) System.out.print(it.next() + " ");
		
		
		nav = ts.subSet(3, true, 7, true); // true : 범위값도 포함, false = 미포함
		it = nav.iterator();
		System.out.print("\n3이상 7이하 값들 : ");
		while(it.hasNext()) System.out.print(it.next() + " ");
	}

}




TreeSet : 이진 트리 구조를 갖는다.

(부모 노드보다 작으면 왼쪽, 크면 오른쪽 자식 노드의 위치)


ㄴ 따라서 [왼쪽 자식 노드 -> 부모 노드 -> 오른쪽 자식 노드 ] 순으로 값을 읽기만 하여도 오름차순으로 정렬된 값들을 얻어올 수 있게 된다.

이와 같은 구조 때문에 검색을 빠르게 할 수 있다.


ㄴ TreeSet은 Set이 들어가 있어 알수 있듯이 이진 트리 구조의 Set 컬렉션으로 중복된 값을 가질 수 없다.





메소드



삽입, 삭제 등 : Set 컬렉션으로 동일한 메소드를 사용한다.

링크

[JAVA/심화] - Java HashSet - 집합 삽입, 삭제, 탐색





E first() : 가장 작은 값

- 가장 작은 값, 즉 이진트리에서 가장 왼쪽의 값이다.





E last() : 가장 큰 값

- 가장 큰 값, 즉 이진트리에서 가장 오른쪽 값이다.





E floor(E e) : 인수보다 이하의 객체(값)

- 인수의 해당하는 값이 없다면 그보다 이하의 값들 중 가장 가까운 값을 리턴한다.


- 미만의 값을 구하고자 한다면 lower() 메소드를 사용하면 된다.





E ceiling(E e) : 인수보다 이상의 객체(값)

- 인수의 해당하는 값이 없다면 그보다 이상의 값들 중 가장 가까운 값을 리턴한다.


- 단, 존재하지 않을 경우 null을 리턴한다.


- 초과의 값을 구하고자 한다면 higher() 메소드를 사용하면 된다.





E pollFirst() / E pollLast = First 값 제거 / Last 값 제거

- 해당하는 값을 리턴해준 후 제거한다.






정렬



- 오름차순 : 이진 트리 구조상 이미 정렬이 되어져 있으므로 iterator() 메소드로 가져오면 오름차순으로 정렬되어 있다.




- 내림차순 : descendingIterator() 메소드를 사용하여서 Iterator<E>의 가져오면 내림차순으로 정렬된다.





범위 검색



NavigableSet<E> headSet(E e, boolean b) : 인수 값보다 작은 값들 검색

- 위 예시에서는 5를 주어서 5이하의 값들을 검색하였다.


- 2번 째 인자인 b가 

true일 경우 e 이하를 검

false일 경우 e 미만을 검색

한다.





NavigableSet<E> tailSet(E e, boolean b) : 인수 값보다 큰 값들 검색

- 위 예시에서는 5와, false를 주어서 5를 초과하는 값들을 검색하였다.


- 2번 째 인자인 b가 

true일 경우 e 이상을 검색

false일 경우 e 초과를 검색

한다.





NavigableSet<E> subSet(E start, boolean b, E end, boolean b2) 

- 시작 값과 끝 값을 인수로 주어 그 사이 범위의 값들을 리턴한다.


- 2, 4번 째 인자는 동일하게 true면 해당값도 포함이며 false면 미포함이다.









Java Set , ArrayList 내림차순 오름차순 정렬






결과

결과






코드

package pk;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class Test {

	public static void main(String[] args) {
		Set<String> s = new HashSet<>() ;
		s.add("abc"); s.add("54c"); s.add("zsd");
		s.add("yx3"); s.add("abcd"); s.add("fds");
		s.add("543"); s.add("a1c"); s.add("bdef");
		
		Iterator<String> it = s.iterator();
		System.out.print("기존 데이터 : ");
		while(it.hasNext()) {
			System.out.print(it.next() + " ");
		}
		
		
		List<String> list = new ArrayList<>(s);
		
		Collections.sort(list);
		System.out.print("\n오름차순 : ");
		for(String a : list) System.out.print(a + " ");
		
		System.out.print("\n내림차순 : ");
		Collections.sort(list, Collections.reverseOrder());
		for(String a : list) System.out.print(a + " ");
	}

}




- 기존 데이터를 보면 Set은 삽입 순서나 글자 순서같은 것과 무관하게 출력하는 것을 볼 수 있다.




- Set의 있는 데이터들을 정렬하기 위해서는 우선 Set -> List 변환하여야 한다.




- 변환한 후 Collections.sort() 를 사용하여서 정렬을 할 수 있다.


ㄴ 첫번째 인수 : 정렬 하고자하는 List

ㄴ 두번째 인수 : Collections.reverseOrder()을 줌으로써 내림차순으로 정렬할 수 있다.

( 생략 시 기본적으로 오름차순으로 정렬한다. )



해당 방법은 List를 정렬하는 방법이므로 ArrayList도 같은 방법으로 정렬을 할 수 있다.








Java Key, Value - HashMap, Hashtable






결과

결과







코드

package pk;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Test {

	public static void main(String[] args) {
		Map<Integer, String> m = new HashMap<>();
		
		m.put(5, "E");	
		m.put(3, "C");	
		m.put(1, "A");	
		m.put(2, "B");	
		m.put(1, "X");	// 동일한 키 존재 시 해당 값 변경
		
		System.out.println("Key 4 존재 ? " + m.containsKey(4) );
		System.out.println("Value C 존재 ? " + m.containsValue("C") );
		System.out.println();
		
		System.out.println("Key 3의 Value : " + m.get(3));
		System.out.println("Key 4의 Value : " + m.get(4));	// 해당 키가 없다면 null 리턴
		System.out.println("길이 : " + m.size());
		
		m.remove(3);	// 삭제
		
		System.out.println();
		// Key
		Iterator<Integer> it = m.keySet().iterator();	// 모든 키를 Set의 넣어 리턴 + iterator
		while(it.hasNext()) {
			System.out.print(it.next() + " ");
		}
		
		System.out.println();
		// Value
		Iterator<String> it2 = m.values().iterator();	// 모든 값을 Collection에 넣어 리턴 + iterator
		while(it2.hasNext()) {
			System.out.print(it2.next() + " ");
		}
	}

}




HashMap : <Key, Value> 쌍의 값을 저장하는 구조이다.

값은 중복될 수도 있지만, 키는 중복 저장이 불가능하다.

만약 기존의 존재하는 키로 추가하였을 때는 해당 키의 값이 변경된다.



HashTable : HashMap과 동일한 구조, 사용방법을 갖는다.

단, HashTable은 스레드의 안전(Thread Safe) 하다.








put(K k, V v) : 추가

- 기존의 존재하는 키를 추가하였을 시 값이 변경된다.





V remove(K k) : 삭제

- 인수로 준 키의 해당하는 쌍을 삭제한다.


- 존재하지 않을 경우 null을 리턴한다.





boolean containsKey(K k) : 키 존재 여부

- 해당 키가 존재하는지 확인한다.





boolean containsValue(V v) : 값 존재 여부

- 해당 값이 존재하는지 확인한다.





V get(K k) : 값 얻기

- 인수로 준 키의 해당하는 값을 리턴한다.


- 존재하지 않는 키일 경우 null을 리턴한다.




int size() : 길이(개수) 리턴




Set<K k> keySet() : 키 Set 리턴





Collection<V v> values() : 값 Collection 리턴










Java Queue(큐) 컬렉션 사용





결과

결과





코드

package pk;

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

public class Test {

	public static void main(String[] args) {
		Queue<String> ss = new LinkedList<>();
		
		// ss.add() = ss.offer() 삽입
		// ss.remove() = ss.poll() 삭제
		// ss.element() = ss.peek() 맨앞
		
		System.out.println(ss.offer("가") );
		ss.offer("나");
		ss.offer("다");
		ss.offer("가");
		ss.offer("라");
		
		System.out.println("현재 맨앞 : " + ss.peek());
		System.out.println("'다' 포함 여부 : " + ss.contains("다"));
		

		while(!ss.isEmpty()) {
			System.out.print(ss.poll() + " ");
		}
		
	}

}





Queue(큐) : 선입선출의 구조로서 먼저 들어온 객체가 가장 먼저 나가는 자료구조 이다.

Queue 인터페이스로 구현된 클래스 중 하나가 LinkedList 이며 이를 형변환하여 사용한다.





boolena offer() & add() : 삽입

- 객체를 삽입한다.






E poll() & remove() : 삭제

- 맨앞의 객체를 삭제한며 리턴해준다.


- 큐가 비어있을 경우 poll()을 사용하여 삭제를 시도하면 null을 리턴하지만 

remove() 사용하면 Exception을 발생시켜 종료한다.





E peek() & element() : 맨앞 가져오기

- 맨앞의 객체를 리턴해준다.


- 큐가 비어있을 경우 peek()를 사용한다면 null을 리턴해주지만 

element() 사용한다면 Exception을 발생시켜 종료한다.





boolean contains(E e) : 객체 찾기


- 인수로 준 객체가 존재한다면 true 아니면 false를 리턴한다.






Java Stack(스택) 컬렉션 사용





결과

결과





코드

package pk;

import java.util.Stack;

public class Test {

	public static void main(String[] args) {
		Stack<String> ss = new Stack<>();
		
		ss.push("가");
		ss.push("나");
		ss.push("다");
		ss.push("가");
		ss.push("라");
		
		System.out.println("현재 맨위 : " + ss.peek());
		System.out.println("'가' 순서 : " + ss.search("가"));
		System.out.println("'라' 순서 : " + ss.search("라"));
		
		while(!ss.empty() ) {
			System.out.print(ss.pop() + " ");
		}
		
	}

}




Stack : 후입선출의 구조로서 나중에 들어온 값이 가장 먼저 나가는 자료구조이다.





E push(E e) : 객체 삽입

- 인수로 준 객체를 스택의 삽입한다.


- 리턴형은 E로 삽입한 객체를 리턴한다.





E peek() : 객체를 가져옴

- 스택에서 객체를 갖고온다.

후입선출의 구조이므로 가장 위에 있는 값, 즉 가장 마지막으로 들어온 값을 리턴한다.


- pop과는 다르게 꼭대기 값을 가져오기만 한다.





E pop() : 객체를 삭제

- 가장 꼭대기의 객체를 삭제한다.


- 리턴형은 E로서 삭제한 객체를 리턴한다.


ㄴ 객체를 가져옴 = peek()

ㄴ 객체를 가져옴 + 삭제 = pop()





int serach(E e) : 객체를 찾음

- 꼭대기부터 인수로 준 객체를 스택에서 찾는다.


- 찾는 다면 해당 객체의 순서를 리턴한다.

여기서 순서란 꼭대기(=1) 부터 아래로 내려갈수록 1씩 증가한다.


즉, 스택의 들어온 역순이며 해당 객체와 동일한 객체가 다수 존재하면 꼭대기와 가장 가까운 객체의 순서를 리턴한다.


만약 객체가 없을경우 -1을 리턴한다.









Java HashSet 합집합, 차집합, 교집합, 부분집합





코드

package pk;

import java.util.HashSet;

public class Test {

	public static void main(String[] args) {
		HashSet<Integer> ss = new HashSet();	// 1 2 3 4
		HashSet<Integer> ss2 = new HashSet();	// 3 4 5 6
		HashSet<Integer> ss3 = new HashSet();	// 1 2
		
		ss.add(1);
		ss.add(2);
		ss.add(3);
		ss.add(4);
		
		ss2.add(3);
		ss2.add(4);
		ss2.add(5);
		ss2.add(6);
		
		ss3.add(1);
		ss3.add(2);
		
		/*
		ss.addAll(ss2);	// (1 2 3 4) ∪ (3 4 5 6) = (1 2 3 4 5 6) 합집합
		for(int n : ss) System.out.print(n + " ");
		System.out.println();
		*/
		
		/*
		ss.retainAll(ss2);	// (1 2 3 4) ∩ (3 4 5 6) = (3 4) 교집합
		for(int n : ss) System.out.print(n + " ");
		System.out.println();
		*/
		
		/*
		ss.removeAll(ss2);	// (1 2 3 4) - (3 4 5 6) = (1 2) 차집합
		for(int n : ss) System.out.print(n + " ");
		System.out.println();
		*/
		
		/*
		System.out.println(ss.containsAll(ss2));	// (1 2 3 4) ≠ (3 4 5 6)
		System.out.println(ss.containsAll(ss3));	// (1 2 3 4) ⊃ (1 2)
		*/
	}

}





HashSet 기본 사용법


링크

[JAVA/심화] - Java HashSet - 집합 삽입, 삭제, 탐색







addAll() : 합집합

합집합

- 두 집합의 원소들을 합한 집합을 만든다.

집합이므로 중복된 원소는 1개만 포함된다.





retainAll() : 교집합

교집합

- 두 집합에서 동일하게 포함하고 있는 원소만 있는 집합을 만든다.





removeAll() : 차집합

차집합

- 인수로 주는 집합의 포함된 동일한 원소들을 제거한다.




containsAll() : 집합 포함 여부(부분 집합)

부분 집합

- 인수로 주는 집합이 부분 집합이면 true이다.


- 해당 코드는 위쪽은 false가 아래는 true가 도출된다.


※ contains와 혼동하면 안된다.







Java HashSet - 집합 삽입, 삭제, 탐색





결과

결과





코드

package pk;

import java.util.HashSet;
import java.util.Iterator;

public class Test {

	public static void main(String[] args) {
		HashSet<String> ss = new HashSet<String>();
		
		ss.add("가");
		ss.add("나");
		ss.add("다");
		ss.add("라");
		ss.add("가");
		
		for(String s : ss) {
			System.out.print(s + " ");
			if(s.equals("라")) ss.remove(s);
		}
		
		System.out.println();
		Iterator<String> it = ss.iterator();
		while(it.hasNext()) {
			String s = it.next();
			System.out.print(s + " ");
			if(s.equals("다")) it.remove();
		}
		
		System.out.println();
		for(String s : ss) {
			System.out.print(s + " ");
		}
		System.out.println();
		System.out.println("길이 : " + ss.size());
		System.out.println("'가' 포함 여부 : " + ss.contains("가"));
		
	}

}




HashSet : 저장 순서가 유지되지 않으며 동일한 값을 1개만 저장할 수 있다.

중복이 없고, 순서가 없으므로 집합으로 볼 수 있다.

ex) 결과 1라인을 보면 중복이 허용안되며 순서도 무작위인걸 확인 가능하다.





boolean add(E e) : 원소 추가

- 리턴형이 boolean형으로 저장이 완료되면 true를, 중복된 원소라 저장이 실패한다면 false를 리턴한다.




boolean remove(Object o) : 원소 제거

- 성공적으로 제거하면 true를 실패하면 false를 리턴한다.




isEmpty() : 비었는지 검사




size() : 개수를 구함




boolean contains(Object o) : 포함 여부 확인

- 인수로 준 객체가 존재하는지 검사한다.




iterator() : iterator 객체를 얻음




탐색

1. for each문을 사용


2. Iterator를 사용

ㄴ boolean hasNext() : 가져올 객체가 있는지 없는지 검사한다.

ㄴ E next() : 한칸 다음으로 이동 후 그 객체 값을 리턴한다.


ex) 0 "가" "나 "다" "라"

이러한 set이 있다면 처음 next()를 실행하였을 경우 0에서 "가" 로 이동한 후 "가"를 리턴하게 된다.






+) 추가


- HashSet은 객체를 비교할 시 hashCode()와 equals() 메소드들을 재정의하여 조건을 지정해 주어야 한다.



링크

[JAVA/심화] - Java HashSet 합집합, 차집합, 교집합, 부분집합






Java List Collection - ArrayList, LinkedList, Vector



예시 리스트



1. ArrayList : 가변적인 크기의 배열

- 동작 방식(삽입)

AL1

AL2

ex) 2번 자리의 추가

2번 자리의 추가를 한다면 맨 뒤 빈자리가 추가된다.

이후 2~4번의 앉아있던 사람이 한칸씩 뒤로 이동한다.

그리고 이동 후 빈자리의 새 값이 들어간다.


=> 삭제도 마찬가지의 과정을 거친다.



※ 따라서 ArrayList는 검색 속도는 빠르지만, 중간 삽입/삭제가 많다면 아주 비효율적이다.





2. LinkedList : ArrayList와 사용 방법 등 똑같지만 내부 동작 구조가 다르다.

- 동작 방식(삽입)

LL1

LL2

ex) 2번 자리에 추가

LinkedList는 내부 객체들끼리 링크로 연결되어 있다.

따라서 ArrayList처럼 자리이동 없이 이 링크만 끊어준 후 다른곳으로 연결만 해주면 된다.



※ 이처럼 ArrayList와 달리 중간에 삽입/삭제가 발생하여도 빠르게 할 수 있다. 하지만 링크를 타고 움직이므로 탐색은 느리다.




3. Vector : ArrayList와 사용 방법 등 똑같지만 스레드의 안전(Thread-Safe) 하다.








결과

결과





코드

package pk;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Vector;

public class Test {

	public static void main(String[] args) {
		ArrayList<String> al = new ArrayList<>();
		Vector<String> v = new Vector<>();
		LinkedList<String> ll = new LinkedList<String>();
		
		System.out.println("- 객체 삽입 -");
		al.add("a");	// a
		al.add("c");	// a c
		al.add("b");	// a c b
		al.add("a");	// a c b a
		al.add(2, "x");	// a c x b a
		
		al.set(1, "y");	//  a y x b a
		System.out.print("값 확인 : ");
		for(String s : al) System.out.print(s + ", ");
		System.out.println("\n");
		
		
		System.out.println("- 객체 검색 -");
		if( !al.isEmpty() ) System.out.println("리스트가 비어있지 않습니다.");
		System.out.println("개수 : " + al.size());
		if( al.contains("a") ) System.out.println( "a가 있습니다." );
		System.out.println("index 2의 객체 : " + al.get(2) + "\n");
		
		
		System.out.println("- 객체 삭제 -");
		System.out.print("index 2 삭제 : ");		
		al.remove(2);	//  a y b a
		for(String s : al) System.out.print(s + ", ");
		System.out.print("\na 찾아서 삭제 : ");
		al.remove("a");	//  y b a
		for(String s : al) System.out.print(s + ", ");
		System.out.print("\n 리스트 비우기 : ");
		al.clear();
		if( al.isEmpty() ) System.out.println("리스트가 비었습니다.");
	}

}



List Collection 메소드들



boolean add(E e) : 맨 뒤에 객체 추가


void add(int index, E e) : 해당 인덱스의 객체 추가


E set(int index, E e) : 해당 인덱스 객체값 수정





boolean contain(Object o) : 해당 객체가 포함되어 있는지 여부


int size() : 저장된 객체 개수 리턴


E get(int index) : 해당 인덱스 값 가져오기


boolean isEmpty() : 비어있는지 검사




E remove(int index) : 해당 인덱스 객체 제거


boolean remove(Object o) : 인자로 받은 객체 제거 (앞에서부터 하나만)


void clear() : 리스트를 비움






+ Recent posts