Java neden Comparablekullanılır? Neden birisi Comparablebir sınıfta uygulasın ki? Kıyaslanabilir uygulamanız gereken gerçek hayat örneği nedir?
Java neden Comparablekullanılır? Neden birisi Comparablebir sınıfta uygulasın ki? Kıyaslanabilir uygulamanız gereken gerçek hayat örneği nedir?
Yanıtlar:
İşte gerçek hayattan bir örnek. Not Stringda uygular 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;
}
}
sonra..
/**
* 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?
Karşılaştırılabilir bir doğal düzen tanımlar. Bunun anlamı, bir nesnenin "küçük" veya "büyük" olarak kabul edilmesi gerektiğinde onu tanımlamanızdır.
Bir grup tamsayıya sahip olduğunuzu ve bunları sıralamak istediğinizi varsayalım. Bu oldukça kolay, onları sıralı bir koleksiyona koyun, değil mi?
TreeSet<Integer> m = new TreeSet<Integer>();
m.add(1);
m.add(3);
m.add(2);
for (Integer i : m)
... // values will be sorted
Ama şimdi, sıralamanın benim için anlamlı olduğu ancak tanımsız olduğu bazı özel nesnelerim olduğunu varsayalım. Diyelim ki, nüfus yoğunluğuna sahip posta koduyla bölgeleri temsil eden verilerim var ve bunları yoğunluğa göre sıralamak istiyorum:
public class District {
String zipcode;
Double populationDensity;
}
Şimdi onları sıralamanın en kolay yolu, Karşılaştırılabilir'i uygulayarak doğal bir sıralama ile tanımlamaktır, bu da bu nesnelerin sipariş edilecek şekilde tanımlandığı standart bir yol olduğu anlamına gelir .:
public class District implements Comparable<District>{
String zipcode;
Double populationDensity;
public int compareTo(District other)
{
return populationDensity.compareTo(other.populationDensity);
}
}
Bir karşılaştırıcı tanımlayarak eşdeğer bir şey yapabileceğinizi unutmayın. Fark, karşılaştırıcının nesnenin dışındaki sıralama mantığını tanımlamasıdır . Belki ayrı bir süreçte aynı nesneleri zipcode ile sipariş etmem gerekiyor - bu durumda sipariş mutlaka nesnenin bir özelliği değildir veya nesnelerin doğal siparişinden farklıdır. Tamsayılarda özel bir sıralama tanımlamak için, örneğin bunları alfabetik değerlerine göre sıralayarak harici bir karşılaştırıcı kullanabilirsiniz.
Temel olarak sipariş mantığı bir yerde var olmak zorundadır. Bu olabilir -
nesnenin kendisinde, doğal olarak karşılaştırılabilirse (Karşılaştırılabilir -eg tam sayılarını genişletir)
Yukarıdaki örnekte olduğu gibi harici bir karşılaştırıcıda sağlanmıştır.
TreeSet<Integer>yerine TreeMap<Integer>, ikincisi mevcut olmadığından, TreeMaps her zaman <Key,Value>-pairs olmalıdır. Btw, bir varsayım TreeMap<District, Object>sadece Bölge Karşılaştırılabilir uygularsa işe yarardı, değil mi? Hala bunu anlamaya çalışıyorum
Javadoc'tan alıntı;
Bu arabirim, onu uygulayan her sınıfın nesnelerine tam bir sıralama uygular. Bu sıralamaya sınıfın doğal sıralaması denir ve sınıfın CompareTo yöntemi de doğal karşılaştırma yöntemi olarak adlandırılır.
Bu arabirimi uygulayan nesne listeleri (ve dizileri) Collections.sort (ve Arrays.sort) tarafından otomatik olarak sıralanabilir. Bu arabirimi uygulayan nesneler, karşılaştırıcı belirtmeye gerek kalmadan, sıralanmış bir haritada anahtarlar olarak veya sıralanmış bir kümedeki öğeler olarak kullanılabilir.
Düzenleme: ..ve önemli bit kalın yaptı.
Bir sınıfın uygulanması Comparable, o sınıftan iki nesne alabileceğiniz ve karşılaştırabileceğiniz anlamına gelir. Nesnelerin karşılaştırılabilir olmasını sağlamak için belirli koleksiyonlar (bir koleksiyondaki sıralama işlevi) gibi bazı sınıflar (sıralamak için hangi nesnenin "en büyük" olduğunu bilmeniz gerekir).
Yukarıdaki örneklerin çoğu, CompareTo işlevinde var olan karşılaştırılabilir bir nesnenin nasıl yeniden kullanılacağını gösterir. Aynı sınıftaki iki nesneyi karşılaştırmak istediğinizde, kendi CompareTo öğesini uygulamak isterseniz, fiyata (daha az önce sıralanır), ardından mola sayısına (tekrar, daha az ilk sırada), aşağıdakileri yaparsınız:
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;
}
}
Birden fazla alan karşılaştırması yapmanın kolay bir yolu Guava'nın CompareChain'idir - o zaman diyebilirsiniz
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(lastName, that.lastName)
.compare(firstName, that.firstName)
.compare(zipCode, that.zipCode)
.result();
}
onun yerine
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);
}
}
Örneğin, sıralanmış bir koleksiyona veya haritaya sahip olmak istediğinizde
Karşılaştırılabilir, sınıfınızın örneklerini karşılaştırmak için kullanılır. Örnekleri birçok yolla karşılaştırabiliriz, bu nedenle örnekleri compareTonasıl karşılaştırmak istediğimizi (nitelikler) bilmek için bir yöntem uygulamamız gerekir .
Dog sınıf: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 sınıf: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'da karşılaştırılabilir nasıl kullanılacağına dair iyi bir örnek:
http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2
Eğer uygulamak Comparablearayüzü, sen yöntemini uygulamak gerekir compareTo(). Örneğin ArrayListsınıf sınıflandırma yöntemini kullanmak için nesneleri karşılaştırmanız gerekir . Nesnelerinizi sıralayabilmek için bunları karşılaştırmanın bir yoluna ihtiyacınız var. compareTo()Sınıfınızda özel bir yönteme ihtiyacınız var, böylece ArrayListsort yöntemiyle kullanabilirsiniz. compareTo()Yöntem döner -1,0,1.
Java Head 2.0'daki uygun bir bölümü okudum, hala öğreniyorum.
Tamam, ama neden sadece compareTo()karşılaştırılabilir arayüz uygulamadan bir yöntem tanımlamıyorsunuz . Örneğin City, nameve temperatureile tanımlanmış bir sınıf
public int compareTo(City theOther)
{
if (this.temperature < theOther.temperature)
return -1;
else if (this.temperature > theOther.temperature)
return 1;
else
return 0;
}