2014-09-15 108 views
8

Sıralanmamış ürün akışı ve bir karşılaştırıcı akışı var. Tüm karşılaştırıcıları "thenComparing" (Multisort) kullanarak akışa uygulamak istiyorum. Bunu yapmak için aşağıdaki koddan daha zarif bir yol var mı?Bir karşılaştırıcı akışı nasıl oluşturulur ve uygulanır?

Comparator compareFunc = comparators.reduce((a, b) -> 0, Comparator::thenComparing); 

Veya bunun yerine Holger gelen biraz çalmak:

Optional<Comparator> compareFunc = comparators.reduce(Comparator::thenComparing); 
Stream<?> result = compareFunc.isPresent() ? result.sorted(compareFunc.get()) 
              : unsorted; 
+0

Azaltılmış null parametresinden ve if (a == null) ifadesinden kaçınmak isterim – jack

+2

Her zaman "null" yerine 0 döndüren bir temel karşılaştırıcı kullandıysanız, muhtemelen biraz daha temiz olabilir. Bu null ve dalı kaldırırdı. –

+2

@mark yep kodunu basitleştiren compareFunc = comparators.reduce ((a, b) -> 0, (a, b) -> a.thenComparing (b)); thanxs – jack

cevap

6

Stream unsorted = ...; 
Stream<Comparator> comparators = ...; 

Comparator compareFunc = comparators.reduce(null, (a, b) -> { 
     if(a == null) { 
      return b; 
     }else { 
      return a.thenComparing(b); 
     } 

    }); 

Stream result = unsorted.sorted(compareFunc); 
+0

thanxs çok güzel görünüyor – jack

4

Mark Peters' önerisini kullanma ve yöntem referans ile karıştırılarak, kendi karşılaştırıcı bu şekilde yazabiliriz Comparator s için kimlik değeri'u kullanmayın. comparators akışı boşsa sıralama olmamalı (yani herhangi Comparator içermiyor): comparators akışı Comparator azalma sonucu olacağını, sadece tek bir Comparator içeriyorsa o

Stream result=comparators.reduce(Comparator::thenComparing) 
      .map(unsorted::sorted).orElse(unsorted); 

Not. Optional.map geçirilen


yöntem referansı buna alışması için biraz tecrübe gerekebilir. Bu yüzden orada neler olduğunu göstermek için daha fazla ayrıntılı lambda sözdizimi kullanılarak değer olabilir:

programlama stili veya kişisel tercih meselesi ve zaman içinde değişebilir
Stream<String> result=comparators.reduce(Comparator::thenComparing) 
    .map((comparator) -> unsorted.sorted(comparator)).orElse(unsorted); 

.

+2

@Holger Senin fikrini biraz çalmıştım - cevabın tersine çevrilmiş sözdizimini dürüst olmak için daha az açık buluyorum. – assylias

+1

Eh, 'İsteğe Bağlı '' isPresent() 'kullanarak ne yapması gerektiğini anlatmayı tercih ediyorum. Bu, Stream's ve harici yineleme ile yaptığınız işe daha yakındır. Ancak, elbette, dış operasyon daha ne ifade ediyor (daha fazla ayrıntı var) neler oluyor… – Holger

İlgili konular