본문 바로가기

프로그래밍/Java

Java_컬렉션 프레임웍(4)_Comparator와 Comparable, HashSet

반응형

⑥ Comparator와 Comparable

: 정렬에 필요한 메서드 (정렬기준)

  • Comparable : 기본 정렬기준을 구현하는데 사용
  • Comparator : 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용
public interface Comparator {
    int compare(Object o1, Object o2);	//o1과 o2를 비교
    boolean equals(Object obj);
}

public interface Comparable {
    int compareTo(Object o);	//객체 자신(this)과 o를 비교
}

→ compare()와 compareTo()는 선언형태와 이름이 약간 다를 뿐 두 객체를 비교한다는 기능은 같다.

 

 

- Comparator와 Comparable 예제

import java.util.*;

class JavaJungsuk_CollectionFrameWork_Comparator_Comparable {
    public static void main(String[] args) {
        String[] strArr={"cat", "Dog", "lion", "tiger"};
        
        Arrays.sort(strArr);	//String의 Comparable구현에 의한 정렬
        System.out.println("strArr="+Arrays.toString(strArr));
        
        Arrays.sort(strArr, String.CASE_INSENSITIVE_ORDER);	//대소문자 구분안함
        System.out.println("strArr="+Arrays.toString(strArr));
        
        Arrays.sort(strArr, new Descending());	//역순정렬
        System.out.println("strArr="+Arrays.toString(strArr));
    }
}

class Descending implelments Comparator {
    public int compare(Object o1, Object o2) {
        if(o1 instanceof Comparable && o2 instanceof Comparable) {
            Comparable c1=(Comparable)o1;
            Comparable c2=(Comparable)o2;
            return c1.compareTo(c2)*-1;	//-1을 곱해서 기본 정렬방식의 역으로 변경
        }
        return -1;
    }
}

결과
strArr=[Dog, cat, lion, tiger]
strArr=[cat, Dog, lion, tiger]
strArr=[tiger, lion, cat, Dog]

→ Array.sort()는 배열을 정렬할 때, Comparator를 지정해주지 않으면 Comparable을 구현한 클래스의 객체에 구현된 내용에 따라 정렬된다.

→ Comparator중 CASE_INSENSITIVE_ORDER를 이용하면 대소문자 구분없이 정렬한다.

→ Comparator 인터페이스를 구현하여 -1을 곱해서 기본 정렬방식의 역으로 변경한다.

 

 

- Integer와 Comparable 예제

import java.util.*;

class JavaJungsuk_CollectionFramework_Integer_Comparable {
    public static void main(String[] args) {
        Integer[] arr={30, 50, 10, 40, 20};
        
        Arrays.sort(arr);	//Integer가 가지고 있는 기본정렬기준 compareTo()로 정렬
        System.out.println(Arrays.toString(arr));
        
        Arrays.sort(arr, new DescComp());	//DescComp에 구현된 정렬기준으로 정렬
        System.out.println(Arrays.toString(arr));
    }
}

class DescComp implements Comparator {
    public int compare(Object o1, Object o2) {
        if(!(o1 instanceof Integer && o2 instanceof Integer))
            return -1;	//Integer가 아니면 비교하지 않고 -1 반환
            
        Integer i =(Integer)o1;
        Integer i2=(Integer)o2;
        
        return i.compareTo(i2)*-1;	//기본 정렬인 compareTo()의 역순으로 정렬
    }
}

결과
[10, 20, 30, 40, 50]
[50, 40, 30, 20, 10]

→ Arrays.sort(arr);는 Integer가 가지고 있는 기본정렬기준 compareTo()로 정렬하고, 

Arrays.sort(arr, new DescComp());는 DescComp의 compare()로 정렬한다. 

 

 

 

⑦ HashSet 순서X, 중복 X

: Set인터페이스를 구현한 대표적인 컬렉션 클래스이다. LinkedHashSet사용.

