なぜ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
ですか?
Comparableは自然な順序を定義します。これは、1つのオブジェクトを「より小さい」または「より大きい」と見なす必要がある場合に定義することを意味します。
たくさんの整数があり、それらをソートしたいとします。とても簡単です。並べ替えられたコレクションに入れるだけですよね?
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);
}
}
コンパレータを定義することで同等のことができることに注意してください。違いは、コンパレータがオブジェクト外の順序付けロジックを定義することです。多分別のプロセスで私は郵便番号で同じオブジェクトを注文する必要があります-その場合、注文は必ずしもオブジェクトのプロパティではないか、オブジェクトの自然な順序とは異なります。外部のコンパレーターを使用して、例えば、それらをアルファベット値でソートすることにより、整数のカスタム順序を定義できます。
基本的に、順序付けロジックはどこかに存在する必要があります。それは-
オブジェクト自体で、それが自然に比較可能な場合(Comparable -eg integersを拡張)
上記の例のように、外部コンパレータで供給されます。
TreeSet<Integer>
代わりにTreeMap<Integer>
する必要があり<Key,Value>
ます。後者は存在しないため、ツリーマップは常に- ペアです。ところで、仮説TreeMap<District, Object>
は、地区が比較可能を実装した場合にのみ機能しますよね?まだこれを理解しようとしている
javadocから引用。
このインターフェイスは、それを実装する各クラスのオブジェクトに完全な順序付けを課します。この順序付けはクラスの自然順序付けと呼ばれ、クラスのcompareToメソッドはその自然比較方法と呼ばれます。
このインターフェイスを実装するオブジェクトのリスト(および配列)は、Collections.sort(およびArrays.sort)によって自動的にソートできます。このインターフェースを実装するオブジェクトは、コンパレーターを指定する必要なく、ソート済みマップのキーまたはソート済みセットの要素として使用できます。
編集:..そして重要な部分を太字にしました。
上記の例のほとんどは、compareTo関数で既存の比較可能なオブジェクトを再利用する方法を示しています。同じクラスの2つのオブジェクトを比較するときに独自のcompareToを実装する場合は、価格でソートするAirlineTicketオブジェクトを言います(少ない方が最初にランク付けされます)。最初にランク付け)、次のようにします:
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
and temperature
およびandで定義されたクラス
public int compareTo(City theOther)
{
if (this.temperature < theOther.temperature)
return -1;
else if (this.temperature > theOther.temperature)
return 1;
else
return 0;
}