5

, böyle Comparable.compareTo(...) uygulamaya Bu:Java 8'in Comperator.comparing (...) ile CompareToBuilder değiştirin thenComparing (...) Java 8 Önce

public int compare(Person a, Person b) { 
    return Comparator 
      .comparing(Person::getLastName) 
      .thenComparing(Person::getFirstName) 
      .compare(a, b); 
} 

yeni Java 8 yolu bize commons-lang3 bağımlılık damla izin verebilir. Bu yeni Java 8 yolu daha hızlı mı? Otomatik olarak taşınmanın bir yolu var mı? Bunun için bir IntelliJ niyetini bulamadım.

public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) { 
    return new CompareToBuilder() 
      .append(b.hasAnyFailure(), a.hasAnyFailure()) // Reverse 
      .append(a.getAverageScore(), b.getAverageScore(), resilientScoreComparator) 
      .toComparison(); 
} 

public int compare(SingleBenchmarkResult a, SingleBenchmarkResult b) { 
    return Comparator 
      .comparing(SingleBenchmarkResult::hasAnyFailure, Comparator.reverseOrder()) // Reverse 
      .thenComparing(SingleBenchmarkResult::getAverageScore, resilientScoreComparator) 
      .compare(a, b); 
} 

cevap

2

herhangi olduğunu sanmıyorum olur: ters emir ve non doğal karşılaştırma dahil orada olduğu zaman biraz daha karmaşık hale gelmesi


Bildirimi bunun için önceden tanımlanmış denetim. IntelliJ'in structural-search'u kullanmayı deneyebilirsiniz, ancak her olası durum için bunu yapmak oldukça zor olabilir. İki karşılaştırmalar ile basit durum için Bir olasılık aşağıdaki olabilir:

arama şablonu ($TYPE$ ve $z$ sebebin meydana geldiği sayısıdır 2):

$ReturnType$ $MethodName$($TYPE$ $z$) { 
     return new CompareToBuilder() 
       .append($A$.$m$(), $B$.$m$()) 
       .append($A$.$m1$(), $B$.$m1$()) 
       .toComparison(); 
    } 

yedek şablonu:

$ReturnType$ $MethodName$($TYPE$ $z$) { 
    return java.util.Comparator 
      .comparing($TYPE$::$m$) 
      .thenComparing($TYPE$::$m1$) 
      .compare($A$, $B$); 
} 

Ben Yapısal arama konusunda uzman değil, ama daha fazla veya daha az karşılaştırmalı aramalar için başka bir model yapmalısınız. bunu her karşılaştırma için yeni Comparator oluşturarak performansı harcıyorsun bu şekilde

public int compare(Person a, Person b) { 
    return Comparator 
      .comparing(Person::getLastName) 
      .thenComparing(Person::getFirstName) 
      .compare(a, b); 
} 

yazarsanız

6

. Ve çevreleyen koda bakarken açıkçası saçma olmalıdır. compare(Person a, Person b) yöntemi, kesinlikle, istenen karşılaştırıcıyı elde etmek için bir yerde anında başladığınız Comparator<Person>'u uygulayan bir sınıfın bir parçasıdır. Bunun yerine 'u örneğinin yerine tüm işlem boyunca kullanılan bir Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName) örneğiyle değiştirmeniz gerekir.

E.g.

// reusable 
static final Comparator<Person> By_NAME = Comparator 
      .comparing(Person::getLastName).thenComparing(Person::getFirstName); 

veya ad hoc

listOfPersons.sort(Comparator.comparing(Person::getLastName) 
          .thenComparing(Person::getFirstName)); 

Bunu bu şekilde kullanırsanız, daha hızlı olması çok olasıdır. Ancak, görmeniz gereken basit bir desen tabanlı değiştirme yoktur. Sınıfın kullanım sitelerini bu basit deklarasyonlu yapıyla değiştirmeniz ve birden fazla kullanım sitesi için paylaşılan bir karşılaştırıcı örneği kullanıp kullanmamaya veya bir ad-hoc oluşturup oluşturmamaya karar vermeniz gerekir. Daha sonra, tüm eski uygulama sınıfını kaldırabilir veya en azından hala başka amaçlara hizmet ediyorsa, karşılaştırıcı işlevini bundan kaldırabilirsiniz.

+0

Kişinin doğal karşılaştırmasını yapmam gerekiyor, bu yüzden önerilen değişiklikleri uygulayamıyorum. Comparator.comparing (...) 'in CompareToBuilder'den daha yavaş olduğuna inanıyor musunuz? –

+1

Eğer doğal düzeni uygularsanız, yöntem “Karşılaştır (Kişi, Kişi)” yerine “CompareTo (Kişi)” olmalıdır, bu yüzden soru yanıltıcıydı. "Comparatorer.comparing" işlevinin "CompareToBuilder" den daha yavaş olacağını düşünmüyorum ama yine de, "static final" alanını cevabımda gösterildiği gibi ilan ederek geliştirebilir ve "compareTo (Person)" öğesini uygulayabilirsiniz. BY_NAME.compare (bu, diğer); – Holger

+0

İyi nokta. Aslında doğal düzeni olan durumlarda kullanıyorum ve yeniden kullanılabilir bir Comperator (yukarıda olduğu gibi) olduğu durumlarda kullanıyorum. Bu uzman Comperator'ı ayrı bir sınıfa hazırlamak için neden gerekmediğini görüyorum. –