Comparable, Comparator 차이

Comparable


ComparableJava.lang package에 있는 인터페이스이며 정렬을 위해 사용되는데, 보통 기본형(Primitive Type)을 정렬하는데 사용하지는 않습니다.
Comparable을 사용하는것은 객체(Object)의 정렬기준을 만들어 주기 위해서입니다.
만약 String타입의 자료들을 정렬하기 위해 배열을 만들고, 정렬한다면 간단하게 Arrays.sort()메서드를 사용하여 사전순서대로 정렬할 수 있습니다.
하지만 객체는 정렬기준이 없기때문에 Comparable 인터페이스를 객체의 클래스에서 구현하여 정렬기준을 만들어주는 방식으로 사용됩니다.
Comparable 인터페이스의 구현체는 반드시 compareTo(<T> e)를 구현해야 합니다.

Comparable 인터페이스 구현 예시


public class CompareTest {
	public static void main(String[] args) {

		List<Emp> list = new ArrayList<>();
		
		list.add(new Emp("A001", "김수한", 10000));
		list.add(new Emp("B001", "무거북", 20000));
		list.add(new Emp("C001", "이와두", 12000));
		list.add(new Emp("D001", "루미삼", 50000));
		list.add(new Emp("E001", "천갑자", 30000));
		
		System.out.println("연봉기준 오름차순 정렬");
		Collections.sort(list);
		
		for(Emp e : list) {
			System.out.println(e);
		}
	}
}

class Emp implements Comparable<Emp> {

	private String emp_no;
	private String emp_name;
	private int salary;	
	
	public Emp(String emp_no, String emp_name, int salary) {
		super();
		this.emp_no = emp_no;
		this.emp_name = emp_name;
		this.salary = salary;
	}

	public String getEmp_no() {
		return emp_no;
	}

	public void setEmp_no(String emp_no) {
		this.emp_no = emp_no;
	}

	public String getEmp_name() {
		return emp_name;
	}

	public void setEmp_name(String emp_name) {
		this.emp_name = emp_name;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}

	@Override
	public String toString() {
		return "emp [emp_no=" + emp_no + ", emp_name=" + emp_name + ", salary=" + salary + "]";
	}

	@Override
	public int compareTo(Emp emp) {
		// 연봉기준 오름차순 정렬이 되도록 구현		
		return salary - emp.getSalary();
	}
}

출력결과

연봉기준 오름차순 정렬
emp [emp_no=A001, emp_name=김수한, salary=10000]
emp [emp_no=C001, emp_name=이와두, salary=12000]
emp [emp_no=B001, emp_name=무거북, salary=20000]
emp [emp_no=E001, emp_name=천갑자, salary=30000]
emp [emp_no=D001, emp_name=루미삼, salary=50000]

위의 예시에서 Emp클래스는 Comparable의 구현체입니다.
따라서 compareTo(Emp emp)메서드를 오버라이드 하였고, 오름차순정렬이 되도록 구현했습니다.
또한 Emp객체를 관리하는 List는 배열이 CollectionFrame이기때문에 Arrays.sort가 아닌 Collections.sort()를 사용하였습니다.

compareTo() 메서드는 자기자신의 salary와 매개변수로 넘어온 객체의 salary를 비교합니다.

  • compareTo(Emp emp) 의 반환값
    • salary > emp.getSalary()
      • return 1
    • salary == emp.getSalary()
      • return 0
    • salary < emp.getSalary()
      • return -1

이렇게 정렬의 대상이 되는 객체의 클래스에 Comparable 인터페이스를 구현하면, 객체들의 정렬기준을 정할 수 있습니다.

Comparator


ComparatorJava.util package에 있는 인터페이스입니다.
Comparable과 마찬가지로 Comparator는 객체의 정렬에 사용됩니다
하지만 Comparator의 구현체는 클래스 자체가 정렬기준으로 사용됩니다.
한마디로 외부 정렬기준을 정의한다는 것입니다
한 가지 예를들어보면 지금 우리가 선언한 Emp클래스는 이미 Comparable 인터페이스를 구현했기때문에 정렬기준을 가지고 있습니다.
만약 사용자가 Emp클래스에 정해진 정렬기준이 아닌 다른 정렬기준으로 데이터를 정렬하고 싶다면 어떻게 해야할까요?
Emp클래스 내부에 구현되어 있는 compareTO() 메서드를 수정하는것은 임시방편일 뿐입니다.
이러한 경우 사용할 수 있는것이 Comparator를 구현한 외부 정렬자를 사용하는 것입니다

