User Tools

Site Tools


java:comparable

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:comparable [2020/02/25 07:57] gthanosjava:comparable [2020/03/15 18:30] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== Συγκρίνοντας αντικείμενα μεταξύ τους ====== ====== Συγκρίνοντας αντικείμενα μεταξύ τους ======
 +
 +===== Το interface java.lang.Comparable =====
  
 Συχνά προκύπτει η ανάγκη να ταξινομήσουμε αντικείμενα ή να εφαρμόσουμε δυαδική αναζήτηση πάνω σε ένα ήδη ταξινομημένο σύνολο. Προκειμένου να εφαρμόσουμε τους παραπάνω αλγορίθμους είναι αναγκαίο να μπορούμε να συγκρίνουμε αντικείμενα μεταξύ τους. Ας υποθέσουμε ότι έχουμε μια σειρά από αντικείμενα της κλάσης ''Rectangle'' τα οποία θέλουμε να ταξινομήσουμε όπως παρακάτω: Συχνά προκύπτει η ανάγκη να ταξινομήσουμε αντικείμενα ή να εφαρμόσουμε δυαδική αναζήτηση πάνω σε ένα ήδη ταξινομημένο σύνολο. Προκειμένου να εφαρμόσουμε τους παραπάνω αλγορίθμους είναι αναγκαίο να μπορούμε να συγκρίνουμε αντικείμενα μεταξύ τους. Ας υποθέσουμε ότι έχουμε μια σειρά από αντικείμενα της κλάσης ''Rectangle'' τα οποία θέλουμε να ταξινομήσουμε όπως παρακάτω:
