파트4. Set(집합)

유태형·2022년 5월 11일
0

알고리즘 - Java

목록 보기
6/32

출처

해당 게시글은 [Java] 어서와! 자료구조 알고리즘은 처음이지?https://programmers.co.kr/learn/courses/13577를 간략히 요약한 게시글이며 모든 출처는 해당강의에 있습니다.




4-1

집합(Set)

배열, 리스트, 맵 등등은 추가하거나 업데이트하기 전에 개발자가 임의로 확인을 먼저 하는 형식으로 이루어져 있지만, 컬렉션에 넣을때 컬렉션 자체 적으로 확인 하기 위해서 마련된 별도의 컬렉션이 존재합니다.

이전 까지 contains(), containsKey(), containsValue()등등 메서드를 호출하여 컬렉션에 값이 이미 존재하는지 확인하는 별도의 로직을 구현해야 했었습니다. 하지만, 집합(Set)을 이용하면 데이터를 입력 하더라도 컬렉션 자체적으로 버려버림으로써 추가되지 않습니다.

컬렉션은 배열, 리스트와 마찬가지로 선형 데이터 구조를 가지고 있습니다. 값을 넣을 때 존재 하는지 여부를 확인 하기 위해선 탐색 알고리즘도 필요할 것입니다.




4-2

기존의 방식으로 데이터 추가

중복을 허용하지 않는 집합을 만들 때 기존의 방식인 리스트로 데이터를 추가해 보겠습니다.

List<Integer> list = new LinkedList<>();

if(!list.contains(1)) list.add(1);
if(!list.contains(2)) list.add(2);
if(!list.continas(3)) list.add(3);

if(!list.contains(1)) list.add(1);
if(!list.contains(2)) list.add(2);
if(!list.continas(3)) list.add(3);

System.out.println(list);

//Console
[1,2,3]

리스트.contains()로 리스트에 이미 값이 존재하고 있는지 개발자가 값을 대입하기 전 확인해야 했었습니다. 1,2,3을 각각 2번씩 대입하였으나 값이 이미 존재하는 경우엔 입력 되지 않습니다.



집합(Set) 방식으로 데이터 추가

Set을 이용하여 데이터를 추가 하겠습니다.

HashSet<Integer> list = new HashSet<>();

list.add(1);
list.add(2);
list.add(3);

list.add(1);
list.add(2);
list.add(3);

System.out.println(list);

//Console
[1,2,3]

단순히 add만으로도 중복을 알아서 걸러 줍니다.



집합(Set)의 인터페이스, 클래스

집합도 컬렉션인 만큼 다양한 인터페이스와 클래스들이 존재합니다. 그 중에서 많이 사용되는 것들은 Set, HashSet, LinkedHashSet, TreeSet등이 있습니다.

HashSet<MyData> list = new HashSet<>(); //set은 순서를 보장하지 않는다.
Set<MyData> list = new HashSet<>(); 
Set<MyData> list = new LinkedHashSet<>(); //LinkedHashSet은 순서를 보장합니다.
Set<MyData> list = new TreeSet<>();


집합(Set)의 메서드

집합.add(값) : 집합에 값이 존재하지 않을 시, 값을 추가합니다.(존재하면 버림)
집합.remove(값) : 집합에 값이 존재하면 해당 값을 집합에서 삭제합니다.
집합.size() : 현재 집합에 존재하는 요소들의 갯수를 반환합니다.
집합.contains(값) : 집합에 값이 존재하면 true, 없으면 false를 반환합니다.
집합.isEmpty() : 집합이 비어 있다면 true, 요소가 하나라도 있으면 false를 반환합니다.
집합.iterator() : 집합을 순회할 수 있는 iterator를 반환합니다.
집합A.addAll(집합B) : 집합A에 집합B의 모든 요소를 추가합니다.(A+B)
집합A.removeAll(집합B) : 집합A에 존재하는 요소들중 집합B에도 존재하는 요소들을 삭제합니다.(A-B)
집합A.retainAll(집합B) : 집합A와 집합B에 존재하는 요소들만 남깁니다.(A*B)