생성자 또는 메서드 설명
HashSet() HashSet 객체를 생성한다.
HashSet(Collection c) 주어진 컬렉션을 포함하는 HashSet객체를 생성한다.
HashSet(int initialCapacity) 주어진 값을 초기용량으로하는 HashSet객체를 생성한다.
HashSet(int initialCapacity, float loadFactor) 초기용량과 load factor를 지정하는 생성자.
boolean add(Object o) 새로운 객체를 저장한다.
boolean addAll(Collection c) 주어진 컬렉션에 저장된 모든 객체들을 추가한다. (합집합)
void clear() 저장된 모든 객체를 삭제한다.
Object clone() HashSet을 복제해서 반환한다.
boolean contains(Object o) 지정된 객체를 포함하고 있는지 알려준다.
boolean containsAll(Collection c) 주어진 컬렉션에 저장된 모든 객체들을 포함하고 있는지 알려준다.
boolean isEmpty() HashSet이 비어있는지 알려준다.
Iterator iterator() Iterator를 반환한다.
boolean remove(Object o) 지정된 객체를 HashSet에서 삭제한다.
boolean removeAll(Collection c) 주어진 컬렉션에 저장된 모든 객체와 동일한 것들을 HashSet에서 모두 삭제한다. (차집합)
boolean retainAll(Collection c) 주어진 컬렉션에 저장된 객체와 동일한 것만 남기고 삭제한다. (교집합)
int size() 저장된 객체의 개수를 반환한다.
Object[] toArray() 저장된 객체들을 객체배열의 형태로 반환한다.
Object[] toArray(Object[] a) 저장된 객체들을 주어진 객체배열(a)에 담는다.

 

 

- HashSet 예제

import java.util.*;

class JavaJungsuk_CollectionFramework_HashSet_1 {
    public static void main(String[] args) {
        Object[] objArr={"1", new Integer(1), "2", "2", "3", "3", "4", "4", "4"};
        Set set=new HashSet();
        
        for(int i=0; i<objArr.length; i++) {
            set.add(objArr[i]);	//HashSet에 objArr의 요소 저장.
        }
        System.out.println(set);
        
        Iterator it=set.iterator();
        
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

결과
[1, 1, 2, 3, 4]
1
1
2
3
4

→ '1'이 두 번 출력되었는데, 하나는 String인스턴스이고 다른 하나는 Integer인스턴스로 서로 다른 객체이므로 중복으로 간주하지 않는다. 

→ Set은 순서를 유지하지 않기 때문에 저장한 순서와 다를 수 있다. 만일 중복을 제거하는 동시에 저장한 순서를 유지하고자 한다면 HashSet대신 LinkedHashSet을 사용해야 한다.

 

import java.util.*;

class JavaJungsuk_CollectionFramework_HashSet_2 {
    public static void main(String args[]) {
        Set set=new HashSet();
        
        for(int i=0; set.size()<6; i++) {
            int num=(int)(Math.random()*45)+1; 
            set.add(new Integer(num));
        }
      	
        List list=new LinkedList(set);
        Collections.sort(list);
        System.out.println(list);
    }
}

결과
[5, 7, 14, 33, 35, 42]

→ HashSet의 성질을 이용해서 로또번호를 만드는 예제이다. Math.random()을 사용했기 때문에 실행할 때마다 결과가 다를 것이다.

→ HashSet에 저장된 객체들을 LinkedList에 담아서 처리했다.

→ 컬렉션에 저장된 객체가 Integer이기 때문에 Integer클래스에 정의된 기본정렬이 사용되었다.

 

import java.util.*;

class JavaJungsuk_CollectionFramework_HashSet_3 {
    public static void main(String[] args) {
        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);
        
        setB.add("4"); setB.add("5"); setB.add("6");
        setB.add("7"); setB.add("8");
        System.out.println("B="+setB);
        
        Iterator it=setB.iterator();
        while(it.hasNext()) {
            Object tmp=it.next();
            if(setA.contains(tmp))
                setKyo.add(tmp);
        }
        
        it=setA.iterator();
        while(it.hasNext()) {
            Object tmp=it.next();
            if(!setB.contains(tmp))
                setCha.add(tmp);
        }
        
        it=setA.iterator();
        while(it.hasNext())
            setHab.add(it.next());
            
        it=setB.iterator();
        while(it.hasNext())
            setHab.add(it.next());
        
        System.out.pritnln("A ∩ B = "+setKyo);
        System.out.println("A ∪ B = "+setHab);
        System.out.println("A - B = "+setCha);
    }
}

결과
A=[1, 2, 3, 4, 5]
B=[4, 5, 6, 7, 8]
A ∩ B = [4, 5]
A ∪ B = [1, 2, 3, 4, 5, 6, 7, 8]
A - B = [1, 2, 3]

교집합 : setA.retainAll(setB); 

합집합 : setA.addAll(setB);

차집합 : setA.removeAll(setB);

 

반응형