전공/객체지향프로그래밍

[객체지향프로그래밍][Java] Set 심화 내용(HashSet, TreeSet)

Campus Coder 2023. 6. 1. 21:17
728x90
반응형

Set

자바 Collection의 계층 구도

 

HashSet

HashSet은 인터페이스 Set의 구현 클래스

 

Enhanced for문 사용 가능

랜덤 위치에 원소가 저장되므로 입력한 순서에 상관없이 원소가 출력됨

 

Set는 원소 중복 허용 x

 

Set 원소 중복

import java.util.*;

class Point {
    int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Point(" + x + "," + y + ")";
    }

//    @Override
//    public boolean equals(Object obj) {
//        Point p = (Point) obj;
//        if (x == p.x && y == p.y) return true;
//        else return false;
//    }
//
//    @Override
//    public int hashCode() {
//        return Objects.hash(x, y);
//    }
}

public class Main {
    public static void main(String[] args) {
        HashSet<Point> set = new HashSet<>();
        set.add(new Point(1, 2));
        set.add(new Point(1, 2));
        set.add(new Point(3, 4));
        set.add(new Point(4, 5));
        set.add(new Point(5, 6));
        System.out.println("size: " + set.size());
        for (Point p : set) System.out.println(p.toString() + '\t');
    }
}

출력 결과

size: 5
Point(4,5)
Point(1,2)
Point(3,4)
Point(5,6)
Point(1,2)

 

Set은 원소 중복 허용 x

하지만, 객체 저장 시 객체에 저장된 값이 중복되는 경우에는 원소가 저장됨

저장된 객체가 서로 다른 객체이기 때문

따라서 위 코드의 주석 부분을 해제하여 Set에서 값이 같은 원소 중복 막을 수 있음(오버라이딩)

 

만약 객체가 멤버로 다른 객체를 포함한다면, 포함하는 객체까지 오버라이딩 해줘야함

 

 

TreeSet

public class TreeSet<E> extends AbsteactSet<E> implements NavigableSet<E>, Cloneable, Serializable

참고: [자료구조] 이진 탐색 트리

TreeSet = 이진 탐색 트리 + 중복 없음

 

TreeSet가 상속받는 인터페이스 NavigableSet

메소드 기능
add 원소 추가
E first() 최솟값 리턴
E last() 최댓값 리턴
E lower(E e) 인자보다 작은 최댓값 리턴
E higher(E e) 인자보다 큰 최솟값 리턴
E floor(E e) 인자보다 작거나 같은 최댓값 수 리턴
E ceiling(E e) 인자보다 크거나 같은 최댓값 수 리턴
E poolFirst() 최솟값 리턴, 삭제
E poolLast() 최댓값 리턴, 삭제
Iterator<E> descendingIterator() 내림차순 반복자 리턴
NevigableSet<E> desendingSet() 역순 정렬된 새로운 set 리턴
NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) 범위가 formElement에서 toElement까지인 새로운 set 리턴
Inclusive가 true인 경우 범위에 Element까지를 포함

 

id로 정렬하는 경우

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

// Comparable 상속
class Student implements Comparable<Student> {
    private String name;
    private int id;

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public String toString() {
        return "Student(name=" + name + ",id=" + id + ")";
    }
    
    @Override // 오버라이딩
    public int compareTo(Student s) {
        return this.id - s.id;
    }
}

public class Main {
    public static void main(String[] args) {
        Set<Student> set = new TreeSet<>();
        set.add(new Student("박", 201701));
        set.add(new Student("김", 201702));
        set.add(new Student("이", 201703));
        for (Student s : set) System.out.println(s);
    }
}

TreeSet에 기본적으로 객체를 추가할 수 없음

따라서 오버라이딩 필요(주석 부분이 있어야 함)

 

이름으로 정렬하는 경우

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

class Student {
    private String name;
    private int id;

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Student(name=" + name + ",id=" + id + ")";
    }
}

// 이름에 대해서 비교할 수 있도록 함
class StudentComparator implements Comparator<Student> {
    public int compare(Student o1, Student o2) {
        return o1.getName().compareTo(o2.getName());
    }
}

public class Main {
    public static void main(String[] args) {
        // TreeSet 생성자에 비교기(Comparator)를 추가하여 해당 기준에 대해서 비교
        Set<Student> set = new TreeSet<>(new StudentComparator());
        set.add(new Student("박", 201701));
        set.add(new Student("김", 201702));
        set.add(new Student("이", 201703));
        for (Student s : set) System.out.println(s);
    }
}

 

 

728x90
반응형