ทำไมจึงComparable
ใช้Java ? ทำไมบางคนถึงใช้Comparable
ในชั้นเรียน อะไรคือตัวอย่างชีวิตจริงที่คุณต้องใช้เทียบเคียง?
ทำไมจึงComparable
ใช้Java ? ทำไมบางคนถึงใช้Comparable
ในชั้นเรียน อะไรคือตัวอย่างชีวิตจริงที่คุณต้องใช้เทียบเคียง?
คำตอบ:
นี่คือตัวอย่างชีวิตจริง ทราบว่ายังมีการดำเนินการString
Comparable
class Author implements Comparable<Author>{
String firstName;
String lastName;
@Override
public int compareTo(Author other){
// compareTo should return < 0 if this is supposed to be
// less than other, > 0 if this is supposed to be greater than
// other and 0 if they are supposed to be equal
int last = this.lastName.compareTo(other.lastName);
return last == 0 ? this.firstName.compareTo(other.firstName) : last;
}
}
ต่อมา ..
/**
* List the authors. Sort them by name so it will look good.
*/
public List<Author> listAuthors(){
List<Author> authors = readAuthorsFromFileOrSomething();
Collections.sort(authors);
return authors;
}
/**
* List unique authors. Sort them by name so it will look good.
*/
public SortedSet<Author> listUniqueAuthors(){
List<Author> authors = readAuthorsFromFileOrSomething();
return new TreeSet<Author>(authors);
}
last
?
การเทียบเคียงกำหนดลำดับตามธรรมชาติ สิ่งนี้หมายความว่าคุณกำลังกำหนดค่าเมื่อวัตถุหนึ่งควรถือว่าเป็น "น้อยกว่า" หรือ "มากกว่า"
สมมติว่าคุณมีจำนวนเต็มและคุณต้องการจัดเรียง มันง่ายมากแค่ใส่ไว้ในคอลเลกชั่นที่จัดเรียงไว้ใช่มั้ย?
TreeSet<Integer> m = new TreeSet<Integer>();
m.add(1);
m.add(3);
m.add(2);
for (Integer i : m)
... // values will be sorted
แต่ตอนนี้สมมติว่าฉันมีวัตถุที่กำหนดเองบางอย่างซึ่งการเรียงลำดับเหมาะสมกับฉัน แต่ไม่ได้กำหนดไว้ สมมติว่าฉันมีข้อมูลที่แสดงเขตตามรหัสไปรษณีย์พร้อมความหนาแน่นของประชากรและฉันต้องการจัดเรียงตามความหนาแน่น:
public class District {
String zipcode;
Double populationDensity;
}
ตอนนี้วิธีที่ง่ายที่สุดในการจัดเรียงคือการกำหนดลำดับตามธรรมชาติโดยใช้การเปรียบเทียบซึ่งหมายความว่ามีวิธีมาตรฐานที่กำหนดให้วัตถุเหล่านี้สั่งได้:
public class District implements Comparable<District>{
String zipcode;
Double populationDensity;
public int compareTo(District other)
{
return populationDensity.compareTo(other.populationDensity);
}
}
โปรดทราบว่าคุณสามารถทำสิ่งที่เทียบเท่าได้โดยการกำหนดตัวเปรียบเทียบ ความแตกต่างคือเปรียบเทียบกำหนดตรรกะการสั่งซื้อนอกวัตถุ บางทีในกระบวนการแยกต่างหากฉันจำเป็นต้องสั่งซื้อวัตถุเดียวกันด้วยรหัสไปรษณีย์ - ในกรณีนี้การสั่งซื้อไม่จำเป็นต้องเป็นคุณสมบัติของวัตถุหรือแตกต่างจากการเรียงลำดับตามธรรมชาติของวัตถุ คุณสามารถใช้ตัวเปรียบเทียบภายนอกเพื่อกำหนดการจัดลำดับที่กำหนดเองสำหรับจำนวนเต็มตัวอย่างเช่นโดยการจัดเรียงตามค่าตามตัวอักษร
โดยพื้นฐานแล้วตรรกะการสั่งซื้อจะต้องมีอยู่ที่ไหนสักแห่ง ที่สามารถ -
ในตัววัตถุเองถ้ามันเทียบเคียงได้ตามธรรมชาติ (ขยายจำนวนเต็ม Comparable -eg)
ให้มาในตัวเปรียบเทียบภายนอกดังตัวอย่างด้านบน
TreeSet<Integer>
แทนTreeMap<Integer>
สำหรับหลังไม่อยู่ทรีแม็ปอยู่เสมอ<Key,Value>
-pairs Btw สมมุติTreeMap<District, Object>
จะใช้ได้ผลถ้า District ใช้ Comparable ใช่ไหม? ยังคงพยายามเข้าใจสิ่งนี้
ยกมาจาก javadoc;
อินเทอร์เฟซนี้กำหนดลำดับทั้งหมดบนอ็อบเจ็กต์ของแต่ละคลาสที่ใช้ การเรียงลำดับนี้เรียกว่าการจัดลำดับตามธรรมชาติของคลาสและวิธีการ CompareTo ของคลาสจะเรียกว่าวิธีการเปรียบเทียบตามธรรมชาติ
รายการ (และอาร์เรย์) ของอ็อบเจ็กต์ที่ใช้อินเทอร์เฟซนี้สามารถจัดเรียงโดยอัตโนมัติโดย Collections.sort (และ Arrays.sort) ออบเจ็กต์ที่ใช้อินเทอร์เฟซนี้สามารถใช้เป็นคีย์ในแผนที่ที่เรียงลำดับหรือเป็นองค์ประกอบในชุดที่เรียงลำดับได้โดยไม่จำเป็นต้องระบุตัวเปรียบเทียบ
แก้ไข: .. และทำให้บิตที่สำคัญเป็นตัวหนา
ความจริงที่ว่าคลาสใช้Comparable
หมายความว่าคุณสามารถนำวัตถุสองชิ้นจากคลาสนั้นมาเปรียบเทียบกันได้ บางคลาสเช่นคอลเลกชันบางอย่าง (ฟังก์ชันการจัดเรียงในคอลเล็กชัน) ที่เก็บอ็อบเจ็กต์ตามลำดับโดยอาศัยการเทียบเคียงกัน (ในการจัดเรียงคุณจำเป็นต้องทราบว่าอ็อบเจ็กต์ใด "ใหญ่ที่สุด" และอื่น ๆ )
ตัวอย่างส่วนใหญ่ด้านบนแสดงวิธีการนำวัตถุเทียบเคียงที่มีอยู่กลับมาใช้ใหม่ในฟังก์ชัน CompareTo หากคุณต้องการใช้การเปรียบเทียบของคุณเองเมื่อคุณต้องการเปรียบเทียบวัตถุสองชิ้นที่มีคลาสเดียวกันให้พูดว่าออบเจ็กต์ AirlineTicket ที่คุณต้องการจัดเรียงตามราคา (น้อยกว่าคืออันดับแรก) ตามด้วยจำนวนจุดแวะพัก (อีกครั้งน้อยกว่าคือ อันดับแรก) คุณจะทำสิ่งต่อไปนี้:
class AirlineTicket implements Comparable<Cost>
{
public double cost;
public int stopovers;
public AirlineTicket(double cost, int stopovers)
{
this.cost = cost; this.stopovers = stopovers ;
}
public int compareTo(Cost o)
{
if(this.cost != o.cost)
return Double.compare(this.cost, o.cost); //sorting in ascending order.
if(this.stopovers != o.stopovers)
return this.stopovers - o.stopovers; //again, ascending but swap the two if you want descending
return 0;
}
}
วิธีง่ายๆในการใช้การเปรียบเทียบหลายฟิลด์คือการใช้ComparisonChain ของ Guavaจากนั้นคุณสามารถพูดได้
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(lastName, that.lastName)
.compare(firstName, that.firstName)
.compare(zipCode, that.zipCode)
.result();
}
แทน
public int compareTo(Person other) {
int cmp = lastName.compareTo(other.lastName);
if (cmp != 0) {
return cmp;
}
cmp = firstName.compareTo(other.firstName);
if (cmp != 0) {
return cmp;
}
return Integer.compare(zipCode, other.zipCode);
}
}
การเปรียบเทียบใช้เพื่อเปรียบเทียบอินสแตนซ์ของชั้นเรียนของคุณ เราสามารถเปรียบเทียบอินสแตนซ์จากหลาย ๆ วิธีนั่นคือเหตุผลที่เราต้องใช้วิธีการcompareTo
เพื่อที่จะรู้ว่า (คุณลักษณะ) ที่เราต้องการเปรียบเทียบอินสแตนซ์อย่างไร
Dog
ชั้น:package test;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Dog d1 = new Dog("brutus");
Dog d2 = new Dog("medor");
Dog d3 = new Dog("ara");
Dog[] dogs = new Dog[3];
dogs[0] = d1;
dogs[1] = d2;
dogs[2] = d3;
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* brutus
* medor
* ara
*/
Arrays.sort(dogs, Dog.NameComparator);
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* ara
* medor
* brutus
*/
}
}
Main
ชั้น:package test;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Dog d1 = new Dog("brutus");
Dog d2 = new Dog("medor");
Dog d3 = new Dog("ara");
Dog[] dogs = new Dog[3];
dogs[0] = d1;
dogs[1] = d2;
dogs[2] = d3;
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* brutus
* medor
* ara
*/
Arrays.sort(dogs, Dog.NameComparator);
for (int i = 0; i < 3; i++) {
System.out.println(dogs[i].getName());
}
/**
* Output:
* ara
* medor
* brutus
*/
}
}
นี่คือตัวอย่างที่ดีในการใช้งานเทียบเท่าใน Java:
http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2
ตัวอย่างเช่นเมื่อคุณต้องการมีคอลเล็กชันหรือแผนที่ที่จัดเรียงไว้
เมื่อคุณใช้อินเตอร์เฟซที่คุณจะต้องใช้วิธีการComparable
compareTo()
คุณต้องใช้เพื่อเปรียบเทียบวัตถุเพื่อใช้ตัวอย่างเช่นวิธีการเรียงลำดับของArrayList
คลาส คุณต้องการวิธีเปรียบเทียบวัตถุของคุณเพื่อให้สามารถจัดเรียงได้ ดังนั้นคุณต้องมีcompareTo()
วิธีการที่กำหนดเองในชั้นเรียนของคุณเพื่อให้คุณสามารถใช้กับArrayList
วิธีการจัดเรียงได้ compareTo()
วิธีการส่งกลับ -1,0,1
ฉันเพิ่งอ่านบทตามใน Java Head 2.0 ฉันยังคงเรียนรู้
ตกลง แต่ทำไมไม่เพียงกำหนดcompareTo()
วิธีการโดยไม่ใช้อินเทอร์เฟซที่เทียบเคียงได้ ตัวอย่างเช่นคลาสที่City
กำหนดโดยname
และtemperature
และ
public int compareTo(City theOther)
{
if (this.temperature < theOther.temperature)
return -1;
else if (this.temperature > theOther.temperature)
return 1;
else
return 0;
}