Tôi đã xem xét sự khác biệt giữa Collections.sortvà list.sort, đặc biệt liên quan đến việc sử dụng các Comparatorphương thức tĩnh và liệu các kiểu tham số có được yêu cầu trong các biểu thức lambda hay không. Trước khi chúng ta bắt đầu, tôi biết tôi có thể sử dụng tham chiếu phương thức, ví dụ: Song::getTitleđể khắc phục sự cố của mình, nhưng truy vấn của tôi ở đây không phải là thứ tôi muốn sửa mà là thứ tôi muốn có câu trả lời, tức là tại sao trình biên dịch Java lại xử lý nó theo cách này .
Đây là phát hiện của tôi. Giả sử chúng ta có một ArrayListloại Song, với một số bài hát được thêm vào, có 3 phương thức lấy tiêu chuẩn:
ArrayList<Song> playlist1 = new ArrayList<Song>();
//add some new Song objects
playlist.addSong( new Song("Only Girl (In The World)", 235, "Rhianna") );
playlist.addSong( new Song("Thinking of Me", 206, "Olly Murs") );
playlist.addSong( new Song("Raise Your Glass", 202,"P!nk") );
Đây là lời gọi đến cả hai loại phương thức sắp xếp hoạt động, không vấn đề gì:
Collections.sort(playlist1,
Comparator.comparing(p1 -> p1.getTitle()));
playlist1.sort(
Comparator.comparing(p1 -> p1.getTitle()));
Ngay khi tôi bắt đầu xâu chuỗi thenComparing, những điều sau sẽ xảy ra:
Collections.sort(playlist1,
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
playlist1.sort(
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
tức là lỗi cú pháp vì nó không biết kiểu p1nữa. Vì vậy, để khắc phục điều này, tôi thêm kiểu Songvào tham số đầu tiên (so sánh):
Collections.sort(playlist1,
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
playlist1.sort(
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
Bây giờ đến phần KẾT NỐI. Đối với p laylist1.sort, tức là Danh sách, điều này giải quyết tất cả các lỗi biên dịch, cho cả hai lần thenComparinggọi sau . Tuy nhiên, đối với Collections.sort, nó giải quyết nó cho cái đầu tiên, nhưng không phải cái cuối cùng. Tôi đã thử nghiệm thêm một số cuộc gọi bổ sung vào thenComparingvà nó luôn hiển thị lỗi cho cuộc gọi cuối cùng, trừ khi tôi đặt (Song p1)tham số.
Bây giờ tôi đã tiếp tục kiểm tra điều này hơn nữa với việc tạo TreeSetvà sử dụng Objects.compare:
int x = Objects.compare(t1, t2,
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
Set<Song> set = new TreeSet<Song>(
Comparator.comparing((Song p1) -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
Điều tương tự cũng xảy ra như trong, đối với TreeSet, không có lỗi biên dịch nhưng đối Objects.comparevới cuộc gọi cuối cùng thenComparinghiển thị lỗi.
Bất cứ ai có thể vui lòng giải thích tại sao điều này đang xảy ra và cũng là lý do tại sao không cần phải sử dụng (Song p1)chút nào khi chỉ cần gọi phương thức so sánh (mà không cần thenComparinggọi thêm ).
Một truy vấn khác về cùng chủ đề là khi tôi thực hiện điều này với TreeSet:
Set<Song> set = new TreeSet<Song>(
Comparator.comparing(p1 -> p1.getTitle())
.thenComparing(p1 -> p1.getDuration())
.thenComparing(p1 -> p1.getArtist())
);
tức là loại bỏ kiểu Songkhỏi tham số lambda đầu tiên cho cuộc gọi phương thức so sánh, nó hiển thị lỗi cú pháp trong lệnh gọi so sánh và lệnh gọi đầu tiên thenComparingnhưng không đến lệnh gọi cuối cùng thenComparing- gần như ngược lại với những gì đang xảy ra ở trên! Trong khi đó, đối với tất cả 3 ví dụ khác tức là với Objects.compare, List.sortvà Collections.sortkhi tôi loại bỏ đầu tiên Songloại param nó show cú pháp lỗi cho tất cả các cuộc gọi.
Rất cám ơn trước.
Đã chỉnh sửa để bao gồm ảnh chụp màn hình các lỗi tôi đã nhận được trong Eclipse Kepler SR2, mà tôi đã tìm thấy kể từ đó là Eclipse cụ thể vì khi biên dịch bằng trình biên dịch java JDK8 trên dòng lệnh, nó biên dịch OK.
