compareTo() ו-Comparable
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Java של Coddy. שיעור 44 מתוך 87.
הממשק Comparable מאפשר לאובייקטים להגדיר את הסדר הטבעי שלהם. באמצעות מימוש הממשק הזה, אפשר למיין את המחלקה שלך באופן אוטומטי בעזרת מתודות כמו Collections.sort() או לאחסן אותה באוספים ממוינים כמו TreeSet.
הממשק דורש ממך לממש מתודה אחת: compareTo(). המתודה משווה בין האובייקט הנוכחי לאובייקט אחר ומחזירה מספר שלם המציין את הסדר היחסי ביניהם:
- ערך שלילי: האובייקט הזה מגיע לפני האובייקט האחר
- אפס: שני האובייקטים שווים
- ערך חיובי: האובייקט הזה מגיע אחרי האובייקט האחר
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person other) {
return Integer.compare(this.age, other.age); // מיין לפי גיל בסדר עולה
}
}לאחר שמממשים את המיון, הוא נעשה פשוט:
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people); // כעת ממוינים לפי גיל: Bob, Aliceלהשוואת מחרוזות או שדות אחרים מסוג Comparable, אפשר להאציל את ההשוואה לשיטת compareTo() שלהם במקום להשתמש בחיסור: return this.name.compareTo(other.name);. הגישה הזאת בטוחה יותר ומטפלת כראוי במקרי קצה. עבור שדות מסוג int, העדיפו את Integer.compare(a, b) על פני a - b, משום שחיסור עלול לגרום לגלישה עם ערכים קיצוניים.
אתגר
קלבואו נבנה מערכת דירוג סרטים שמשתמשת בממשק Comparable כדי למיין סרטים לפי הדירוגים שלהם. תיצרו מחלקה בשם Movie שיודעת להשוות את עצמה לסרטים אחרים, וכך יתאפשר מיון אוטומטי מהדירוג הגבוה לנמוך.
תארגנו את הקוד שלכם בשני קבצים:
Movie.java: צרו מחלקה שמייצגת סרט וניתן להשוות אותו לסרטים אחרים. לסרט יש שלושה שדות פרטיים:title(String),director(String) ו-rating(double, מ-0.0 עד 10.0). כללו בנאי לאתחול כל השדות ומתודות getter לכל אחד מהם.גרמו למחלקה Movie לממש את
Comparable<Movie>ולדרוס את המתודהcompareTo(). יש למיין את הסרטים לפי הדירוג בסדר יורד (הדירוג הגבוה ביותר ראשון). כשמשווים ערכי double, השתמשו ב-Double.compare()להשוואה בטוחה: זכרו להפוך את הסדר כדי למיין בסדר יורד!דרסו את
toString()כך שתחזיר:[title] by [director] - Rating: [rating]Main.java: תנו למחלקה Movie חיים על ידי יצירת רשימת סרטים ומיונם. תקבלו קלט עבור שלושה סרטים, כל אחד בשורה נפרדת ובתבנית:title,director,ratingנתחו כל שורה כדי ליצור אובייקטים מסוג Movie, הוסיפו אותם ל-
ArrayList, ואז השתמשו ב-Collections.sort()כדי למיין את הרשימה. בזכות המימוש שלכם שלComparable, הסרטים יסתדרו אוטומטית לפי הדירוג!אחרי המיון, הדפיסו כל סרט בשורה משלו ובתבנית
toString(). הסרט בעל הדירוג הגבוה ביותר אמור להופיע ראשון.
תקבלו שלוש שורות קלט, שכל אחת מהן מכילה נתוני סרט בתבנית: title,director,rating
לדוגמה, שורת קלט עשויה להיראות כך: Inception,Christopher Nolan,8.8
זכרו לייבא את java.util.ArrayList, את java.util.Collections ואת java.util.Scanner בקובץ Main שלכם. שימו לב כיצד מימוש Comparable מאפשר לכם למיין אובייקטים מותאמים אישית באמצעות קריאה אחת למתודה: אין צורך ב-comparator נוסף!
נסו בעצמכם
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// קראו שלוש שורות של נתוני סרטים
String line1 = scanner.nextLine();
String line2 = scanner.nextLine();
String line3 = scanner.nextLine();
// TODO: צרו ArrayList לאחסון אובייקטים מסוג Movie
// TODO: פענחו כל שורה (פורמט: title,director,rating)
// רמז: השתמשו ב־split(",") כדי להפריד בין החלקים
// רמז: השתמשו ב־Double.parseDouble() עבור הדירוג
// TODO: צרו אובייקטים מסוג Movie והוסיפו אותם לרשימה
// TODO: מיינו את הרשימה באמצעות Collections.sort()
// TODO: הדפיסו כל סרט (אחד בכל שורה)
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא לתכנות מונחה עצמיםמחלקות לעומת אובייקטיםמילת המפתח thisמתודותשדות (מאפיינים)מתודת הבנאיהעמסת בנאיםחזרה – מחשבון פשוט4ירושה
ירושה בסיסית (extends)מילת המפתח superדריסת מתודות (@Override)שרשור בנאיםהמחלקה Objectירושה יחידה ורב־רמתיתלמה אין ירושה מרובה של מחלקותסיכום – היררכיית עובדים7מתודות מיוחדות ומחלקת Object
מתודת toString()equals() ו-hashCode()מתודת clone()compareTo() ו-Comparableהממשק Comparatorסיכום – מיון מותאם אישית2מצייני גישה ואנקפסולציה
סקירה של רמות הגישהמתודות Getter ו-Setterהסתרת מידעמילת המפתח finalסיכום – מנהל חשבון בנק5פולימורפיזם
יסודות העמסת מתודותדריסת מתודות (בזמן ריצה)המרה כלפי מעלה וכלפי מטההאופרטור instanceofמחלקות ומתודות מופשטותסיכום – מחשבון צורות8מושגי OOP מתקדמים
הרכבה מול ירושהאגרגציה מול הרכבהמחלקות פנימיות, מקוננות ואנונימיותEnums ומתודות של EnumRecords (Java 16+)מחלקות חתומות (Java 17+)3מאפייני מחלקה וחברים סטטיים
משתני מופע לעומת משתנים סטטייםמתודות סטטיותבלוקים סטטייםקבועים (static final)סיכום — מונה ומחלקת עזר6ממשקים ומחלקות מופשטות
מבוא לממשקיםמימוש ממשקיםמימוש של כמה ממשקיםמתודות ברירת מחדל וסטטיות בממשקמחלקות מופשטות לעומת ממשקיםממשקים פונקציונלייםסיכום – מערכת תשלומיםתרגלו בעצמכם: קומפיילר Java אונליין