Comparator 인터페이스 구현 예시


public class CompareTest {
	public static void main(String[] args) {

		List<Emp> list = new ArrayList<>();
		
		list.add(new Emp("A001", "김수한", 10000));
		list.add(new Emp("B001", "무거북", 20000));
		list.add(new Emp("C001", "이와두", 12000));
		list.add(new Emp("D001", "루미삼", 50000));
		list.add(new Emp("E001", "천갑자", 30000));
		
		System.out.println("연봉기준 내림차순 정렬");
		Collections.sort(list, new SalaryDesc());
		
		for(Emp e : list) {
			System.out.println(e);
		}
		System.out.println();
		
		System.out.println("이름기준 내림차순 정렬");
		Collections.sort(list, new NameDesc());
		
		for(Emp e : list) {
			System.out.println(e);
		}
	}
}

class SalaryDesc implements Comparator<Emp> {

	@Override
	public int compare(Emp emp1, Emp emp2) {
		// 연봉기준 내림차순 정렬이 되도록 구현
		return emp1.compareTo(emp2) * -1;
	}
}

class NameDesc implements Comparator<Emp> {

	@Override
	public int compare(Emp emp1, Emp emp2) {
		//이름기준 오름차순 정렬이 되도록 구현
		return emp1.getEmp_name().compareTo(emp2.getEmp_name()) * -1;
	}
}

출력결과

연봉기준 내림차순 정렬
emp [emp_no=D001, emp_name=루미삼, salary=50000]
emp [emp_no=E001, emp_name=천갑자, salary=30000]
emp [emp_no=B001, emp_name=무거북, salary=20000]
emp [emp_no=C001, emp_name=이와두, salary=12000]
emp [emp_no=A001, emp_name=김수한, salary=10000]

이름기준 내림차순 정렬
emp [emp_no=E001, emp_name=천갑자, salary=30000]
emp [emp_no=C001, emp_name=이와두, salary=12000]
emp [emp_no=B001, emp_name=무거북, salary=20000]
emp [emp_no=D001, emp_name=루미삼, salary=50000]
emp [emp_no=A001, emp_name=김수한, salary=10000]

Comparable 인터페이스를 구현할 때와 조금 다른것을 볼 수 있습니다
우선 Collections.sort()메서드의 매개변수가 2개가 되었습니다.
외부 정렬자(Comparator의 구현체)를 사용할 때는 Collections.sort()의 매개변수로 정렬기준을 넘겨주어야 합니다
그리고 Comparator의 구현체는 compare(Emp emp1, Emp emp2)메서드를 구현하는데 매개변수가 2개입니다
현재 자기자신의 값과 비교하는 compareTo메서드와 다르게 매개변수로 받은 2개의 객체가 가진 값을 비교하기 때문입니다.
마지막으로 연봉기준 내림차순 정렬을 구현한 SalaryDesc클래스를 보면, Emp클래스에 이미 구현되어 있는 compareTo메서드를 재사용하였습니다.
이미 오름차순으로 정렬기준이 잡혀있는 comepareTo메서드의 결과에 -1을 곱하면 내림차순으로 쉽게 구현할 수 있습니다.
이처럼 이미 정해진 정렬기준 외 다른 정렬기준을 사용하고 싶다면 Comparator의 구현체를 사용하여 여러가지 정렬기준을 사용할 수 있습니다.

Summary


