KH/JAVA

# 37 Set - HashSet, TreeSet

오늘의 진 2022. 7. 28. 14:20

Set

 

set : 중복허용하지 않고, 순서가 없다. 

이때 같은 1 이더라도 데이터 타입이 다르면 출력이된다. 

 

 

▶▶ HashSet

package ja_0728;
import java.util.LinkedHashSet;
import java.util.Set;

public class HashSet_1 {
	public static void main(String[] args) {

		Object[] obj = { "1", new Integer(1), "1", "4", "4", "2", "2", "3", "3", "4", "4" };

		Set sett = new LinkedHashSet();

		for (int i = 0; i < obj.length; i++) {
			sett.add(obj[i]); // 집합 sett에다가 모든 값을 담음
		}
		System.out.println(sett); // 같은 1 이더라도 데이터 타입이 다르면 출력된다.
        // [1, 1, 4, 2, 3] 출력됨
	}

}

 

 

 

Set의 합집합, 교집합, 차집합

A.retainAll( B) A에 B와 공통된 것만 남기고 나머지 다 삭제  (교집합)
A.addAll( B) A에 B의 요소들을 추가해준다. (합집합)
A. removeAll( B) A에서 B와 공통된 요소들을 모두 삭제 (차집합 A-B)
A.containsAll(B) A안에 B가 모두 포함되어있는가? 참이면 True 거짓이면 false 반환 (부분집합)

 

package ja_0728;

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

public class HashSet_2 {
	public static void main(String[] args) {

		HashSet setA = new HashSet();
		HashSet setB = new HashSet();

		HashSet setHap = new HashSet();
		HashSet setKyo = new HashSet();
		HashSet setCha = new HashSet();

		setA.add("1");
		setA.add("2");
		setA.add("3");
		setA.add("4");
		setA.add("5");

		System.out.println("A = " + setA);

		setB.add("4");
		setB.add("5");
		setB.add("6");
		setB.add("7");
		setB.add("8");
		System.out.println("B = " + setB);

		Iterator itt = setB.iterator();

		while (itt.hasNext()) {
			Object obj = itt.next();

			if (setA.contains(obj)) {
				setKyo.add(obj);
			}

		}

		itt = setA.iterator();

		while (itt.hasNext()) {
			Object obj = itt.next();
			if (!setB.contains(obj)) {
				setCha.add(obj);
			}

		}

		itt = setA.iterator();
		while (itt.hasNext()) {
			setHap.add(itt.next());
		}

		itt = setB.iterator();
		while (itt.hasNext()) {
			setHap.add(itt.next());
		}

		System.out.println("A ∩ B : " + setKyo);
		System.out.println("A ∪ B : " + setHap);
		System.out.println("A - B : " + setCha);
		System.out.println();

		System.out.println("A ∩ B : " + setA.retainAll(setB)); // 작업을 완료하면 true반환
		// 두객체의 공통적인 요소는 HashSet에 남기고 나머지는 HashSet에서 삭제
		System.out.println("A ∩ B : " + setA);
		System.out.println("A ∪ B : " + setA.addAll(setB));

		System.out.println("A - B : " + setA.removeAll(setB));
		System.out.println("A - B : " + setB);

	}

}

 

 

 

 

 

 

 

 

 

 

제너릭을 <String> 으로 한정한 경우 

package ja_0728;

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

