เมื่อใดควรเป็นคลาสที่สามารถเปรียบเทียบได้และ / หรือเครื่องมือเปรียบเทียบ


138

ฉันได้เห็นการเรียนซึ่งใช้ทั้งเทียบเคียงและเปรียบเทียบ สิ่งนี้หมายความว่า? ทำไมฉันถึงต้องใช้อันเดียวกัน?


18
คุณอ่าน javadoc กับพวกเขาหรือไม่? มันอธิบายความแตกต่างค่อนข้างชัดเจน
skaffman

1
สิ่งที่เทียบเคียงและเปรียบเทียบและเมื่อใดที่จะใช้เปรียบเทียบและเปรียบเทียบ หากต้องการทราบว่าสิ่งเหล่านี้อ่านลิงค์นี้ สิ่งนี้จะช่วยให้คุณเข้าใจพฤติกรรมและการใช้งานของพวกเขา http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
RockStar

6
นี่เป็นคำถามที่ดีกับคำตอบที่ดีและมีวัตถุประสงค์ ฉันผิดหวังที่มันปิด
รัสเซลซิลวา

3
คำถามอื่น ๆเกี่ยวกับ StackOverflow อ้างถึงคำถามนี้ว่า "แตกต่างกันอย่างไรระหว่างคำถามเปรียบเทียบและเปรียบเทียบ" ทำไมจึงถูกทำเครื่องหมายว่า "ไม่สร้างสรรค์" ในฐานะที่เป็น Java Newbie นี่เป็นคำถามที่มีประโยชน์มาก!
Pete

คำตอบ:


241

ข้อความด้านล่างมาจากComparator vs Comparable

เทียบเคียง

วัตถุที่เปรียบเทียบนั้นสามารถเปรียบเทียบตัวเองกับวัตถุอื่นได้ คลาสเองต้องใช้java.lang.Comparableอินเตอร์เฟสเพื่อให้สามารถเปรียบเทียบอินสแตนซ์ของมันได้

เปรียบเทียบ

วัตถุตัวเปรียบเทียบสามารถเปรียบเทียบวัตถุสองชนิดที่แตกต่างกันได้ คลาสไม่ได้ทำการเปรียบเทียบอินสแตนซ์ของมัน แต่เป็นอินสแตนซ์ของคลาสอื่น คลาสตัวเปรียบเทียบนี้ต้องใช้java.util.Comparatorอินเตอร์เฟส


สำหรับคำอธิบายโดยละเอียดเกี่ยวกับการใช้ทั้ง Comparator และ Comparable: sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings

2
อีกบทความที่ดี: codecramp.com/java-comparable-vs-comparator
EMM

@ mel3kings - ไม่สามารถเข้าถึงลิงก์ได้อีก
Gaurav

152

การนำไปใช้Comparableหมายถึง " ฉันสามารถเปรียบเทียบตัวเองกับวัตถุอื่น " ซึ่งโดยทั่วไปจะมีประโยชน์เมื่อมีการเปรียบเทียบค่าเริ่มต้นตามธรรมชาติ

การนำไปใช้Comparatorหมายถึง " ฉันสามารถเปรียบเทียบวัตถุสองชิ้นอื่น ๆ ได้ " ซึ่งโดยทั่วไปจะเป็นประโยชน์เมื่อมีหลายวิธีในการเปรียบเทียบสองอินสแตนซ์ของประเภท - เช่นคุณสามารถเปรียบเทียบบุคคลตามอายุชื่อ ฯลฯ


1
สวัสดี skeet คุณกรุณาส่งรหัสโดยใช้การเปรียบเทียบและเปรียบเทียบ
Mdhar9e

5
@ mdhar9e: มีตัวอย่างมากมายรอบตัว - ถ้าคุณพบว่ามันยากที่จะแปลพวกเขาเป็นสถานการณ์เฉพาะของคุณโปรดให้ข้อมูลเพิ่มเติมในคำถามใหม่
Jon Skeet

