Alors que la réponse la plus élevée est la meilleure réponse à Java 8, elle est en même temps absolument pire en termes de performances. Si vous voulez vraiment une mauvaise application peu performante, allez-y et utilisez-la. La simple exigence d'extraction d'un ensemble unique de noms de personne doit être obtenue par de simples «pour chacun» et un «ensemble». Les choses empirent encore si la liste dépasse 10.
Considérez que vous avez une collection de 20 objets, comme ceci:
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"));
Où vous vous opposez SimpleEvent
ressemble à ceci:
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;
}
}
Et pour tester, vous avez un code JMH comme celui-ci, (veuillez noter que j'utilise le même prédicat distinctByKey mentionné dans la réponse acceptée):
@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();
}
Ensuite, vous aurez des résultats de référence comme celui-ci:
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
Et comme vous pouvez le voir, un simple For-Each a un débit 3 fois supérieur et un score d'erreur inférieur à Java 8 Stream.
Plus le débit est élevé, meilleures sont les performances
Function<? super T, ?>
nonFunction<? super T, Object>
. Il convient également de noter que pour le flux parallèle ordonné, cette solution ne garantit pas quel objet sera extrait (contrairement à la normaledistinct()
). De plus, pour les flux séquentiels, il y a une surcharge supplémentaire sur l'utilisation de CHM (qui est absent dans la solution @nosid). Enfin, cette solution viole le contrat defilter
méthode dont le prédicat doit être sans état comme indiqué dans JavaDoc. Néanmoins voté.