JAVA

JAVA : Comparable & Comparator (+ 백준 11650)

Haerin 2021. 6. 22. 15:40

Java에서 Arrays.sort()를 이용하면 배열 값을 오름차순으로 정렬할 수 있다.

 

 

< String 배열 sort 구현>

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
class Main {
  public static void main(String[] args) {

    String[] productsName = new String[]{"bag", "mouse","note"};

    Arrays.sort(productsName);

    for(int i =0;i < productsName.length; i++){
      System.out.println(productsName[i]+ " ");
    }
  }
}

 

결과

자바에서 기본적으로 제공되는 정렬이 가능한 클래스는 인터페이스 Comparable 구현하고 있다.

 

 

 

<ArrayList sort 구현>

class Products {
  private String name;
  private int price;

  public Products(String name, int price){
    this.name = name;
    this.price = price;
  }

  public void setName(String name){
    this.name  = name;
  }

  public String getName(){
    return this.name;
  }

  public void setPrice(int price){
    this.price  = price;
  }

  public int getPrice(){
    return this.price;
  }

 
}

 

 

ArrayList는 Arrays.sort() 대신 Collections.sort()를 이용한다.

* Arrays.sort() :  배열을 정렬하는 경우 (ex. primitive Array : 기본 자료형에 대한 배열, Object Array : 새로 정의한 클래스에 대한 배열)

* Collections.sort() : List Collection 정렬의 경우

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
class Main {
  public static void main(String[] args) {

    ArrayList<Products> productList = new ArrayList<Products>();

    Products product1 = new Products("book",12000);
    Products product2 = new Products("candy",1000);
    Products product3 = new Products("noodle",4000);

    productList.add(product1);
    productList.add(product2);
    productList.add(product3);

    Collections.sort(productList);
    
    for(int i =0;i < productList.size(); i++){
      System.out.println(productList.get(i).getName());
    }

  }
}
​

결과 > 오류가 발생한다

: Products의 정렬을 기준을 name으로 할지, price로 할지 정하지 않았기 때문!!!

-> ComparablecompareTo 메소드 구현을 통해 기본적으로 적용되는 정렬 기준을 정의해야 한다!

 

 

 

JAVA 공식 api에서 확인가능하다.

 

Comparable (Java Platform SE 8 )

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method. Lists (and arrays) of o

docs.oracle.com

 

class Products implements Comparable<Products>{
  private String name;
  private int price;

  public Products(String name, int price){
    this.name = name;
    this.price = price;
  }

  public void setName(String name){
    this.name  = name;
  }

  public String getName(){
    return this.name;
  }

  public void setPrice(int price){
    this.price  = price;
  }

  public int getPrice(){
    return this.price;
  }
  // CASE1 : 이름 오름차순 정렬 기준
  @Override
  public int compareTo(Products products){
    return name.compareTo(products.getName());
  }
  // CASE2 : 나이 오름차순 정렬 기준
  @Override
  public int compareTo(Products products){
    if(this.age > o.age) {
    	return 1; // 자신의 나이가 더 클 경우
    }else if(this.age < o.age) {
    	return -1; // 자신의 나이가 더 작을 경우
    }else {
    	return 0; // 자신의 나이와 동일한 경우
    }
  }
}

따라서, Products의 정렬 기준에 따라 2가지 케이스의 coparareTo 메소드를 구현했다.

 

 

CASE1의 경우, 이름 순으로 정렬한 결과

정렬 성공!!

▶ Comparable은 기본 정렬기준을 구현하는 데 사용한다.

 

 


 

기본 정렬 기준 외에 다른 기준으로 정렬하고 싶을 때는 Comparator을 사용한다.

 

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Comparator;
class Main {
  public static void main(String[] args) {

    ArrayList<Products> productList = new ArrayList<Products>();

    Products product1 = new Products("book",12000);
    Products product2 = new Products("candy",1000);
    Products product3 = new Products("noodle",4000);

    productList.add(product1);
    productList.add(product2);
    productList.add(product3);

    Collections.sort(productList, new Comparator<Products>(){
      @Override
      public int compare(Products p1, Products p2){
      //가격순으로 정렬
        if(p1.getPrice() > p2.getPrice() )
          return 1;
        else if (p1.getPrice() < p2.getPrice())
          return -1;
        else
          return 0;
      }
    });

    for(int i =0;i < productList.size(); i++){
      System.out.println(productList.get(i).getName());
    }
  }
}

 

 

Comparator을 사용할때는 compare를 재정의 해야한다. 

위의 코드는 가격이 저렴한 순으로 나열했다.

 

 

위 코드대로 매개 변수 p1와 p2를 비교할 때 

 양수 return -> 정렬 결과 : p2 - p1 순

음수 return -> 정렬 결과 : p1 - p2 순

 

 

Comparable은 자기자신과 매개변수 객체를 비교하는 역할로 객체의 기본 정렬기준을 세운다. > compareTo 메소드 구현 필요

Comparator은 두 매개변수 객체를 비교하는 역할로 객체의 기본 정렬 기준 외에 다른 정렬 기준을 세울 때 사용한다. > compare 메소드 구현 필요

 

 

 

활용) 백준 문제 11650

 

11650번: 좌표 정렬하기

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net

 

: 2차원 평면의 점들이 주어졌을 때, x좌표가 증가하는 순으로 정렬하고

x좌표가 같다면 y좌표가 증가하는 순으로 정렬하는 프로그램 작성하기

 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.Comparator;
// 1. n : 좌표 개수 입력 받기
// 2. arr : 좌표값 입력 받기
// 3. sort

class Main {
  public static void main(String[] args) throws IOException{

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    int n = Integer.parseInt(br.readLine());

    int[][] arr = new int[n][2];
    StringTokenizer st;
    for(int i =0;i<n;i++){
      st = new StringTokenizer(br.readLine());
      arr[i][0]=Integer.parseInt(st.nextToken()); //x좌표
      arr[i][1]=Integer.parseInt(st.nextToken()); //y좌표
    }

     Arrays.sort(arr ,new Comparator<int[]>(){
      @Override
      public int compare(int[] p1, int[] p2){
        if(p1[0] == p2[0] ) //x좌표가 동일하면
          return Integer.compare(p1[1],p2[1]); //y좌표 비교
        else  //x좌표가 다르면
          return Integer.compare(p1[0],p2[0]); //x좌표 비교
      }
    });

    StringBuilder sb = new StringBuilder();
    for(int i =0; i <n;i++){
      sb.append(arr[i][0]+ " "+ arr[i][1]).append('\n');
    }
   
    System.out.println(sb);

  }
}

 


정리

 

 

 

참고 사이트

 

 

자바 정렬 Java Comparable Comparator 확실히 알고 넘어가기

배열이나 Collection 프레임워크 등에서 sort() 를 사용하면 컴퓨터가 알아서 정렬을 해준다. 여기서 사용되는 sort() 는 Comparable 구현에 의해 정렬된 것인데, 오늘은 자바 정렬 Java Comparable과 Comparato.

cwondev.tistory.com

 

[Java] 내가 만든 클래스 객체 배열 정렬하기 (comparable, comparator, comparing)

www.baeldung.com/java-sorting Sorting in Java | Baeldung Practical introduction to sorting in Java. www.baeldung.com 내가 직접 추상화해 만든 클래스의 객체들로 이루어진 배열을 정렬하고자 할 때 어떤 방법들이 있을까?

choichumji.tistory.com