설명이 두서없이 길어진것 같아서 이해하기 어려울 수 있을것같습니다
간단하게 Comparable과 Comparator의 차이를 정리하고 포스팅을 마치겠습니다

  • Comparable
    • java.lang package
    • 객체의 정렬기준을 정해줄 때 사용한다.
    • Comparable 인터페이스의 구현체는 compareTo메서드를 구현해야 한다.
  • Comparator
    • java.util package
    • 이미 정해진 정렬기준 외 다른 정렬기준을 사용하고 싶을때 사용한다.
    • Comparator 인터페이스의 구현체는 compare메서드를 구현해야 한다.
    • Comparator 인터페이스의 구현체는 그 자체가 정렬자로 사용된다. (정렬기준)

2020

MVC Model1과 MVC Model2

November 24 2020

MVC 패턴 MVC패턴은 소프트웨어 공학에서 사용되는 디자인 패턴 중 하나입니다. MVC패턴은 사용자 인터페이스와 비즈니스 로직을 분리하여 각각의 로직을 독립적으로 운용하여 유지보수를 용이하게 만들 수 있는 디자인 패턴입니다.

URL과 URI

November 23 2020

URL URL은 Uniform Resource Locator의 약자로써 리소스의 위치를 통해 식별하는 방법을 의미합니다.

Tomcat 구조

November 19 2020

bin bin은 톰캣을 실행하고, 종료시키는 역할을 하는 스크립트(.bat, .sh) 파일이 위치하는 폴더입니다.

터미널에서 자바 컴파일과 실행

November 19 2020

Terminal을 사용하는 이유 IDE툴을 사용하면 소스코드를 알아서 컴파일해주고 실행해주기 때문에 어떻게 이러한 과정이 이루어지는지 생각하지 않게됩니다. 특히 경로에 대한 개념이 무뎌지는것 같습니다. 그래서 이번에는 Eclipse를 사용하지 않고 Terminal을 이용하여 직...

Web Server와 WAS

October 19 2020

Intro 본 포스팅은 HeeJeong Kwon님의 블로그를 참고하였습니다.

Socket통신과 HTTP통신

October 15 2020

Socket통신 Socket통신은 Server와 Client가 특정포트에 실시간으로 연결되어 있는 통신방식입니다. UDP를 사용하여 비연결지향 통신방식을 사용할 수 있지만, Socket통신의 경우 대부분이 TCP를 사용하여 연결지향형 통신방식을 사용합니다. 연결지향형이기 때문에...

HTTP Response 구조

October 13 2020

Intro 본 게시물은 아래의 게시물을 참고하여 포스팅하였습니다.

SQL-99 표준

October 11 2020

SQL-99 표준 SQL문은 ISO/ANSI에서 관계형 데이터베이스 표준 언어로 지정(SQL-82)된 후 SQL-92를 거쳐 SQL-99 표준 문법이 나왔습니다. 그리고 오라클은 9i 버전부터 SQL-99 방식의 문법을 지원하고 있습니다. SQL-99 조인은 앞에서 배운 조인 ...

JOIN의 종류(외부조인)

October 11 2020

외부조인(OUTER JOIN) 이전 포스팅에서는 등가조인, 비등가조인, 자체조인에 대해서 알아보았습니다. 이번 포스팅에서는 외부조인(outer join)에 대해서 알아보려고 합니다. 등가조인에서는 조인 조건의 데이터가 일치하는 정보만을 출력하였습니다. 다시 말해서 조인 조건의 ...

JOIN 기본개념

October 10 2020

JOIN JOIN은 필요한 데이터가 여러 테이블에 분산되어 있는경우 테이블과 테이블간의 관계를 이용하기 위한 것입니다. 만약 사원의 정보와 함께 사원의 근무부서의 위치를 함께 조회하고 싶다면, 사원테이블과 부서테이블을 둘 다 조회해야합니다. 이러한 경우에 사용되는 것이 JOIN...

log4j(log for java)

October 08 2020

Log4j 정의 Log4j (Log for Java)는 로그문의 출력을 다양한 대상으로 할 수 있도록 도와주는 도구이며 오픈소스 기반입니다.

iBatis

October 08 2020

iBatis iBatis는 객체와 DB 테이블간의 관계를 Mapping하여 효율적으로 데이터를 처리할 수 있는 기능을 제공해주는 ORM Framework입니다. iBatis를 사용하면 기존의 JDBC코드 없이 SQL문장을 더욱 직관적이고 간결하게 수행할 수 있습니다.

