Khi nào một lớp nên được so sánh và / hoặc so sánh?


138

Tôi đã thấy các lớp thực hiện cả So sánhSo sánh . Điều đó có nghĩa là gì? Tại sao tôi lại dùng cái này?


18
Bạn đã đọc javadoc trên chúng? Nó mô tả sự khác biệt khá rõ ràng.
skaffman

1
Thế nào là so sánh và so sánh và khi nào nên sử dụng so sánh và so sánh. Để biết những điều này đọc liên kết này. điều này sẽ giúp bạn hiểu hành vi và cách sử dụng của họ. http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
Rockstar

6
Đây là một câu hỏi hay với một câu trả lời tốt, khách quan. Tôi mất tinh thần rằng nó được đóng lại.
Russell Silva

3
Các câu hỏi khác trên StackOverflow đề cập đến điều này là câu hỏi "Sự khác biệt giữa so sánh và so sánh" dứt khoát. Tại sao nó được đánh dấu là "không mang tính xây dựng"? Là một Newbie Java, đây là một câu hỏi rất hữu ích!
Pete

Câu trả lời:


241

Văn bản dưới đây đến từ So sánh so với so sánh

So sánh

Một đối tượng có thể so sánh có khả năng so sánh chính nó với một đối tượng khác. Bản thân lớp phải thực hiện java.lang.Comparablegiao diện để có thể so sánh các thể hiện của nó.

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 này không so sánh các thể hiện của nó, nhưng một số thể hiện của lớp khác. Lớp so sánh này phải thực hiện java.util.Comparatorgiao diện.


để được giải thích chi tiết về việc sử dụng cả So sánh và so sánh: sysdotoutdotprint.com/index.php/2017/03/28/ trên
mel3kings 28/03/2017

2
Một bài viết hay khác: codecramp.com/java-comparable-vs-comparator
EMM

@ mel3kings - Liên kết không thể truy cập nhiều hơn.
Gaurav

152

Triển khai Comparablecó nghĩa là " Tôi có thể so sánh bản thân mình với một đối tượng khác. " Điều này thường hữu ích khi có một so sánh mặc định tự nhiên duy nhất.

Việc triển khai Comparatorcó nghĩa là " Tôi có thể so sánh hai đối tượng khác. " Điều này thường hữu ích khi có nhiều cách so sánh hai trường hợp của một loại - ví dụ: bạn có thể so sánh mọi người theo độ tuổi, tên, v.v.


1
Xin chào, bạn có thể bỏ mã bằng cách sử dụng so sánh và so sánh.
Mdhar9e

5
@ mdhar9e: Có rất nhiều ví dụ xung quanh - nếu bạn cảm thấy khó dịch chúng sang kịch bản cụ thể của mình, vui lòng cung cấp thêm thông tin trong một câu hỏi mới.
Jon Skeet

2
@alireza: Tôi đã đưa ra một ví dụ trong đoạn thứ hai: bằng cách có các bộ so sánh khác nhau, bạn có thể sắp xếp cùng một bộ sưu tập (người) theo các thuộc tính khác nhau (tuổi, tên, v.v.). Bạn không thể làm điều đó chỉ bằng cách Personthực hiện Comparable, bởi vì sau đó bạn không thể thay đổi cách so sánh hai người.
Jon Skeet

1
@feelgoodandprogramming: Không, đó là những thuật toán sắp xếp khác nhau . Có khả năng có ba đoạn mã ở đây, trong ba lớp khác nhau: 1) Bản thân thực thể, vd Person. 2) Bộ so sánh, ví dụ PersonAgeComparatorcó thể so sánh hai thực thể khác nhau và quyết định cái nào sẽ đến trước theo thứ tự sắp xếp cụ thể đó. 3) Mã sắp xếp, lấy một tập hợp các thực thể và một bộ so sánh và sắp xếp bộ sưu tập đó bằng cách sử dụng bộ so sánh để xác định thứ tự.
Jon Skeet

2
@RishiKeshPathak: Vâng, nhiều hơn nữa là bạn sử dụng So sánh nếu chỉ có một điều rõ ràng duy nhất để so sánh. Và thậm chí sau đó bạn chỉ có thể viết một So sánh. Nếu bạn có hai chương trình khác nhau sử dụng cùng một lớp và một chương trình muốn sắp xếp theo độ tuổi và chương trình kia chỉ bằng tên, ít nhất một trong số chúng sẽ cần sử dụng Trình so sánh.
Jon Skeet

