왜 Java가 Comparable사용됩니까? 누군가 Comparable클래스에서 구현 하는 이유는 무엇 입니까? 비슷한 것을 구현해야하는 실제 사례는 무엇입니까?
왜 Java가 Comparable사용됩니까? 누군가 Comparable클래스에서 구현 하는 이유는 무엇 입니까? 비슷한 것을 구현해야하는 실제 사례는 무엇입니까?
답변:
실제 샘플은 다음과 같습니다. 그 참고 String도 구현을 Comparable.
class Author implements Comparable<Author>{
String firstName;
String lastName;
@Override
public int compareTo(Author other){
// compareTo should return < 0 if this is supposed to be
// less than other, > 0 if this is supposed to be greater than
// other and 0 if they are supposed to be equal
int last = this.lastName.compareTo(other.lastName);
return last == 0 ? this.firstName.compareTo(other.firstName) : last;
}
}
나중..
/**
* List the authors. Sort them by name so it will look good.
*/
public List<Author> listAuthors(){
List<Author> authors = readAuthorsFromFileOrSomething();
Collections.sort(authors);
return authors;
}
/**
* List unique authors. Sort them by name so it will look good.
*/
public SortedSet<Author> listUniqueAuthors(){
List<Author> authors = readAuthorsFromFileOrSomething();
return new TreeSet<Author>(authors);
}
last않습니까?
비교는 자연 순서를 정의합니다. 이것이 의미하는 것은 하나의 객체가 "보다 작음"또는 "보다 큼"으로 간주되어야 할 때이를 정의한다는 것입니다.
여러 개의 정수가 있고 정렬하려고한다고 가정하십시오. 꽤 쉬운 방법입니다. 정렬 된 컬렉션에 넣으면됩니다.
TreeSet<Integer> m = new TreeSet<Integer>();
m.add(1);
m.add(3);
m.add(2);
for (Integer i : m)
... // values will be sorted
그러나 이제 정렬이 의미가 있지만 정의되지 않은 사용자 정의 객체가 있다고 가정합니다. 인구 밀도가있는 우편 번호로 지구를 나타내는 데이터가 있고 밀도별로 정렬하려고한다고 가정 해 보겠습니다.
public class District {
String zipcode;
Double populationDensity;
}
이제 그것들을 정렬하는 가장 쉬운 방법은 Comparable을 구현하여 자연스러운 순서로 정의하는 것입니다. 즉, 이러한 객체가 정렬되도록 정의 된 표준 방법이 있습니다. :
public class District implements Comparable<District>{
String zipcode;
Double populationDensity;
public int compareTo(District other)
{
return populationDensity.compareTo(other.populationDensity);
}
}
비교기를 정의하여 동등한 작업을 수행 할 수 있습니다. 차이점은 비교기 가 객체 외부의 순서 논리를 정의한다는 것 입니다. 별도의 프로세스에서 우편 번호로 동일한 객체를 주문해야합니다.이 경우 순서는 반드시 객체의 속성 일 필요는 없으며 객체의 자연 순서와 다릅니다. 외부 비교기를 사용하여 예를 들어 사전 순으로 정렬하여 정수에 대한 사용자 정의 순서를 정의 할 수 있습니다.
기본적으로 순서 논리는 어딘가에 존재해야합니다. 그것은 가능하다 -
객체 자체에서 자연스럽게 비교 가능한 경우 (예 : 정수 확장)
위의 예와 같이 외부 비교기에서 제공됩니다.
TreeSet<Integer>대신 대신 TreeMap<Integer>해야합니다. 후자는 존재하지 않기 때문에 TreeMaps는 항상 <Key,Value>쌍입니다. Btw, TreeMap<District, Object>교육구가 Comparable을 구현 한 경우에만 가상의 효과 가 있을까요? 아직도 이해하려고 노력 중
javadoc에서 인용;
이 인터페이스는이를 구현하는 각 클래스의 객체에 총 정렬을 부과합니다. 이 순서를 클래스의 자연 순서라고하며 클래스의 compareTo 메소드를 자연 비교 방법이라고합니다.
이 인터페이스를 구현하는 객체의 목록 (및 배열)은 Collections.sort (및 Arrays.sort)로 자동 정렬 할 수 있습니다. 이 인터페이스를 구현하는 객체는 비교기를 지정할 필요없이 정렬 된 맵의 키 또는 정렬 된 세트의 요소로 사용할 수 있습니다.
편집 : .. 그리고 중요한 비트를 굵게 표시했습니다.
위의 예제 대부분은 compareTo 함수에서 기존의 비교 가능한 객체를 재사용하는 방법을 보여줍니다. 같은 클래스의 두 객체를 비교할 때 고유 한 compareTo를 구현하려면 가격별로 정렬하려는 AirlineTicket 객체 (첫 번째 순위는 낮음)와 중간 기착 횟수 (더 적은 것은 1 위), 다음을 수행합니다.
class AirlineTicket implements Comparable<Cost>
{
public double cost;
public int stopovers;
public AirlineTicket(double cost, int stopovers)
{
this.cost = cost; this.stopovers = stopovers ;
}
public int compareTo(Cost o)
{
if(this.cost != o.cost)
return Double.compare(this.cost, o.cost); //sorting in ascending order.
if(this.stopovers != o.stopovers)
return this.stopovers - o.stopovers; //again, ascending but swap the two if you want descending
return 0;
}
}
여러 필드 비교를 구현하는 쉬운 방법은 Guava의 ComparisonChain 을 사용하는 것입니다.
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(lastName, that.lastName)
.compare(firstName, that.firstName)
.compare(zipCode, that.zipCode)
.result();
}
대신에
public int compareTo(Person other) {
int cmp = lastName.compareTo(other.lastName);
if (cmp != 0) {
return cmp;
}
cmp = firstName.compareTo(other.firstName);
if (cmp != 0) {
return cmp;
}
return Integer.compare(zipCode, other.zipCode);
}
}
예를 들어 정렬 된 컬렉션 또는 맵 을 원할 때
Comparable은 클래스의 인스턴스를 비교하는 데 사용됩니다. 여러 가지 방법으로 인스턴스를 비교할 수 있으므로 인스턴스 compareTo를 비교하려는 방식을 파악하기 위해 메소드를 구현해야하는 이유가 있습니다 .
Dog 수업:package test;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Dog d1 = new Dog("brutus");
Dog d2 = new Dog("medor");
Dog d3 = new Dog("ara");
Dog[] dogs = new Dog[3];
dogs[0] = d1;
dogs[1] = d2;
dogs[2] = d3;
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* brutus
* medor
* ara
*/
Arrays.sort(dogs, Dog.NameComparator);
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* ara
* medor
* brutus
*/
}
}
Main 수업:package test;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Dog d1 = new Dog("brutus");
Dog d2 = new Dog("medor");
Dog d3 = new Dog("ara");
Dog[] dogs = new Dog[3];
dogs[0] = d1;
dogs[1] = d2;
dogs[2] = d3;
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* brutus
* medor
* ara
*/
Arrays.sort(dogs, Dog.NameComparator);
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* ara
* medor
* brutus
*/
}
}
다음은 Java에서 비슷한 기능을 사용하는 좋은 예입니다.
http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2
좋아, 그러나 compareTo()비슷한 인터페이스를 구현하지 않고 메소드를 정의하는 것은 어떻습니까? 예를 들어, 클래스 City에 의해 정의의 name및 temperature및
public int compareTo(City theOther)
{
if (this.temperature < theOther.temperature)
return -1;
else if (this.temperature > theOther.temperature)
return 1;
else
return 0;
}