BabyGin(SW Expert Academy)

October 07 2020

Baby Gin Baby Gin은 간단한 카드게임입니다 Baby Gin게임은 run과 triple이 존재하고 카드의 구성이 run과 triple로만 이루어져 있으면 이것을 Baby Gin이라고 하고, 그렇지 않으면 lose입니다.

Gravity(SW Expert Academy)

October 06 2020

Gravity Gravity문제는 2차원 배열을 다루는 간단한 문제입니다. 2차원 배열은 박스와 빈 공간으로 이루어져 있고, 각각은 1과 0으로 표현됩니다. 주어진 2차원 배열을 시계방향으로 90도 회전시켰을 때 가장 큰 낙차가 얼마인지 구하는 문제입니다

File Sample Code(파일 예제)

September 27 2020

Sample Code ```java import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List;

File Stream(파일 스트림)

September 27 2020

File 자바에서는 File 클래스는 사용해서 간단한 파일작업을 할 수 있다 오늘 예제에서는 파일을 생성하고, 읽어오는 방법에 대해 알아보려고 한다 File클래스는 이름은 File이지만 Directory까지 다루는 클래스이다

File Encoding(파일 인코딩)

September 27 2020

File Encoding 이전 포스팅에서 Endiong문제로 파일작업이 제대로 이루어지지 않는 경우에 대한 예제를 살펴보았다. 오늘은 보조스트림을 통해 Encoding까지 지정하는 방법을 알아보려고 한다.

ByteArrayIOStream(바이트 배열기반 입출력 스트림)

September 27 2020

Stream Stream이란 데이터를 주고받는 통로를 의미한다 Stream은 단방향으로만 작업이 가능하다. 따라서 입력과 출력을 위한 Stream이 따로 존재하고, 두 가지 작업을 하기 위해서는 입력스트림(InputStream)과 출력스트림(outputStream)이 하나씩 필...

Single-Thread VS Multi-Thread

September 22 2020

Single Thread(단일 쓰레드) Single Thread는 말 그대로 하나의 Thread를 사용하는 것이다. 단일 쓰레드를 사용하는 프로세스는 별도로 쓰레드를 관리하는 번거로움이 없어서 코딩은 용이하겠지만, 작업시간이 낭비되는 경우가 생긴다.

Thread

September 21 2020

Process Process는 운영체제에서 실행중인 하나의 프로그램을 의미한다. Multi-Process는 두 개 이상의 프로세스가 실행되는 것을 의미한다. Multi-Tasking은 두 개 이상의 프로세스를 실행하여 일을 처리하는 것을 의미한다.

람다식(Lambda)

September 21 2020

람다식 익명함수를 생성하기 위한 식이다.

해싱(Hashing)과 해시함수(Hash Function)

September 15 2020

해싱(Hashing) 해싱(Hashing)이란 해시함수(Hash Function)를 이용하여 해시 테이블(Hash Table)에 데이터를 저장하는 방법을 말합니다. 해시함수는 데이터가 저장되어 있는 위치를 알려주기 때문에 많은 데이터 중에서도 원하는 데이터를 빠르게 찾아낼 수...

Comparable, Comparator 차이

September 14 2020

Comparable Comparable은 Java.lang package에 있는 인터페이스이며 정렬을 위해 사용되는데, 보통 기본형(Primitive Type)을 정렬하는데 사용하지는 않습니다. Comparable을 사용하는것은 객체(Object)의 정렬기준을 만들어 주기 위해...

초급 프로젝트 후기

September 12 2020

초급 프로젝트 개발원에서 5일간 진행하는 프로젝트가 끝났다. JDBC를 이용해서 간단한 프로그램을 만드는 프로젝트였다. 우리는 영화관 예매 시스템을 만들기로했고, 생각보다 쉽지않다는 것을 느꼈다. 우선 시간을 관리한다는것이 어렵다는 것을 느꼈다. 모든 경우의 수를 생각해야하고,...

CHAR, VARCHAR2 (ORACLE)

September 06 2020

문자열 오라클의 문자열 자료는 ' '(single quote)로 묶어서 표현되며, 문자열 자료형은 CHAR, VARCHAR, VARCHAR2, LONG, CLOB, NVARCHAR, NCLOB 등이 있습니다. VARCHAR2는 오라클에서만 사용하는 문자열 자료형입니다. VARC...

Greedy Algorithm(탐욕 알고리즘)

August 20 2020

Greedy Algorithm (탐욕 알고리즘) Greedy Algorithm(탐욕 알고리즘)이란 최적해를 구하는 데 사용되는 근시안적인 방법입니다. 여러 경우 중 하나를 결정해야 할 때마다 그 순간에 최적이라고 생각되는 것을 선택해 나가는 방식으로 진행하여 최종적인 해답에 도...

검색 알고리즘(Search Algorithm)

August 14 2020

선형검색 알고리즘(LinearSearch Algorithm) 선형검색(LinearSearch)알고리즘이란, 요소가 직선모양으로 나열되어 있는 배열에서는 순차적으로 요소를 조회하여 원하는 값을 찾을 수 있습니다. 검색 알고리즘 중 가장 간단한 알고리즘입니다.

버블정렬(Bubble Sorting)

August 11 2020

버블정렬(Bubble Sorting) 버블정렬(Bubble Sorting)은 배열에서 인접한 인덱스의 값을 비교하여 오름차순 또는 내림차순으로 정렬하는 방법입니다.

추상클래스와 인터페이스 (Abstract Class and Interface)

August 08 2020

추상클래스(Abstract Class) 추상클래스(Abstract Class)는 말 그대로 추상적인 클래스입니다. 하지만 추상적이라는 것은 너무 광범위한 단어입니다. 자바에서는 추상메소드가 한 개라도 선언되어 있는 클래스는 반드시 추상클래스로 선언해야합니다. 추상메소드란 메소드...

오버라이딩과 다형성(Overriding and Polymorphism)

August 07 2020

오버라이딩(Overriding) 오버라이딩(Overriding)이란 상위 클래스에 선언되어 있는 메소드를 하위 클래스에서 동일하게 선언하여 사용하는 것입니다. 메소드의 이름, 시그니처가 동일하지만 하위 클래스에서 구현내용을 재정의 하여 사용할 수 있습니다.

상속(Inheritance)

August 06 2020

상속(Inheritance) 자바에서 상속이라는 것은 내용이 작성되어 있는 클래스를 다른 클래스에서 사용할 수 있도록 만들어 주는 것입니다 또한 상속을 사용하면 코드의 재사용을 통해 코드의 중복을 없앨 수 있고, 유지보수가 매우 용이해지는 장점이 있습니다. 하나의 클래스만 잘 ...

생성자(Constructor)

August 05 2020

생성자 생성자란 객체 생성시 제공되는 초기화 기능이라고 생각하면 됩니다.

자바의 변수종류(Variables)

August 03 2020

변수(Variable) 자바에서 변수는 값을 저장하기 위한 공간이라고 생각할 수 있습니다. 그리고 변수들은 데이터 타입(Data Type)을 가지게 됩니다. 우선 변수에 대해 알아보기 전에 자바의 데이터 타입에 대해 알아보겠습니다.

중첩 클래스(Nested Class)

August 01 2020

중첩 클래스(Nested Class) 중첩 클래스는 단어 그대로 클래스가 중첩되어있는 상태입니다. 하나의 클래스안에 또 다른 클래스가 정의되어 있는 형태라고 생각하면 됩니다. 이러한 중첩클래스 3가지 종류가 있습니다.

JVM 메모리 구조(JVM Memory Structure)

July 31 2020

JVM (Java Virtual Machine) 자바 프로그램은 JVM을 통해 실행됩니다. 자바 프로그램을 실행하면, JVM은 운영체제로부터 메모리를 할당받아 프로그램을 실행합니다. 오늘은 자바 프로그램을 실행하면 JVM의 메모리 구조에 대해 알아보겠습니다.

형변환(Type Casting)

July 27 2020

목차 1. 형변환이란? 2. 기본형 표현범위 포함관계 3. 형변환 종류 4. 유의사항 5. 연습문제

맨 위로 이동 ↑