כדי לארגן אובייקטים מאותו סוג המאוחסנים במערך או באוסף, מפתחי Java המציאו את ה-
אחת הדרכים הפשוטות והיעילות ביותר למיין מערך אובייקטים היא שיטת
Comparable
. הוא מצהיר רק על שיטה אחת compareTo
:
public interface Comparable<T> {
public int compareTo(T o);
}
ממשק Comparable
מוגדר לפי סוג האובייקט שהוא מקבל כפרמטר לשיטה compareTo
. במקרה זה, אנו מזהירים את המהדר אילו סוגי אובייקטים אנו הולכים להשוות. אם תנאי זהות הסוג לא מתקיים, נקבל שגיאה ClassCastException
. שיטה compareTo
ב-Java משווה את האובייקט הקורא לאובייקט המועבר כפרמטר ומחזירה מספר שלם כתוצאה מההשוואה:
- חיובי אם האובייקט הקורא גדול מהאובייקט המועבר כפרמטר;
- שלילי אם האובייקט הקורא קטן מהאובייקט המועבר כפרמטר;
- null אם האובייקטים שווים.
מדוע נדרשת שיטת compareTo ב-Java?
מתכנת Java נאלץ להתמודד לעיתים קרובות עם מערכים ורשימות של אובייקטים. כאשר עובדים עם כמויות גדולות של נתונים, לרוב נוח לאחסן אותם בצורה מאורגנת או ממוינת. ראשית, היא מזרזת את העבודה עם האוסף בעת חיפוש המידע הדרוש, ושנית, נתונים מאורגנים נתפסים טוב יותר מבחינה ויזואלית.sort()
המחלקה Arrays
, ואוסף אובייקטים בצורה של רשימה היא שיטת מחלקה דומה Collections
. כדי למיין באמצעות שיטות אלו, מפתחי Java נתנו לנו את החופש לבחור כיצד לציין את קריטריוני המיון: על ידי הטמעת הממשק Comparable
במחלקת האובייקטים שאנו רוצים למיין, או על ידי שימוש ב- Comparator
. במקרה הראשון, שיטות מיון מקבלות קבוצה של אובייקטים בצורה של מערך או רשימה:
sort(T[]array)//sorting массива
sort(List<T> list)// sorting списка
ובשנייה - פלוס יישום נוסף של הממשק Comparator
:
sort(T[]array, Comparator <? super T> comparator)//sorting массива
sort(List<T> list, Comparator <? super T> comparator)// sorting списка
הממשק Comparable
משמש כאשר אנו רוצים לקבוע סדר טבעי (ההגיוני ביותר מנקודת המבט שלנו) של אובייקטים בעת המיון. זוהי גם דרך "לחוט" את האלגוריתם להשוואת אובייקטים ממחלקה זו בשלב התכנון. לדוגמה, באמצעות היישום של ממשק זה, הקריטריונים לסדר טבעי במחלקות העטיפה של הסוגים הפרימיטיביים העיקריים מוגדרים: , , Byte
, Character
, Long
, Integer
, Short
, Double
, Float
. זה גם אומר שלמחלקות הללו יש שיטה מיושמת שבה נוכל להשתמש בתוכנית במידת הצורך. בואו נסתכל על דוגמה להשוואת מחרוזות כדי לראות כיצד שיטה זו מיושמת במחלקה . Boolean
String
compareTo
String
String str1="Аарон";
String str2="АAPOH";
String str3="аарон";
String str4="ААрон";
String str5="аАрон";
String str6="Берта";
String str7="берта";
String[] allStr=new String[]{str1,str2,str3,str4, str5,str6, str7};
Arrays.sort(allStr);
for (String s:allStr){
System.out.println(s);
}
}
אם נבצע את הקוד הזה בשיטה main
, נקבל את התוצאה הבאה:
АAPOH
ААрон
Аарон
Берта
аАрон
аарон
берта
כפי שניתן לראות בדוגמה במחלקה String
, השיטה compareTo
מסדרת מחרוזות לפי סדר אלפביתי, לקסיקוגרפי ותלוי רישיות. סדר זה של השוואת מחרוזות הוא המוגדר על ידי מפתחי המחלקה String
כטבעי. להבנה פשוטה יותר של מה זה סדר לקסיקוגרפי, מספיק לזכור כיצד מילים מסודרות במילוני לשון. כאשר משווים מספרים, אובייקטים מסודרים בסדר עולה. היגיון השוואה זה מוטבע במחלקות Byte
, Character
, Long
, Integer
, Shor
, Double
, Float
.
בואו ליישם את ההשוואה בכיתה שלנו
הבה נסתכל על דוגמה כיצד תוכל לבנות את היכולת להשוות אובייקטים לתוך הכיתה שלך. בעת הטמעתcompareto
שיטת Java, אנו יכולים לציין קריטריון אחד או יותר להזמנת אובייקטים, וגם להשתמש בשיטות compareto
מהמחלקות String
ו Integer
. לדוגמה, עבור אובייקטי מחלקה User
אנו מגדירים מיון לפי שם, ובמקרה של שמות שווים, לפי גיל. חפצים יהיו מסודרים בסדר הטבעי שלהם (ככל שהערך גדל). מעמד User
:
public class User implements Comparable <User>{//добавляем возможность сравнивать an objectы User
private String name;
private Integer age;
private String email;
public User(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
@Override
//реализуем метод compareTo интерфейса Comparable
public int compareTo(User o) {
//используем метод compareTo из класса String для сравнения имен
int result = this.name.compareTo(o.name);
//если имена одинаковые - сравниваем возраст,
используя метод compareTo из класса Integer
if (result == 0) {
result = this.age.compareTo(o.age);
}
return result;
}
@Override
public String toString() {
return "{" +
"name='" + name + '\'' +
", age=" + age +
", email='" + email + '\'' +
'}';
}
בואו נבדוק את פעולת השיטה compareTo
המיושמת במחלקה User
באמצעות שיטת sort
המחלקה Collections
:
public static void main(String[] args) {
User user = new User("Andrey", 19, "andryha@mail.ru");
User user2 = new User("Олег", 25, "oleg@mail.ru");
User user3 = new User("Andrey", 24,"opr@google.com");
User user4 = new User("Igor", 16, "igor@mail.ru");
User user5 = new User("Andrey", 44,"stary@google.com");
List<User> list = new ArrayList<>();
list.add(user);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
System.out.println("-------до сортировки--------");
for (User u : list) {
System.out.println(u);
}
System.out.println("-------после сортировки-----");
Collections.sort(list);
for (User u : list) {
System.out.println(u);
}
}
}
}
תוצאת השיטה main
:
-------до сортировки--------
{name='Андрей', age=19, email='andryha@mail.ru'}
{name='Олег', age=25, email='oleg@mail.ru'}
{name='Андрей', age=24, email='opr@google.com'}
{name='Игорь', age=16, email='igor@mail.ru'}
{name='Андрей', age=44, email='stary@google.com'}
-------после сортировки-----
{name='Андрей', age=19, email='andryha@mail.ru'}
{name='Андрей', age=24, email='opr@google.com'}
{name='Андрей', age=44, email='stary@google.com'}
{name='Игорь', age=16, email='igor@mail.ru'}
{name='Олег', age=25, email='oleg@mail.ru'}
אז בואו נסכם. אם אתה תומך בסדר בכל דבר ומעוניין לסדר את האובייקטים שלך במערך או רשימה ללא קוד מיותר, השתמש בממשק Comparable
. היישום של שיטת compareTo שלה מקל למדי לבנות מנגנון לסדר טבעי של אובייקטים בכיתה שלך. אם אתה צריך לעבוד עם אוספים ומערכים של אובייקטים של מחלקות סטנדרטיות המתוארות בספריית Java, השתמש בהטמעות מוכנות compareTo
במחלקות אלה.
GO TO FULL VERSION