public class HashSet_2 {
	public static void main(String[] args) {

		HashSet<String> setA = new HashSet<String>();
		HashSet<String> setB = new HashSet<String>();

		HashSet<String> setHap = new HashSet<String>();
		HashSet<String> setKyo = new HashSet<String>();
		HashSet<String> setCha = new HashSet<String>();

		setA.add("1");
		setA.add("2");
		setA.add("3");
		setA.add("4");
		setA.add("5");

		System.out.println("A = " + setA);

		setB.add("4");
		setB.add("5");
		setB.add("6");
		setB.add("7");
		setB.add("8");
		System.out.println("B = " + setB);

		Iterator<String> itt = setB.iterator();

		while (itt.hasNext()) {
			String obj = itt.next();

			if (setA.contains(obj)) {
				setKyo.add(obj);
			}

		}

		itt = setA.iterator();

		while (itt.hasNext()) {
			String obj = itt.next();
			if (!setB.contains(obj)) {
				setCha.add(obj);
			}

		}

		itt = setA.iterator();
		while (itt.hasNext()) {
			setHap.add(itt.next());
		}

		itt = setB.iterator();
		while (itt.hasNext()) {
			setHap.add(itt.next());
		}

		System.out.println("A ∩ B : " + setKyo);
		System.out.println("A ∪ B : " + setHap);
		System.out.println("A - B : " + setCha);
		System.out.println();

		System.out.println("A ∩ B : " + setA.retainAll(setB));
		// 두객체의 공통적인 요소는 HashSet에 남기고 나머지는 HashSet에서 삭제
		System.out.println("A ∩ B : " + setA);
		System.out.println("A ∪ B : " + setA.addAll(setB));

		System.out.println("A - B : " + setA.removeAll(setB));
		System.out.println("A - B : " + setB);

	}

}

 

package ja_0728;

import java.util.HashSet;

public class HashSet_3 {
	public static void main(String[] args) {

		HashSet set = new HashSet();

		set.add("abc");
		set.add("abc");

		set.add(new King("Hong", 20));
		set.add(new King("Hong", 20));

		System.out.println(set);

	}
}

class King {
	String name;
	int age;

	King(String name, int age) {
		this.name = name;
		this.age = age;

	}

	public boolean equals(Object obj) {
		if (obj instanceof King) {
			King tmp = (King) obj;
			return name.equals(tmp.name) && age == tmp.age;
		}

		return false;
	}

	public int hashCode() {
		return name.hashCode() + age;
	}

	public String toString() {
		return name + " : " + age;
	}

}

 

(로또생성기)

package ja_0728;

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

public class HashSetLotto_1 {
	public static void main(String[] args) {

		Set set = new HashSet();
		Set set2 = new HashSet();

		//생성기1
		while (true) {

			int num = (int) (Math.random() * 45 + 1); // 1-45 까지 수가 나옴 
			set.add(new Integer(num));// add해도 set이므로 중복은 허용되지 않는다 .

			if (set.size() == 6) {
				break;
			}

		}

		List list = new LinkedList(set);

		System.out.println(list);
		System.out.println(set);
		Collections.sort(list); // 오름차순 정렬 
		System.out.println(list);
		
        // 생성기2
		while (true) {
			int num = (int) (Math.random() * 45 + 1);
			set2.add(new Integer(num)); //set2에 랜덤으로 수를 하나하나 넣을건데  set이니까 중복은 알아서 걸러줌

			if (set2.size() == 7) { // 사이즈를 7로 하겠다. 
				break;
			}

		}

		List list2 = new LinkedList(set2); // set으로 출력해도 된다. 

		Iterator itt = list2.iterator();

		while (itt.hasNext()) {
			Object obj = itt.next();
			System.out.println(obj);
		}

		System.out.println();
		System.out.println("Lotto 당첨번호");

		for (int i = 0; i < list2.size() - 1; i++) {
			System.out.println(list2.get(i));

		}
		System.out.print("\n 2등 당첨번호 : ");
		System.out.println(list2.get(list2.size() - 1)); // 마지막 번호를 따로 뽑아봄 2등알려줄려구


	}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

▶▶ stack  와 Qeueu

 

stack

1. stack (스택) : 스택이란 LIFO 구조로 라스트 인 펄스트 아웃 (나중에 입력된 것이 먼저 출력) 구조입니다
 2. 자바에서는 Stack 클래스를 사용해서 객체를 생성할 수 잇습니다
3. isEmpty : 스택 구조에서 데이터가 없는 상태 인지 (텅 빈) 확인합니다
4. push : 스택 구조에서 데이터를 삽입합니다
5. peek : 스택 구조에서 제일 상단에 있는(제일 마지막으로 저장된) 요소를 반환
6. search : 전달된 객체가 존재하는 위치의 인덱스를 반환합니다 (최상단 - 맨 마지막에 저장된 데이터 위치 1부터 시작)
7. pop : 해당 스택의 제일 상단에 있는(제일 마지막으로 저장된) 요소를 반환하고, 해당 요소를 스택에서 제거
8. clear : 스택에 저장된 데이터를 초기화 (삭제) 

Qeueu

입력시 (객체명). offer( );  // 저장을 성공하면 true, 실패하면 false 반환
                              출력시 (객체명). poll( );

 

 

 

 

package ja_0728;

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

public class Stack_1 {
	public static void main(String[] args) {
		
		
		Stack stt = new Stack(); // Stack은 list인데 마지막에 들어간게 먼저 나옴
		
		//LinkedList 는 Queue 인터페이스를 구현하였다.
		Queue qq = new LinkedList();   //Queue : 먼저들어간게 먼저 나옴
		
		 //stack에 객체저장
		stt.push("1");
		stt.push("2");
		stt.push("3");
		stt.push("4");
		
		//Queue에 객체를 저장한다. 성공하면  true/실패하면 false
		qq.offer("1"); 
		qq.offer("2");
		qq.offer("3");
		qq.offer("4");
		
		//출력구문
		System.out.println("==Stack==");
		
		while(!stt.empty()) {
			System.out.println(stt.pop()); //Stack 의 맨 위에 저장된 객체를 꺼낸다. 
		}
		
		System.out.println("==Queue==");
		while(!qq.isEmpty()) {
			System.out.println(qq.poll()); // Queue에서 꺼낸다. 비어있으면 예외 발생.
		}

	}

}

[ stack ]
먼저 입력된 값이 나중에 출력되는 구조이다. stack 역시 List이다. 
입력시 (객체명). push( );
출력시 (객체명). pop( ) ;     // 맨 위에 저장된(맨마지막에저장된) 것이 출력된다.
pop은 값을 반환하고 그 값을 삭제한다. 
 (객체명).peek : 가장 나중에들어간 값 즉 가장위에 있는 값을 보여준다. 

[ Queue ]
먼저 입력된 값이 먼저 출력되는 구조이다. 
                              입력시 (객체명). offer( );  // 저장을 성공하면 true, 실패하면 false 반환
                              출력시 (객체명). poll( );
                            

 

(예) stack 이용

package ja_0728;

import java.util.Stack;

public class Stack_2 {

