새소식

Java

[JAVA] Comparable? Comparator?

  • -

 

서론

객체 간의 sort를 수행하던 중 Comparable이라고 하는 것과 Comparator라고 하는 것이 존재해 둘 중 어떤 걸 어느 상황에 써야 하나..라는 생각으로 작성했다.

 

 

공통점

- 모두 인터페이스다.

- 원하는 객체에 추가하고, 각각 요구로 하는 메서드(비교 메서드)를 구현해주면 된다.

 

 

Comparable

- compareTo(T o) return: int

- 자기 자신과 매개변수 객체를 비교한다.

- 자기 자신을 기준으로 내가 더 크면 양수, 상대가 더 크면 음수를 반환하여 사용한다.

- 문자열의 경우 좀 다른데, 기준값에 비교대상이 포함되어 있다면, 서로의 문자열 길이의 차이값을 리턴한다.

- 뭔소리냐하면 예시를 보자

String str = "abcd";

System.out.println(str.compareTo("abcd")); // 같기 때문에 0이 나온다.
System.out.println(str.compareTo("ab")); // abcd안에 ab가 포함되어 있기 때문에 두 문자열의 차이인 2
System.out.println(str.compareTo("a")); // 같은 이유로 1
System.out.println(str.compareTo("c")); //이 친구는 -2가 나온다.
// 같은 위치의 문자만 비교하기 때문에, 첫번째 문자를 비교해 다르면 아스키값을 기준으로 비교한다.

 

 

Comparator

- compare(T o1, T o2) 

- 두 매개변수 객체를 비교한다

- compare를 오버라이딩할 객체가 별도로 존재해야 한다.

하지만 Comparator를 정말 비교용으로만 사용하기 위해 굳이 객체를 선언하기엔 아까운 사람들을 위해

익명 객체를 생성하여 사용하는 방법이 생겼다.

 

 

 

익명 객체

- 말 그대로 이름이 정의되지 않은 객체다.

- 주로 특정 구현 부분만 사용하거나, 중간에 수정된 코드를 잠깐 이용할 때 사용된다.

public static void main(String[] args) {
	
		Person a = new Person();
		
		// 익명 객체 선언!!
		Person b = new Person() {
		    	int age;
			@Override
			int get() {
				return age;
			}
		};
        
        System.out.println(a.get());
        System.out.println(b.get());
}


//////

class Person{
    String name;
    int height;
    
    int get(){
    	return height;
    }
}

해당 코드를 살펴보면 b에는 Person의 객체를 이어받아 get()을 오버라이딩 했지만, 해당 객체의 이름은 따로 지정되어있지 않은데, 이러한 객체가 익명 객체다.

여기서 살펴볼 점은 저 b에 저장된 익명객체는 기존의 Person이 가지고 있던 name과 height 외에 age라는 변수가 추가되었다. 어디서 많이 본 방식인데.. 하고 생각해 보면 상속된 클래스와 같은 형태라고 볼 수 있다.

생성되는 익명 객체는 기존 클래스의 상속 관계이라는 말이 된다.

 

 

 

 

익명 객체로 Comparator 구현하기

익명 객체가 뭐 하는 객체인지도 알았고, Comparator가 어떤 방식으로 돌아가는지도 알아보았다. 이제 이 둘을 잘 엮어서 Comparator라는 인터페이스를 구현할 익명 객체를 만들어 두 객체를 비교해 주는 compare 메서드를 구현하게 되면 compare를 자유롭게 사용할 수 있게 되는 것이다.

public static void main(String[] args) {
	Person a = new Person("호날두", 186);
	Person b = new Person("메시", 170);
	Comparator<Person> comp = new Comparator<Person>() {
		@Override
		public int compare(Person p1, Person p2){
   	         	return p1.height - p2.height;
       		}
	};
        
	System.out.println(comp.compare(a, b));
}


//////

class Person{
    String name;
    int height;
    
    Person(String name, int height){
    	this.name = name;
        this.height = height;
    }
}

 

 

이런 방식의 장점은 따로 객체를 만드는 것이기 때문에 여러 변수에 대해 비교 메서드를 구현할 수 있다는 점이 있다. 

자매품으로 정렬을 이용할 때, Arrays.sort(arr, comp)와 같이 익명 객체를 파라미터로 사용하여 정렬을 수행하는 방법도 있다.

 

 

 

정렬 꿀팁(?)

- 정렬은 기본적으로 두 수를 비교해서 음수 또는 양수에 따라 교환이 이루어진다.

- 자바는 기본적으로 오름차순을 지향하고 있다.

- a - b가 음수라면 a가 더 작기 때문에 교환을 하지 않는다.

- a - b가 양수라면 a가 더 크기 때문에 교환이 이루어진다.

 

a - b의 결과 부호를 바꿔준다면? => 내림차순이 되는 것이다.

'Java' 카테고리의 다른 글

[JAVA] Stream API  (0) 2024.07.25
[JAVA] Lambda  (0) 2024.07.24
[JAVA] Generic  (3) 2024.07.22
[JAVA] 추상  (1) 2024.07.20
[JAVA] 다형성  (2) 2024.07.18
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.