Sự khác biệt giữa Java's compare()và compareTo()các phương thức là gì? Những phương pháp đó có đưa ra câu trả lời giống nhau không?
Sự khác biệt giữa Java's compare()và compareTo()các phương thức là gì? Những phương pháp đó có đưa ra câu trả lời giống nhau không?
Câu trả lời:
Từ JavaNotes :
a.compareTo(b):
Giao diện có thể so sánh : So sánh các giá trị và trả về một int cho biết các giá trị được so sánh nhỏ hơn, bằng hay lớn hơn.
Nếu các đối tượng lớp của bạn có thứ tự tự nhiên , hãy triển khai Comparable<T>giao diện và định nghĩa phương thức này. Tất cả các lớp Java có một trật tự tự nhiên thực hiện Comparable<T>- Ví dụ: String, lớp wrapper ,BigInteger
compare(a, b):
Giao diện so sánh: So sánh giá trị của hai đối tượng. Điều này được triển khai như một phần của Comparator<T>giao diện và cách sử dụng điển hình là xác định một hoặc nhiều lớp tiện ích nhỏ thực hiện điều này, để chuyển cho các phương thức như sort()hoặc để sử dụng bằng cách sắp xếp các cấu trúc dữ liệu như TreeMapvàTreeSet . Bạn có thể muốn tạo một đối tượng Comparator để làm như sau:
sort()phương thức.Nếu các đối tượng lớp của bạn có một thứ tự sắp xếp tự nhiên, bạn có thể không cần so sánh ().
Tổng hợp từ http://www.digizol.com/2008/07/java-sorting-comparator-vs-comp so sánh.html
Có
thể so sánh Một đối tượng có thể so sánh được có khả năng so sánh chính nó với một đối tượng khác.
Bộ so sánh
Một đối tượng so sánh có khả năng so sánh hai đối tượng khác nhau. Lớp không so sánh các cá thể của nó, mà là một số cá thể của lớp khác.
Các ngữ cảnh trường hợp sử dụng:
Giao diện so sánh
Các bằng phương pháp và ==và != các nhà khai thác thử nghiệm cho sự bình đẳng / bất bình đẳng, nhưng không cung cấp một cách để kiểm tra cho các giá trị tương đối .
Một số lớp (ví dụ: Chuỗi và các lớp khác có thứ tự tự nhiên) triển khai Comparable<T>giao diện, định nghĩa một compareTo()phương thức.
Bạn sẽ muốn triển khai Comparable<T>trong lớp của mình nếu bạn muốn sử dụng nó với Collections.sort()hoặc Arrays.sort()các phương thức.
Xác định đối tượng Bộ so sánh
Bạn có thể tạo Bộ so sánh để sắp xếp bất kỳ cách nào tùy ý cho bất kỳ lớp nào .
Ví dụ, Stringlớp định nghĩa bộ CASE_INSENSITIVE_ORDERso sánh .
Sự khác biệt giữa hai cách tiếp cận có thể được liên kết với khái niệm về:
Bộ sưu tập có thứ tự :
Khi một Bộ sưu tập được đặt hàng, điều đó có nghĩa là bạn có thể lặp lại bộ sưu tập theo một thứ tự cụ thể (không phải ngẫu nhiên) (a Hashtablekhông được sắp xếp theo thứ tự).
Bộ sưu tập có thứ tự tự nhiên không chỉ được sắp xếp theo thứ tự mà còn được sắp xếp . Xác định một trật tự tự nhiên có thể khó khăn! (như theo thứ tự Chuỗi tự nhiên ).
Một sự khác biệt khác, được chỉ ra bởi HaveAGuess trong các bình luận :
Comparable đang trong quá trình triển khai và không hiển thị từ giao diện, vì vậy khi sắp xếp, bạn không thực sự biết điều gì sẽ xảy ra. Comparator giúp bạn yên tâm rằng thứ tự sẽ được xác định rõ ràng. compareTo()là từ Comparablegiao diện.
compare() là từ Comparatorgiao diện.
Cả hai phương pháp đều làm điều tương tự, nhưng mỗi giao diện được sử dụng trong một ngữ cảnh hơi khác nhau.
Các tính năng tương đương giao diện được sử dụng để áp đặt một trật tự tự nhiên trên các đối tượng của lớp thực hiện. Các compareTo()phương pháp được gọi là phương pháp so sánh tự nhiên. Các sánh giao diện được sử dụng để áp đặt một tổng trật tự trên các đối tượng của lớp thực hiện. Để biết thêm thông tin, hãy xem các liên kết để biết chính xác thời điểm sử dụng từng giao diện.
Điểm giống nhau:
Cả hai đều là cách tùy chỉnh để so sánh hai đối tượng.
Cả hai đều trả về một intmô tả mối quan hệ giữa hai đối tượng.
Sự khác biệt:
Phương thức compare()là một phương thức mà bạn bắt buộc phải triển khai nếu bạn triển khai Comparatorgiao diện. Nó cho phép bạn chuyển hai đối tượng vào phương thức và nó trả về một intmô tả mối quan hệ của chúng.
Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);
Phương thức compareTo()là một phương thức mà bạn bắt buộc phải triển khai nếu bạn triển khai Comparablegiao diện. Nó cho phép một đối tượng được so sánh với các đối tượng cùng loại.
String s = "hi";
int result = s.compareTo("bye");
Tóm lại:
Về cơ bản chúng là hai cách khác nhau để so sánh mọi thứ.
Các phương pháp không nhất thiết phải đưa ra các câu trả lời giống nhau. Điều đó phụ thuộc vào đối tượng / lớp nào bạn gọi chúng.
Nếu bạn đang triển khai các lớp của riêng mình mà bạn biết rằng bạn muốn so sánh ở một số giai đoạn, bạn có thể yêu cầu chúng triển khai giao diện So sánh và triển khai phương thức CompareTo () cho phù hợp.
Nếu bạn đang sử dụng một số lớp từ một API không triển khai giao diện Có thể so sánh, nhưng bạn vẫn muốn so sánh chúng. Tức là để phân loại. Bạn có thể tạo lớp của riêng mình để triển khai giao diện Bộ so sánh và trong phương thức so sánh () của nó, bạn triển khai logic.
Giao diện so sánh chứa một phương thức được gọi là phương thức compareTo(obj)chỉ nhận một đối số và nó tự so sánh với một thể hiện hoặc các đối tượng khác của cùng một lớp.
Giao diện so sánh chứa một phương thức được gọi là phương thức compare(obj1,obj2)nhận hai đối số và nó so sánh giá trị của hai đối tượng từ các lớp giống nhau hoặc khác nhau.
compareTo(T object)
đến từ giao diện java.lang.Comp so sánh được, được triển khai để so sánh đối tượng này với đối tượng khác để cung cấp giá trị int âm cho đối tượng này nhỏ hơn, 0 đối với bằng hoặc giá trị dương lớn hơn đối tượng kia. Đây là phương pháp so sánh thuận tiện hơn, nhưng phải được thực hiện trong mọi lớp bạn muốn so sánh.
compare(T obj1, T obj2)
đến từ giao diện java.util.Comparator, được triển khai trong một lớp riêng biệt để so sánh các đối tượng của lớp khác để cung cấp giá trị int âm cho đối tượng đầu tiên nhỏ hơn, 0 cho bằng hoặc giá trị dương cho lớn hơn đối tượng thứ hai. Nó là cần thiết khi bạn không thể tạo một lớp triển khai CompareTo () vì nó không thể sửa đổi. Nó cũng được sử dụng khi bạn muốn có nhiều cách khác nhau để so sánh các đối tượng, không chỉ một (chẳng hạn như theo tên hoặc tuổi).
Sử dụng Comparator, chúng ta có thể có n số logic so sánh được viết cho một lớp .
Ví dụ
Đối với một hạng xe
Chúng ta có thể có một lớp So sánh để so sánh dựa trên số kiểu xe. Chúng tôi cũng có thể có một lớp So sánh để so sánh dựa trên năm mẫu xe.
Hạng ô tô
public class Car {
int modelNo;
int modelYear;
public int getModelNo() {
return modelNo;
}
public void setModelNo(int modelNo) {
this.modelNo = modelNo;
}
public int getModelYear() {
return modelYear;
}
public void setModelYear(int modelYear) {
this.modelYear = modelYear;
}
}
Bộ so sánh số 1 dựa trên Mẫu số
public class CarModelNoCompartor implements Comparator<Car>{
public int compare(Car o1, Car o2) {
return o1.getModelNo() - o2.getModelNo();
}
}
Bộ so sánh số 2 dựa trên Năm mẫu
public class CarModelYearComparator implements Comparator<Car> {
public int compare(Car o1, Car o2) {
return o1.getModelYear() - o2.getModelYear();
}
}
Nhưng điều này không thể xảy ra với trường hợp So sánh giao diện .
Trong trường hợp của giao diện So sánh, chúng ta chỉ có thể có một logic trong phương thức CompareTo () .
Mối quan hệ của đối tượng có phương thức này và các cộng tác viên của nó là khác nhau.
compareTo()là một phương thức của giao diện Có thể so sánh , vì vậy nó được sử dụng để so sánh trường hợp NÀY với trường hợp khác.
compare()là một phương thức của interface Comparator , vì vậy nó được sử dụng để so sánh hai trường hợp khác nhau của một lớp khác với nhau.
Nếu bạn muốn, việc triển khai Comparablecó nghĩa là các thể hiện của lớp có thể được so sánh dễ dàng.
Việc thực thi Comparatorcó nghĩa là các cá thể phù hợp để so sánh các đối tượng khác nhau (của các lớp khác).
Sự khác biệt chính là trong việc sử dụng các giao diện:
So sánh được (trong đó có CompareTo ()) yêu cầu các đối tượng được so sánh (để sử dụng Sơ đồ cây hoặc để sắp xếp danh sách) để triển khai giao diện đó. Nhưng điều gì sẽ xảy ra nếu lớp không triển khai So sánh được và bạn không thể thay đổi nó vì nó là một phần của thư viện bên thứ ba? Sau đó, bạn phải triển khai Bộ so sánh, cách sử dụng này hơi kém thuận tiện hơn.
compareTo()được gọi trên một đối tượng, để so sánh nó với một đối tượng khác.
compare()được gọi trên một số đối tượng để so sánh hai đối tượng khác.
Sự khác biệt là nơi logic so sánh thực tế được xác định.
Khi bạn muốn sắp xếp một Danh sách bao gồm Foo đối tượng, lớp Foo phải triển khai giao diện So sánh được, vì cách sắp xếp của Danh sách đang sử dụng methode này.
Khi bạn muốn viết một lớp Util để so sánh hai lớp khác, bạn có thể triển khai lớp So sánh.
Tên bảng nhân viên , DoB, Lương
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 2/10/1998, 520
Các tính năng tương đương giao diện cho phép bạn sắp xếp một danh sách các đối tượng ví dụ như nhân viên với tham chiếu đến một lĩnh vực chính - ví dụ, bạn có thể sắp xếp theo tên hoặc bằng lương với CompareTo () phương pháp
emp1.getName().compareTo(emp2.getName())
Giao diện linh hoạt hơn cho các yêu cầu như vậy được cung cấp bởi giao diện Bộ so sánh , có phương thức duy nhất là so sánh ()
public interface Comparator<Employee> {
int compare(Employee obj1, Employee obj2);
}
Mã mẫu
public class NameComparator implements Comparator<Employee> {
public int compare(Employee e1, Employee e2) {
// some conditions here
return e1.getName().compareTo(e2.getName()); // returns 1 since (T)omas > (D)an
return e1.getSalary().compareTo(e2.getSalary()); // returns -1 since 400 > 300
}
}
Có một khía cạnh kỹ thuật cũng cần được nhấn mạnh. Giả sử bạn cần tham số hóa hành vi so sánh từ một lớp máy khách và bạn đang phân vân nên sử dụng Comparablehay Comparatorcho một phương thức như thế này:
class Pokemon {
int healthPoints;
int attackDamage;
public void battle (Comparable<Pokemon> comparable, Pokemon opponent) {
if (comparable.compareTo(opponent) > 0) { //comparable needs to, but cannot, access this.healthPoints for example
System.out.println("battle won");
} else {
System.out.println("battle lost");
}
}
}
comparablesẽ là lambda hoặc một đối tượng, và không có cách nào comparableđể truy cập vào các trường thisPokemon. (Trong lambda, thistham chiếu đến cá thể lớp ngoài trong phạm vi của lambda, như được định nghĩa trong văn bản chương trình.) Vì vậy, điều này không bay , và chúng ta phải sử dụng a Comparatorvới hai đối số.
Important Answar
String name;
int roll;
public int compare(Object obj1,Object obj2) { // For Comparator interface
return obj1.compareTo(obj1);
}
public int compareTo(Object obj1) { // For Comparable Interface
return obj1.compareTo(obj);
}
Ở đây trong return obj1.compareTo(obj1)hoặc return obj1.compareTo(obj)câu lệnh chỉ lấy Object; nguyên thủy không được phép. Ví dụ
name.compareTo(obj1.getName()) // Correct Statement.
Nhưng
roll.compareTo(obj1.getRoll())
// Wrong Statement Compile Time Error Because roll
// is not an Object Type, it is primitive type.
tên là Đối tượng chuỗi để nó hoạt động. Nếu bạn muốn sắp xếp số cuộn của sinh viên hơn sử dụng mã dưới đây.
public int compareTo(Object obj1) { // For Comparable Interface
Student s = (Student) obj1;
return rollno - s.getRollno();
}
hoặc là
public int compare(Object obj1,Object obj2) { // For Comparator interface
Student s1 = (Student) obj1;
Student s2 = (Student) obj2;
return s1.getRollno() - s2.getRollno();
}