	// main이 static이니까 main에서 사용하기 위해서 static으로 선언해주었다.
	public static Stack back = new Stack();
	public static Stack forward = new Stack();

	public static void main(String[] args) {

		goURL("1.Google");
		goURL("2.Daum");
		goURL("3.Nate");
		goURL("4.Naver");

		printprint();

		goBack();
		System.out.println("뒤로가기 1 후 ~~");

		printprint();

		goBack();
		System.out.println("뒤로가기 2 후 ~~");

		printprint();

		goForward();
		System.out.println("앞으로 가기 후 ~~");

		printprint();

		goURL("www.korea.com");
		System.out.println("새로운 주소로 이동후 ~~");

		printprint();

	}

	private static void goForward() {
		if (!forward.empty()) {
			back.push(forward.pop());
		}
	}

	private static void goBack() {
		if (!back.empty()) {
			forward.push(back.pop()); // back의 가장위의 것(뒤의것)을 가져와서 forward에 넣기
		}
	}

	private static void printprint() {
		System.out.println("back : " + back);
		System.out.println("forward : " + forward);
		System.out.println("현재화면 : " + back.peek()); // peek : 가장위의 값을 보여줌
		System.out.println();
	}

	private static void goURL(String str) {
		back.push(str);
		if (!forward.empty()) { // forward가 비어있지 않다면 비워주어라
			forward.clear();

//			데이터를 추가하는 작업을 push라고 한다.
//			리스트에서의 add와 같은 역할이다.
//			데이터를 삭제하는 작업을 pop이라고 한다.
//			리스트에서의 remove와 같은 역할.

		}

	}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(예)Qeueu

package ja_0728;

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

public class Queue_1 {
	public static void main(String[] args) {

		int time = 10;

		Queue<Integer> qq = new LinkedList();

//		for(int i=0;i<time; i++) {
//			qq.add(i);
//		}

		for (int i = 1; i < time; i += 2) {
			qq.offer(i);
		}

		System.out.println(qq.peek() + "aaa");
		System.out.println(qq);

//		큐안에 넣을때에는 Queue명.offer(값);
//		큐에서 값을 빼낼때에는 Queue명.poll();

		while (!qq.isEmpty()) {
			System.out.println(qq.poll() + "aaa");
			System.out.println(qq);
			// System.out.println(qq.remove()+"3333");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

▶▶ TreeSet

hashset과는 달리 Treeset은 이진 탐색트리(BinarySearchTree) 구조로 이루어져 있다.

이진 탐색 트리는 추가와 삭제에는 시간이 조금더 걸리지만 정렬, 검색에 높은 성능을 보이는 자료구조이다.

그렇기에 HashSet보다 데이터의 추가와 삭제에는 시간이 더 걸리지만 검색과 정렬에는 유리하다.

TreeSet은 데이터를 저장할 시 이진탐색트리의 형태로 데이터를 저장한다.

기본은 오름차순정렬이다. 

TreeSet set = new TreeSet(Collections.reverseOrder()); 라고쓰면 내림차순 정렬을 할 수 잇다. 

 

 

 

 

 

 

set.subSet(from, to); set에서 from이상 to 미만의 순서에 속하는 값들이 출력됨
set.headSet(a) 인덱스 순서상 a뒤에 위치한 값들이 나온다. 
set.tailSet(a) 인덱스 순서상 a 앞쪽에 위치한 값들이 온다. 

 

 

package ja_0729;

import java.util.Collections;
import java.util.TreeSet;

public class TreeSet_1 {
	public static void main(String[] args) {

		TreeSet set = new TreeSet(); // 오름차순정렬
		// TreeSet set = new TreeSet(Collections.reverseOrder()); //내림차순정렬

		int[] score = { 75, 48, 66, 93, 37, 55, 10, 75, 63, 84 };

		for (int i = 0; i < score.length; i++) {
			set.add(new Integer(score[i]));
		}

		System.out.println("65보다 작은 값 : " + set.headSet(new Integer(65)));
		//headSet( )  : set에서 ()안의 값보다 앞쪽에 있는 값을 반환
		System.out.println("65보다 큰 값 : " + set.tailSet(new Integer(65)));
        ////tailSet( )  : set에서 ()안의 값보다 뒤쪽에 있는 값을 반환
	}
}

//출력구문
//65보다 작은 값 : [10, 37, 48, 55, 63]
//65보다 큰 값 : [66, 75, 84, 93]

 

(예) range 

package ja_0729;

import java.util.TreeSet;

public class TreeSet_2 {
	public static void main(String[] args) {

		TreeSet<String> set = new TreeSet<>();

		String from = "b";
		String to = "d";

		set.add("abc");
		set.add("alien");
		set.add("bat");
		set.add("car");
		set.add("Car");
		set.add("disc");
		set.add("dance");
		set.add("dZZZZ");
		set.add("elevator");
		set.add("dzzzz");
		set.add("elephant");
		set.add("korea");
		set.add("fan");
		set.add("flower");
		// set.add("d");

		System.out.println(set); // 오름차순정렬이되어서 나옴

		System.out.println("range search : from : " + from + " to " + to);
		System.out.println("result11 : " + set.subSet(from, to));
		// 순서상 b이상부터 d미만 까지만 나옴 예를들어 dance는 d보다 큼으로 포함 안됨.
		System.out.println("result22 : " + set.subSet(from, to + "zzzz"));
		// to + "zzzz" : dzzzz을 의미

	}
}


//출력
//[Car, abc, alien, bat, car, dZZZZ, dance, disc, dzzzz, elephant, elevator, fan, flower, korea]
//range search : from : b to d
//result11 : [bat, car]
//result22 : [bat, car, dZZZZ, dance, disc]

 

(예) 로또생성기

package ja_0729;

import java.util.Set;
import java.util.TreeSet;

public class TreeSetLotto {
	public static void main(String[] args) {

		Set<Integer> set = new TreeSet<>();
		Set<Integer> set2 = new TreeSet<>();

		for (int i = 0; set.size() < 6; i++) {

			int num = (int) (Math.random() * 45 + 1);
			set.add(new Integer(num));

		}

	System.out.println(set);

		for (int i = 0; set2.size() < 7; i++) {
			int num = (int) (Math.random() * 45 + 1);
			set2.add(new Integer(num));
		}

		System.out.println(set2);

	}
}