2
@alireza: ฉันได้รับตัวอย่างในวรรคสองแล้ว: โดยมีเครื่องมือเปรียบเทียบที่แตกต่างกันคุณสามารถเรียงลำดับคอลเลกชันเดียวกัน (คน) โดยคุณสมบัติที่แตกต่างกัน (อายุชื่อ ฯลฯ ) คุณไม่สามารถทำได้เพียงแค่Personใช้งานComparableเพราะคุณไม่สามารถเปลี่ยนวิธีการเปรียบเทียบคนสองคน
Jon Skeet

1
@feelgoodandprogramming: ไม่มีผู้ที่มีการจัดเรียงที่แตกต่างกันขั้นตอนวิธีการ นอกจากนี้อาจเกิดขึ้นสามชิ้นของรหัสที่นี่ในสามชั้นเรียนที่แตกต่างกัน: 1) Personนิติบุคคลที่ตัวเองเช่น 2) ตัวเปรียบเทียบเช่นPersonAgeComparatorซึ่งสามารถเปรียบเทียบเอนทิตีที่แตกต่างกันสองรายการและตัดสินใจว่าควรจะเรียงลำดับใดเป็นอันดับแรก 3) รหัสการเรียงลำดับซึ่งใช้การรวบรวมเอนทิตีและตัวเปรียบเทียบและเรียงลำดับการรวบรวมนั้นโดยใช้ตัวเปรียบเทียบเพื่อกำหนดลำดับ
Jon Skeet

2
@RishiKeshPathak: มันเป็นมากกว่าที่คุณใช้ Comparable หากมีสิ่งเดียวที่ชัดเจนที่จะเปรียบเทียบ และจากนั้นคุณก็สามารถเขียนเครื่องมือเปรียบเทียบ หากคุณมีโปรแกรมที่แตกต่างกันสองโปรแกรมที่ใช้คลาสเดียวกันและอีกโปรแกรมหนึ่งต้องการเรียงลำดับตามอายุเพียงอย่างเดียวและอีกรายการหนึ่งโดยใช้ชื่ออย่างน้อยหนึ่งรายการจะต้องใช้ Comparator
Jon Skeet

38

Comparable ให้คลาสใช้การเปรียบเทียบของตัวเอง:

  • มันอยู่ในชั้นเรียนเดียวกัน (มักเป็นข้อได้เปรียบ)
  • มีเพียงการใช้งานเพียงครั้งเดียว (ดังนั้นคุณจึงไม่สามารถใช้งานได้หากคุณต้องการสองกรณีที่แตกต่างกัน)

โดยการเปรียบเทียบ Comparator เป็นการเปรียบเทียบภายนอก:

  • มันมักจะอยู่ในอินสแตนซ์ที่ไม่ซ้ำกัน (ทั้งในชั้นเรียนเดียวกันหรือในที่อื่น)
  • คุณตั้งชื่อการใช้งานแต่ละวิธีด้วยวิธีที่คุณต้องการเรียงลำดับสิ่งต่าง ๆ
  • คุณสามารถจัดเตรียมเครื่องมือเปรียบเทียบสำหรับคลาสที่คุณไม่ได้ควบคุม
  • การนำไปใช้นั้นสามารถใช้งานได้แม้ว่าวัตถุแรกจะเป็นโมฆะ

ทั้งในการใช้งานคุณยังสามารถเลือกสิ่งที่คุณต้องการที่จะเปรียบเทียบ ด้วยยาชื่อสามัญคุณสามารถประกาศได้และตรวจสอบได้ในเวลารวบรวม สิ่งนี้ช่วยเพิ่มความปลอดภัย แต่ก็เป็นความท้าทายในการกำหนดค่าที่เหมาะสม

