ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] HashSet
    JAVA 2022. 8. 18. 12:10
    728x90
    반응형

    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);
        }
    }
    728x90
    반응형

    '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제] 콘솔 만들기 - 남궁성의 초보 코드 스터디  (1) 2022.08.12
Designed by Tistory.