Mặc dù câu trả lời được đánh giá cao nhất là câu trả lời hoàn toàn tốt nhất cho Java 8, nhưng đồng thời nó lại hoàn toàn kém nhất về hiệu năng. Nếu bạn thực sự muốn một ứng dụng hiệu suất thấp, thì hãy tiếp tục và sử dụng nó. Yêu cầu đơn giản để trích xuất một nhóm Tên người duy nhất sẽ đạt được chỉ bằng "Dành cho mỗi" và "Tập hợp". Mọi thứ thậm chí còn tồi tệ hơn nếu danh sách có kích thước trên 10.
Hãy xem xét bạn có một bộ sưu tập gồm 20 Đối tượng, như thế này:
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"));
Nơi bạn phản đối SimpleEvent
trông như thế này:
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;
}
}
Và để kiểm tra, bạn có mã JMH như thế này, (Xin lưu ý, tôi đang sử dụng cùng một Dự báo riêng biệt được đề cập trong câu trả lời được chấp nhận):
@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();
}
Sau đó, bạn sẽ có kết quả Điểm chuẩn như thế này:
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
Và như bạn có thể thấy, For-Each đơn giản tốt hơn thông lượng gấp 3 lần và ít hơn về điểm số lỗi so với Java 8 Stream.
Cao hơn thông, tốt hơn hiệu suất
Function<? super T, ?>
, khôngFunction<? super T, Object>
. Ngoài ra, cần lưu ý rằng đối với luồng song song có trật tự, giải pháp này không đảm bảo đối tượng nào sẽ được trích xuất (không giống như bình thườngdistinct()
). Ngoài ra, đối với các luồng liên tiếp có thêm chi phí sử dụng CHM (không có trong giải pháp @nosid). Cuối cùng, giải pháp này vi phạm hợp đồng củafilter
phương thức mà vị ngữ phải không trạng thái như đã nêu trong JavaDoc. Tuy nhiên được nâng cấp.