Line 41: Line 43:
      
   public static void print_rectangles(Rectangle []rectangles) {   public static void print_rectangles(Rectangle []rectangles) {
 +    System.out.println("================");
     for(int i=0; i<rectangles.length; i++)     for(int i=0; i<rectangles.length; i++)
       System.out.println(i+". "+rectangles[i].toString());       System.out.println(i+". "+rectangles[i].toString());
Line 57: Line 60:
  
 Ο λόγος που συμβαίνει αυτό είναι ότι δεν υπάρχει τρόπος να συγκριθούν τα αντικείμενα τύπου ''Rectangle'' μεταξύ τους. Προκειμένου να επιτευχθεί η σύγκριση, η Java αναμένει η κλάση ''Rectangle'' να υλοποιεί το interface [[https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html|java.lang.Comparable]]. Το interface [[https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html|java.lang.Comparable]] απαιτεί να υλοποιήσετε τη μέθοδο ''int compareTo(Rectangle r)'', η οποία επιστρέφει:  Ο λόγος που συμβαίνει αυτό είναι ότι δεν υπάρχει τρόπος να συγκριθούν τα αντικείμενα τύπου ''Rectangle'' μεταξύ τους. Προκειμένου να επιτευχθεί η σύγκριση, η Java αναμένει η κλάση ''Rectangle'' να υλοποιεί το interface [[https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html|java.lang.Comparable]]. Το interface [[https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html|java.lang.Comparable]] απαιτεί να υλοποιήσετε τη μέθοδο ''int compareTo(Rectangle r)'', η οποία επιστρέφει: 
-  * **>0** έαν το τρέχον αντικείμενο είναι μεγαλύτερο από το ''r'',  +  * **> 0** έαν το τρέχον αντικείμενο είναι μεγαλύτερο από το ''r'',  
-  * **<0** εάν το τρέχον αντικείμενο είναι μικρότερο από το ''r''+  * **< 0** εάν το τρέχον αντικείμενο είναι μικρότερο από το ''r''
-  * **==0** εάν το τρέχον αντικείμενο είναι ίσο με το ''r''.+  * **== 0** εάν το τρέχον αντικείμενο είναι ίσο με το ''r''.
  
 Το κριτήριο μέσω του οποίου θα συγκρίνετε δύο αντικείμενα τύπου ''Rectangle'' δεν προσδιορίζεται. Ας υποθέσουμε ότι θέλουμε να κατατάξουμε τα αντικείμεμενα τύπου ''Rectangle'' με βάση το εμβαδό τους. Μπορούμε να γράψουμε τη συνάρτηση compareTo εντός της κλάση ''Rectangle'' ως εξής: Το κριτήριο μέσω του οποίου θα συγκρίνετε δύο αντικείμενα τύπου ''Rectangle'' δεν προσδιορίζεται. Ας υποθέσουμε ότι θέλουμε να κατατάξουμε τα αντικείμεμενα τύπου ''Rectangle'' με βάση το εμβαδό τους. Μπορούμε να γράψουμε τη συνάρτηση compareTo εντός της κλάση ''Rectangle'' ως εξής:
  
-</code java>+<code java>
   public int compareTo(Rectangle r) {   public int compareTo(Rectangle r) {
     return this.area() - r.area();     return this.area() - r.area();
Line 69: Line 72:
 </code> </code>
  
-Επίσης, δεν πρέπει να παραλήψουμε να δηλώσουμε ότι η κλάση ''Rectangle'' υλοποιεί το συγκεκριμένο interface. Συνολικά η κλάση ''Rectangle'' γράφεται ως εξής:+Επίσης, δεν πρέπει να παραλήψουμε να δηλώσουμε ότι η κλάση ''Rectangle'' υλοποιεί το συγκεκριμένο interface. Τελικάη κλάση ''Rectangle'' γράφεται ως εξής:
  
 <code java Rectangle.java> <code java Rectangle.java>
Line 95: Line 98:
 </code> </code>
  
 +<WRAP tip 80% center round>
 +Οι βασικές κλάσεις του πακέτου java.lang (String,Character,Long,Integer,Short,Double,Float) υλοποιούν το interface [[https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html|java.lang.Comparable]]. Η κλάση [[https://docs.oracle.com/javase/8/docs/api/java/lang/String.html|java.lang.String]] υλοποιεί σύγκριση δύο Strings λεξικογραφικά.
 +</WRAP>
 +
 +===== Το interface java.util.Comparator =====
 +
 +Στο προηγούμενο παράδειγμα, ας υποθέσουμε ότι ενώ η κλάση Rectangle υλοποιεί το interface Comparable εμείς δεν θέλουμε να κατατάξουμε τα αντικείμενα με βάση το κριτήριο σύγκρισης που εισάγει η μέθοδος compareTo (το εμβαδό του παραλληλογράμμου), αλλά με βάση το ύψος. Σε αυτή την περίπτωση μπορούμε να εκμεταλλευτούμε μια παραλλαγή της μεθόδου sort, η οποία εκτός από τον πίνακα λαμβάνει ως δεύτερο όρισμα μία κλάση που θα επιτελέσει τη σύγκριση δύο αντικειμένων μεταξύ τους. Η κλάση αυτή πρέπει υποχρεωτικά να υλοποιεί το interface [[https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html|java.util.Comparator]]. Για το προηγούμενο παράδειγμα ας δημιουργήσουμε μία τέτοια κλάση.
 +
 +<code java RectangleComparator.java>
 +public class RectangleComparator implements java.util.Comparator<Rectangle>{
 +    
 +  public int compare(Rectangle r1, Rectangle r2) {
 +      return r1.height - r2.height;
 +  }  
 +}
 +</code>
 +
 +και στη μέθοδο main να καλέσουμε την παραλλαγή της sort ως εξης:
 +<code java>
 +    Arrays.sort(rectangles, new RectangleComparator());
 +</code>
 +
 +<code java SortRectangleArray.java>
 +import java.util.Random;
 +import java.util.Arrays;
 +
 +class SortRectangleArray {
 +  
 +    public static void main(String []args) {
 +    Random rand = new Random(12345);
 +    Rectangle []rectangles = new Rectangle[5];
 +    for(int i=0;i<5; i++)
 +      rectangles[i] = new Rectangle(rand.nextInt(10), rand.nextInt(10));
 +      
 +    print_rectangles(rectangles);
 +    Arrays.sort(rectangles, new RectangleComparator());
 +    print_rectangles(rectangles);
 +  }
 +  
 +  public static void print_rectangles(Rectangle []rectangles) {
 +    System.out.println("================");
 +    for(int i=0; i<rectangles.length; i++)
 +      System.out.println(i+". "+rectangles[i].toString());
 +  }
 +}
 +</code>
 +
 +Παρατηρείτε ότι η σειρά της τελικής κατάταξης των αντικειμένων αλλάζει. Αγνοείται η σειρά κατάταξης που δημιουργεί η μέθοδος ''compareTo'' και εισάγεται η σειρά κατάταξης που ορίζει η παραπάνω κλάση.
 +
 +<WRAP tip 80% center round>
 +Ο παραπάνω τρόπος σύγκρισης έχει ιδιαίτερη χρησιμότητα όταν έχουμε κλάσεις των οποίων θέλουμε να συγκρίνουμε τα αντικείμενα μεταξύ τους, αλλά οι κλάσεις αυτές δεν υλοποιούν το interface java.lang.Comparable.
 +</WRAP>
 +
 +| Προηγούμενο : [[ :java:abstract_classes_vs_interfaces | Σύγκριση abstract κλάσεων και interfaces ]] | [[ :toc | Περιεχόμενα ]] | Επόμενο: [[ :java:instanceof | Ο τελεστής instanceof ]]  |
java/comparable.1582617466.txt.gz · Last modified: 2020/02/25 07:57 by gthanos