38

So sánh cho phép một lớp thực hiện so sánh của riêng mình:

  • đó là trong cùng một lớp (nó thường là một lợi thế)
  • chỉ có thể có một triển khai (vì vậy bạn không thể sử dụng nếu bạn muốn hai trường hợp khác nhau)

Để so sánh, so sánh là một so sánh bên ngoài:

  • nó thường ở một thể hiện duy nhất (trong cùng một lớp hoặc ở một nơi khác)
  • bạn đặt tên cho mỗi cách thực hiện theo cách bạn muốn sắp xếp mọi thứ
  • bạn có thể cung cấp bộ so sánh cho các lớp mà bạn không kiểm soát
  • việc thực hiện có thể sử dụng được ngay cả khi đối tượng đầu tiên là null

Trong cả hai triển khai, bạn vẫn có thể chọn những gì bạn muốn được so sánh . Với generic, bạn có thể khai báo như vậy và kiểm tra nó tại thời gian biên dịch. Điều này cải thiện sự an toàn, nhưng nó cũng là một thách thức để xác định giá trị phù hợp.

Theo hướng dẫn, tôi thường sử dụng lớp hoặc giao diện chung nhất mà đối tượng có thể so sánh được, trong tất cả các trường hợp sử dụng tôi hình dung ... Mặc dù không phải là một định nghĩa rất chính xác! :-(

  • Comparable<Object>cho phép bạn sử dụng nó trong tất cả các mã tại thời gian biên dịch (tốt nếu cần hoặc xấu nếu không và bạn mất lỗi thời gian biên dịch); việc thực hiện của bạn phải đối phó với các đối tượng và thực hiện khi cần thiết nhưng theo một cách mạnh mẽ.
  • Comparable<Itself> là rất nghiêm ngặt trái lại.

Thật buồn cười, khi bạn phân lớp chính nó thành Lớp con, Lớp con cũng phải được so sánh và mạnh mẽ về nó (hoặc nó sẽ phá vỡ Nguyên tắc Liskov và cung cấp cho bạn lỗi thời gian chạy).


20

java.lang.Comparable

  1. Để thực hiện Comparablegiao diện, lớp phải thực hiện một phương thức duy nhấtcompareTo()

    int a.compareTo(b)

  2. Bạn phải sửa đổi lớp mà cá thể bạn muốn sắp xếp. Vì vậy, chỉ có một chuỗi sắp xếp có thể được tạo ra cho mỗi lớp.

java.util.Comparator

  1. Để thực hiện giao diện Trình so sánh, lớp phải thực hiện một phương thức duy nhất compare()

    int compare (a,b)

  2. Bạn xây dựng một lớp riêng biệt với lớp mà bạn muốn sắp xếp. Vì vậy, nhiều chuỗi sắp xếp có thể được tạo ra cho mỗi lớp.

14

Comparable là để cung cấp một thứ tự mặc định trên các đối tượng dữ liệu, ví dụ nếu các đối tượng dữ liệu có thứ tự tự nhiên.

A Comparatorđại diện cho chính đơn đặt hàng cho một mục đích sử dụng cụ thể.


8

Comparablethường được ưa thích. Nhưng đôi khi một lớp đã thực hiện Comparable, nhưng bạn muốn sắp xếp trên một thuộc tính khác. Sau đó, bạn buộc phải sử dụng a Comparator.

Một số lớp học thực sự cung cấp Comparatorscho các trường hợp phổ biến; ví dụ, Strings theo mặc định phân biệt chữ hoa chữ thường khi được sắp xếp, nhưng cũng có một lệnh Comparatorgọi tĩnh CASE_INSENSITIVE_ORDER.


7
Tôi không chắc chắn tôi đồng ý với So sánh được ưa thích. Một số đối tượng có ý thức mạnh mẽ về trật tự tự nhiên, cụ thể là các số, dưới mọi hình thức: số tự nhiên, số thực, ngày tháng, v.v. Nhưng ngay cả các đối tượng tương đối nguyên thủy khác như chuỗi ký tự cũng không có thứ tự áp dụng chung. Trong trường hợp các đối tượng phức tạp hơn như một thực thể từ mô hình miền ứng dụng, việc triển khai So sánh thường là một sai lầm. Nhiều tính chất của chúng làm cho quá khó để dự đoán thứ tự nào sẽ được muốn thường xuyên nhất.
erickson

6

Dưới đây là một vài điểm khác biệt giữa So sánh và So sánh tôi tìm thấy trên web:

  1. Nếu bạn thấy sự khác biệt logic giữa hai cái này là So sánh trong Java thì so sánh hai đối tượng được cung cấp cho anh ta, trong khi giao diện so sánh so sánh tham chiếu "này" với đối tượng được chỉ định.

  2. So sánh trong Java được sử dụng để thực hiện thứ tự tự nhiên của đối tượng. Trong Chuỗi API Java, các lớp Ngày và trình bao bọc thực hiện giao diện So sánh.

  3. Nếu bất kỳ lớp nào thực hiện giao diện so sánh trong Java thì bộ sưu tập của đối tượng đó có thể được sắp xếp tự động bằng cách sử dụng phương thức Collections.sort () hoặc Array.sort () theo thứ tự tự nhiên được xác định theo phương thức so sánh.

  4. Các đối tượng triển khai Có thể so sánh trong Java có thể được sử dụng làm khóa trong bản đồ được sắp xếp hoặc các phần tử trong một tập hợp được sắp xếp, ví dụ TreeSet, mà không chỉ định bất kỳ Trình so sánh nào.

trang web: Làm thế nào để sử dụng Trình so sánh và So sánh trong Java? Ví dụ

Đọc thêm: Làm thế nào để sử dụng Trình so sánh và So sánh trong Java? Ví dụ


5

Comparablelà cho các đối tượng với một trật tự tự nhiên. Các đối tượng tự biết làm thế nào để được ra lệnh.
Comparatordành cho các đối tượng không có thứ tự tự nhiên hoặc khi bạn muốn sử dụng một thứ tự khác.


4

Sự khác biệt giữa giao diện so sánh và so sánh

Comparable được sử dụng để so sánh chính nó bằng cách sử dụng với một đối tượng khác.

Comparator được sử dụng để so sánh hai kiểu dữ liệu là các đối tượng.


2

Nếu bạn thấy sự khác biệt logic giữa hai cái này là Comparatortrong Java, hãy so sánh hai đối tượng được cung cấp cho anh ta, trong khi Comparablegiao diện so sánh tham chiếu "này" với đối tượng được chỉ định.

Comparabletrong Java được sử dụng để thực hiện thứ tự tự nhiên của đối tượng. Trong Chuỗi API Java, các lớp Date và Wrapper triển khai Comparablegiao diện.

Nếu bất kỳ lớp nào thực hiện Comparablegiao diện trong Java thì bộ sưu tập của đối tượng đó Listhoặc Arraycó thể được sắp xếp tự động bằng cách sử dụng Collections.sort()hoặc Array.sort()phương thức và đối tượng sẽ được sắp xếp dựa trên thứ tự tự nhiên được xác định bởi compareTophương thức.

Các đối tượng triển khai Comparabletrong Java có thể được sử dụng làm khóa trong bản đồ được sắp xếp hoặc các phần tử trong một tập hợp được sắp xếp chẳng hạn TreeSet, mà không chỉ định bất kỳ Comparator.


0

Lib chú thích của tôi để thực hiện so sánh và so sánh:

public class Person implements Comparable<Person> {         
    private String firstName;  
    private String lastName;         
    private int age;         
    private char gentle;         

    @Override         
    @CompaProperties({ @CompaProperty(property = "lastName"),              
        @CompaProperty(property = "age",  order = Order.DSC) })           
    public int compareTo(Person person) {                 
        return Compamatic.doComparasion(this, person);         
    }  
} 

Nhấp vào liên kết để xem thêm ví dụ. tính toán


3
Chào mừng đến với stackoverflow. Câu hỏi này đã cũ và đã được trả lời. Thông thường, tốt nhất là không phục hồi các chủ đề cũ trừ khi phản hồi của bạn đóng góp một cái gì đó mới hoặc khác biệt đáng kể so với các câu trả lời trước đó.
oers
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.