오늘의하루

[JAVA] HashSet 본문

JAVA

[JAVA] HashSet

오늘의하루_master 2022. 8. 18. 12:10

HashSet은 Set인터페이스를 구현한 대표 클래스이며 순서를 유지하지 않는 데이터의 집합이고 데이터의 중복을 허용하지 않는다.

  • 순서를 유지하고 싶다면 LinkedHashSet을 사용하면 된다.

HashSet의 주요 Method

생성자

  • HashSet() : 기본 생성자
  • HashSet(Collection c) : Collection(c)을 저장하는 생성자
  • HashSet(int initialCapacity) : 초기 용량(initialCapacity) 설정 생성자
    • 용량이 모자라면 내부적으로 초기 용량의 x2만큼 늘린다.
  • HashSet(int initialCapacity, float loadFactor) : 용량을 x2 하는 시점(loadFactor)을 지정해준다.
    • 예: loadFactor가 0.8일 경우 용량이 80% 찼을 때 미리 용량을 x 2해 달라는 이야기다.

추가

Set안에 같은 객체가 없다면 추가(저장), 이미 객체가 있다면 무시(저장 x)된다.

  • boolean add(Object o)
    • add(Object o)를 호출하면 자동적으로 equals()와 hashCode()를 호출한다.
      • equals()와 hashCode()가 오버 라이딩되어 있어야 한다.
class HashPerson{
    String name;
    int age;
    
    HashPerson(String name, int age){
        this.name = name;
        this.age = age;
    }
    
    public String toString(){
        return name + ":" + age;
    }
    // 여기까지만 작성하고 Set에서 add를 하면 논리적 에러가 발생한다
    // equals를 그냥 두게되면 주소를 비교하기 때문이다. (값을 비교하게 만들어줘야 한다.)
    
    public boolean equals(Object o){
        if(!(o instanceof HashPerson)){
            return false;
        }
        HashPerson tmp = (HashPerson)o;
        return this.name.equals(tmp.name) && this.age == tmp.age;
        // equals를 오버라이딩해서 값을 비교하게 만들어준다.
    }
    
    public int hashCode(){
        return (name+age).hashCode(); // String 메서드인 hashCode()를 사용
        // return Objects.hash(name,age); >> 요즘 방법
    }
}
  • boolean addAll(Collection c) : 합집합

삭제

  • boolean remove(Object o)
  • boolean removeAll(Collection c) : 교집합
  • boolean retainAll(Collection c) : 조건부 삭제(차집합 : Collection(c)를 제외한 나머지를 삭제한다.) 
  • void clear() : 모두 삭제

검색

  • boolean contains(Object o) : Set이 지정된 객체(o)를 포함하고 있는지 확인 (포함 : true)
  • boolean containsAll(Collection c) : Set에 collection(여러 객체)가 포함되어 있는지 확인 (포함 : true)

그 외

  • Iterator iterator()
  • boolean isEmpty() : 비어있는지 확인
  • int size() : 저장된 객체의 수를 반환
  • Object [] toArray() : Set에 저장된 객체를 배열로 반환
  • Object [] toArray(Object [] a) : Set에 저장된 객체를 배열로 반환

예제로 공부하기