합집합, 차집합, 교집합

요소로 사용할 MyData 클래스 정의

class MyData{
    int v;

    public MyData(int v){
        this.v = v;
    }
    public String toString(){
        return "" + v;
    }

    @Override
    public boolean equals(Object obj) { //객체간 비교
        if(this == obj) return true; //같은 객체
        if(obj == null || getClass() != obj.getClass()) return false; //다른 클래스
        MyData myData = (MyData) obj; //타입 캐스팅
        return v == myData.v; //값 비교
    }

    @Override
    public int hashCode() {
        return Objects.hash(v); //해시 반환
    }
}

집합 A와 집합 B를 구성합니다.

Set<MyData> setA = new LinkedHashSet<>();
Set<MyData> setB = new LinkedHashSet<>();

//A
setA.add(new MyData(1));
setA.add(new MyData(2));
setA.add(new MyData(3));

//B
setB.add(new MyData(2));
setB.add(new MyData(3));
setB.add(new MyData(4));

합집합, 차집합, 교집합을 구합니다.

//A+B
setA.addAll(setB); //[1,2,3,4]
//A-B
setA.removeAll(setB); //[1]
//A*B
setA.retainAll(setB); //[2,3]




소스 코드

package Set집합;

import java.util.*;

class MyData{
    int v;

    public MyData(int v){
        this.v = v;
    }
    public String toString(){
        return "" + v;
    }

    @Override
    public boolean equals(Object obj) { //객체간 비교
        if(this == obj) return true; //같은 객체
        if(obj == null || getClass() != obj.getClass()) return false; //다른 클래스
        MyData myData = (MyData) obj; //타입 캐스팅
        return v == myData.v; //값 비교
    }

    @Override
    public int hashCode() {
        return Objects.hash(v); //해시 반환
    }
}
public class Set실습 {
    public static void main(String[] args){

//        List<Integer> list = new LinkedList<>();
//
//        if(!list.contains(1)) list.add(1);
//        if(!list.contains(2)) list.add(2);
//        if(!list.contains(3)) list.add(3);
//
//        if(!list.contains(1)) list.add(1);
//        if(!list.contains(2)) list.add(2);
//        if(!list.contains(3)) list.add(3);

//        HashSet<Integer> list = new HashSet<>();

//        list.add(1);
//        list.add(2);
//        list.add(3);
//
//        list.add(1);
//        list.add(2);
//        list.add(3);

//        HashSet<MyData> list = new HashSet<>(); //set은 순서를 보장하지 않는다.
//        Set<MyData> list = new HashSet<>();
//        Set<MyData> list = new LinkedHashSet<>();

//        list.add(new MyData(1));
//        list.add(new MyData(2));
//        list.add(new MyData(3));
//
//        list.add(new MyData(1));
//        list.add(new MyData(2));
//        list.add(new MyData(3));


        Set<MyData> setA = new LinkedHashSet<>();
        Set<MyData> setB = new LinkedHashSet<>();

        //A
        setA.add(new MyData(1));
        setA.add(new MyData(2));
        setA.add(new MyData(3));

        //B
        setB.add(new MyData(2));
        setB.add(new MyData(3));
        setB.add(new MyData(4));

//
//        //A + B
//        setA.addAll(setB);
//        //A - B
//        setA.removeAll(setB);
        //A * B
        setA.retainAll(setB);

        System.out.println(setA);
    }
}



GitHub

https://github.com/ds02168/Study_Algorithm/blob/master/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/%5BJava%5D%20%EC%96%B4%EC%84%9C%EC%99%80%20%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%80%20%EC%B2%98%EC%9D%8C%EC%9D%B4%EC%A7%80/%ED%8C%8C%ED%8A%B84.Set(%EC%A7%91%ED%95%A9)/Set%EC%8B%A4%EC%8A%B5.java

profile
오늘도 내일도 화이팅!

0개의 댓글