ตามแนวทางฉันมักจะใช้คลาสทั่วไปหรืออินเตอร์เฟสที่วัตถุนั้นสามารถนำมาเปรียบเทียบได้ในทุกกรณีการใช้งานที่ฉันนึกภาพ ... ไม่ได้นิยามที่แม่นยำมาก ๆ ! :-(

  • Comparable<Object>ช่วยให้คุณสามารถใช้มันในทุกรหัสในเวลาคอมไพล์ (ซึ่งดีถ้าจำเป็นหรือไม่ดีถ้าไม่ใช่และคุณสูญเสียข้อผิดพลาดในการคอมไพล์เวลา) การติดตั้งใช้งานของคุณต้องรับมือกับวัตถุและใช้งานได้ตามต้องการ แต่ก็มีประสิทธิภาพ
  • Comparable<Itself> เข้มงวดมากในทางตรงกันข้าม

ตลกเมื่อคุณคลาสย่อยตัวเองเป็นคลาสย่อยคลาสย่อยจะต้องสามารถเปรียบเทียบและมีประสิทธิภาพเกี่ยวกับมัน (หรือมันจะทำลายหลักการ Liskov และให้ข้อผิดพลาดรันไทม์)


20

java.lang.Comparable

  1. ในการใช้Comparableส่วนต่อประสานคลาสจะต้องใช้วิธีการเดียวcompareTo()

    int a.compareTo(b)

  2. คุณต้องแก้ไขคลาสที่มีอินสแตนซ์ที่คุณต้องการเรียงลำดับ เพื่อให้สามารถสร้างลำดับการเรียงลำดับได้หนึ่งคลาสต่อหนึ่งคลาส

java.util.Comparator

  1. ในการใช้ส่วนต่อประสาน Comparator คลาสจะต้องใช้วิธีการเดียว compare()

    int compare (a,b)

  2. คุณสร้างคลาสแยกจากคลาสที่มีอินสแตนซ์ที่คุณต้องการเรียงลำดับ เพื่อให้สามารถสร้างลำดับการเรียงได้หลายคลาสต่อคลาส

14

Comparable ใช้สำหรับจัดเตรียมการสั่งซื้อเริ่มต้นบนวัตถุข้อมูลตัวอย่างเช่นถ้าวัตถุข้อมูลมีลำดับธรรมชาติ

Comparatorหมายถึงการสั่งซื้อของตัวเองสำหรับการใช้งานที่เฉพาะเจาะจง


8

Comparableมักเป็นที่ต้องการ แต่บางครั้งคลาสก็ใช้งานอยู่Comparableแต่คุณต้องการเรียงลำดับในคุณสมบัติอื่น Comparatorแล้วคุณจะบังคับให้ใช้

บางคลาสจัดเตรียมComparatorsไว้สำหรับกรณีทั่วไป เช่นStrings โดยกรณีค่าเริ่มต้นเมื่อเรียงลำดับ แต่ยังคงเรียกว่าComparatorCASE_INSENSITIVE_ORDER


7
ฉันไม่แน่ใจว่าฉันเห็นด้วยกับการเปรียบเทียบเป็นที่ต้องการ วัตถุบางอย่างมีความรู้สึกเป็นธรรมชาติลำดับ - กล่าวคือตัวเลขในทุกรูปแบบ: จำนวนธรรมชาติจำนวนจริงวันที่ ฯลฯ แต่แม้แต่วัตถุดั้งเดิมอื่น ๆ ที่ค่อนข้างเหมือนสายอักขระไม่มีคำสั่งที่ใช้ในระดับสากล ในกรณีของวัตถุที่ซับซ้อนมากขึ้นเช่นเอนทิตีจากโมเดลโดเมนของแอปพลิเคชันการใช้การเปรียบเทียบนั้นมักจะเป็นข้อผิดพลาด คุณสมบัติหลายอย่างของพวกเขาทำให้มันยากเกินกว่าที่จะคาดการณ์ได้ว่าคำสั่งซื้อใดที่ต้องการบ่อยที่สุด
erickson

6

นี่คือความแตกต่างเล็กน้อยระหว่าง Comparator และ Comparable ที่ฉันพบบนเว็บ:

  1. หากคุณเห็นความแตกต่างเชิงตรรกะระหว่างสองสิ่งนี้คือ Comparator ใน Java จะเปรียบเทียบวัตถุสองอย่างที่มีให้กับเขาในขณะที่ส่วนต่อประสานที่เปรียบเทียบได้จะเปรียบเทียบการอ้างอิง "นี่" กับวัตถุที่ระบุ

  2. เปรียบได้ใน Java ใช้ในการดำเนินการสั่งซื้อวัตถุตามธรรมชาติ ใน Java API String คลาส Date และ wrapper ใช้อินเตอร์เฟสที่เปรียบเทียบได้

  3. ถ้าคลาสใดใช้อินเตอร์เฟสที่สามารถเปรียบเทียบได้ใน Java ดังนั้นการรวบรวมของวัตถุนั้น List หรือ Array สามารถเรียงลำดับโดยอัตโนมัติโดยใช้ Collections.sort () หรือ Array.sort () วิธีการและวัตถุจะถูกเรียงตามลำดับธรรมชาติที่กำหนดโดยวิธี CompareTo

  4. วัตถุที่ใช้ Comparable ใน Java สามารถใช้เป็นกุญแจในแผนที่เรียงหรือองค์ประกอบในชุดเรียงเช่น TreeSet โดยไม่ต้องระบุ Comparator ใด ๆ

ไซต์: วิธีใช้เครื่องมือเปรียบเทียบและเปรียบเทียบได้ใน Java ด้วยตัวอย่าง

อ่านเพิ่มเติม: จะใช้ Comparator และ Comparable ใน Java ได้อย่างไร ด้วยตัวอย่าง


5

Comparableสำหรับวัตถุที่มีการจัดเรียงแบบเป็นธรรมชาติ วัตถุเองรู้วิธีการสั่งซื้อ
Comparatorสำหรับวัตถุที่ไม่มีลำดับตามธรรมชาติหรือเมื่อคุณต้องการใช้ลำดับที่แตกต่างกัน


4

ความแตกต่างระหว่าง Comparator และ Interfaceable

Comparable ใช้เพื่อเปรียบเทียบตัวเองโดยใช้กับวัตถุอื่น

Comparator ใช้ในการเปรียบเทียบสองประเภทข้อมูลเป็นวัตถุ


2

หากคุณเห็นความแตกต่างทางตรรกะระหว่างสองสิ่งนี้อยู่Comparatorใน Java เปรียบเทียบสองวัตถุที่จัดเตรียมให้เขาในขณะที่Comparableส่วนต่อประสานจะเปรียบเทียบการอ้างอิง "นี้" กับวัตถุที่ระบุ

Comparableในจาวาถูกนำมาใช้เพื่อดำเนินการตามลำดับของวัตถุ ใน Java API String คลาส Date และ wrapper ใช้Comparableอินเตอร์เฟส

หากคลาสใดใช้Comparableอินเตอร์เฟสใน Java ดังนั้นการรวบรวมของวัตถุนั้นListหรือArrayสามารถเรียงลำดับโดยอัตโนมัติโดยใช้Collections.sort()หรือArray.sort()วิธีการและวัตถุจะถูกจัดเรียงตามลำดับธรรมชาติที่กำหนดโดยcompareToวิธีการ

วัตถุที่ใช้Comparableใน Java สามารถใช้เป็นกุญแจในแผนที่เรียงหรือองค์ประกอบในชุดเรียงตัวอย่างโดยไม่ต้องระบุใด ๆTreeSetComparator


0

lib คำอธิบายประกอบของฉันสำหรับการใช้ Comparable และ Comparator:

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);         
    }  
} 

คลิกลิงก์เพื่อดูตัวอย่างเพิ่มเติม compamatic


3
ยินดีต้อนรับสู่ stackoverflow คำถามนี้เก่าและมีคำตอบแล้ว โดยปกติแล้วจะเป็นการดีที่สุดที่จะไม่กู้คืนเธรดเก่าเว้นแต่ว่าคำตอบของคุณจะช่วยให้มีสิ่งใหม่หรือแตกต่างจากคำตอบก่อนหน้า
oers
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.