import java.util.*;
public class MyClass {
    public static void main(String args[]) {
      Object[] objArr = {"1", "2", "2", "3", "3", "4", "4", "4"};
      Set set = new HashSet();
      for(int i = 0; i < objArr.length; i++){
          set.add(objArr[i]);
      }
      System.out.println("add 해준거");
      System.out.println(set);
      System.out.println();
      
      Iterator it = set.iterator();
      System.out.println("iterator로 만드거");
      while(it.hasNext()){
          System.out.println(it.next());
      }
      
      Set set2 = new HashSet();
      for (int i = 0; set2.size() < 6; i++){
          int num = (int)(Math.random() * 45) + 1; // 1 ~ 45
          set2.add(new Integer(num));
      }
      List list = new LinkedList(set2); // LinkedList(Collection c)
      Collections.sort(list);
      System.out.println(list);
      System.out.println();
      
      Set set3 = new HashSet();
      set3.add("abc");
      set3.add("abc");
      // add에 지정된 Object가 String이기 때문에 equals()를 오버라이딩 안해줘도 값을 비교한다.
      System.out.println(set3);  // [abc]
      System.out.println();
      
      set3.add(new HashPerson1("story", 20));
      set3.add(new HashPerson1("story", 20)); // equals()를 오버라이딩하지 않아서 주소를 비교하게되서 저장된다.
      System.out.println(set3); // [abc, HashPerson1@6f2b958e, HashPerson1@3d012ddd]
      System.out.println();
      
      set3.add(new HashPerson2("nike",30)); 
      set3.add(new HashPerson2("nike",30)); // equals()를 오버라이딩하여 중복되는 값은 저장되지 않는다.
      System.out.println(set3); // [abc, HashPerson1@6f2b958e, HashPerson1@3d012ddd, HashPerson2@63f762a]
      System.out.println();
      
      HashSet setA = new HashSet();
      HashSet setB = new HashSet();
      HashSet setHab = 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); // [1,2,3,4,5] >> 순서 보장안된다.
      
      setB.add("4"); setB.add("2"); setB.add("3"); setB.add("7"); setB.add("8");
      System.out.println("B = " + setB); // [4,2,3,7,8] >> 순서 보장안된다.
      
      // 교집합 만들기
      Iterator it2 = setB.iterator();
      while(it2.hasNext()){
          Object tmp = it2.next();
          if(setA.contains(tmp)){ // setA에 tmp가 포함되어있는지 확인
              setKyo.add(tmp);
          }
      }
      System.out.println("Kyo = " + setKyo); // [2,3,4]
      
      setA.retainAll(setB);
      System.out.println("차집합 간소화 = " + setA); // [2,3,4]
      // setA가 변경된다.
      setA.addAll(setB);
      System.out.println("합집합 = " + setA); // [2,3,4,7,8]
      // setA가 변경된다.
      setA.removeAll(setB);
      System.out.println("setA에서 setB를 제거한 결과 = " + setA); // []
      // setA가 변경된다.
      
      setA.add("1"); setA.add("2"); setA.add("3"); setA.add("4"); setA.add("5");
      it2 = setA.iterator();
      while(it2.hasNext()){
          Object tmp2 =it2.next();
          if(!setB.contains(tmp2)){ // setB에 tmp2가 포함되지 않는걸 찾는다.
              setCha.add(tmp2);
          }
      }
      System.out.println("setCha 교집합 = " + setCha); // [1,5]
      
      Iterator it3 = setB.iterator();
      while(it3.hasNext()){
          setHab.add(it3.next());
      }
      it3 = setA.iterator();
      while(it3.hasNext()){
          setHab.add(it3.next());
      }
      System.out.println("setHab 합집합 = " + setHab); // [1,2,3,4,5,7,8]
      
    }
}

class HashPerson1{ // equals()를 오버라이딩 해주지 않았다.
    String name;
    int age;
    
    HashPerson1(String name, int age){
        this.name = name;
        this.age = age;
    }
}

class HashPerson2{ // equals()와 hashCode()를 오버라이딩 해줬다.
    String name;
    int age;
    
    HashPerson2(String name, int age){
        this.name = name;
        this.age = age;
    }
    public boolean equals(Object o){
        if(!(o instanceof HashPerson2)){
            return false;
        }
        HashPerson2 tmp = (HashPerson2)o;
        return this.name.equals(tmp.name) && this.age == tmp.age;
    }
    public int hashCode(){
        return Objects.hash(name,age);
    }
}

'JAVA' 카테고리의 다른 글

[JAVA] Map 관련 내용  (0) 2022.08.19
[JAVA] TreeSet  (0) 2022.08.19
[JAVA] Iterator Method 관련 내용  (0) 2022.08.18
[JAVA] Collection Framework 정리  (0) 2022.08.17
[Java1000제] 콘솔 만들기 - 남궁성의 초보 코드 스터디  (0) 2022.08.12
Comments