En yüksek oylanan cevap Java 8 wrt kesinlikle en iyi cevap olsa da, aynı zamanda performans açısından kesinlikle en kötü yanıtı. Gerçekten kötü bir düşük performanslı uygulama istiyorsanız, devam edin ve kullanın. Benzersiz bir Kişi Adları grubunun çıkarılması için basit bir gereklilik sadece "Her biri için" ve "Set" ile sağlanacaktır. Liste 10'dan büyükse işler daha da kötüleşir.
Aşağıdaki gibi 20 Nesne koleksiyonunuz olduğunu düşünün:
public static final List<SimpleEvent> testList = Arrays.asList(
new SimpleEvent("Tom"), new SimpleEvent("Dick"),new SimpleEvent("Harry"),new SimpleEvent("Tom"),
new SimpleEvent("Dick"),new SimpleEvent("Huckle"),new SimpleEvent("Berry"),new SimpleEvent("Tom"),
new SimpleEvent("Dick"),new SimpleEvent("Moses"),new SimpleEvent("Chiku"),new SimpleEvent("Cherry"),
new SimpleEvent("Roses"),new SimpleEvent("Moses"),new SimpleEvent("Chiku"),new SimpleEvent("gotya"),
new SimpleEvent("Gotye"),new SimpleEvent("Nibble"),new SimpleEvent("Berry"),new SimpleEvent("Jibble"));
İtiraz ettiğiniz yer SimpleEvent
şöyle:
public class SimpleEvent {
private String name;
private String type;
public SimpleEvent(String name) {
this.name = name;
this.type = "type_"+name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Ve test etmek için, böyle JMH kodunuz var , (Lütfen dikkat, kabul edilen cevapta belirtilen aynı farklı imi kullanıyorum ):
@Benchmark
@OutputTimeUnit(TimeUnit.SECONDS)
public void aStreamBasedUniqueSet(Blackhole blackhole) throws Exception{
Set<String> uniqueNames = testList
.stream()
.filter(distinctByKey(SimpleEvent::getName))
.map(SimpleEvent::getName)
.collect(Collectors.toSet());
blackhole.consume(uniqueNames);
}
@Benchmark
@OutputTimeUnit(TimeUnit.SECONDS)
public void aForEachBasedUniqueSet(Blackhole blackhole) throws Exception{
Set<String> uniqueNames = new HashSet<>();
for (SimpleEvent event : testList) {
uniqueNames.add(event.getName());
}
blackhole.consume(uniqueNames);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(MyBenchmark.class.getSimpleName())
.forks(1)
.mode(Mode.Throughput)
.warmupBatchSize(3)
.warmupIterations(3)
.measurementIterations(3)
.build();
new Runner(opt).run();
}
Sonra Benchmark sonuçları şöyle olacaktır:
Benchmark Mode Samples Score Score error Units
c.s.MyBenchmark.aForEachBasedUniqueSet thrpt 3 2635199.952 1663320.718 ops/s
c.s.MyBenchmark.aStreamBasedUniqueSet thrpt 3 729134.695 895825.697 ops/s
Gördüğünüz gibi, basit bir For-Each , iş hacminde 3 kat daha iyi ve Java 8 Stream ile karşılaştırıldığında hata puanında daha az.
Daha yüksek verim, daha iyi performans
Function<? super T, ?>
, değilFunction<? super T, Object>
. Ayrıca, sıralı paralel akış için bu çözeltinin hangi nesnenin çıkarılacağını (normalden farklı olarakdistinct()
) garanti etmediğine dikkat edilmelidir . Ayrıca sıralı akışlar için CHM kullanımında ek yük vardır (bu, nosid çözeltisinde yoktur). Son olarak bu çözümfilter
, JavaDoc'da belirtildiği gibi yüklemin vatansız olması gereken yöntem sözleşmesini ihlal etmektedir . Yine de iptal edildi.