
“สวัสดี อามีโก้!”
"สวัสดี บิลาโบ!"
"วันนี้เราจะตรวจสอบหัวข้อเล็กๆ แต่น่าสนใจและมีประโยชน์: การเรียงลำดับคอลเลกชัน"
"การเรียงลำดับ? ฉันได้ยินบางอย่างเกี่ยวกับเรื่องนั้น"
"นานมาแล้ว โปรแกรมเมอร์ทุกคนต้องสามารถเขียน sorting algorithm ได้ ทำได้และต้องเขียนมัน แต่วันเวลาเหล่านั้นจบลงแล้ว ทุกวันนี้ การเขียน sorting code ของคุณเองถือเป็นรูปแบบที่ไม่ดี ถูกประดิษฐ์ขึ้น"
"ใน Java (และภาษาโปรแกรมอื่นๆ) การเรียงลำดับได้ถูกนำมาใช้แล้ว งานของคุณคือเรียนรู้วิธีการใช้สิ่งที่มีอยู่แล้วอย่างเหมาะสม "
"ตกลง."
" คลาสตัวช่วย คอลเลกชั่นมีวิธีการจัดเรียงแบบคงที่ที่ใช้ในการจัดเรียงคอลเลกชั่น หรืออย่างแม่นยำกว่านั้นคือรายการ องค์ประกอบในแผนที่และเซ็ตไม่มีลำดับ/ดัชนี ดังนั้นจึงไม่มีอะไรให้จัดเรียง"
“ใช่ ฉันจำได้ ฉันใช้วิธีนี้ครั้งนึงในการจัดเรียงรายการตัวเลข”
"เยี่ยมมาก แต่วิธีนี้มีประสิทธิภาพมากกว่าที่เห็นในแวบแรกมาก มันสามารถจัดเรียงได้ไม่เพียงแค่ตัวเลขเท่านั้น แต่ยังรวมถึงวัตถุใดๆ ตามเกณฑ์ใดๆ อินเทอร์เฟซสองแบบช่วยให้วิธีนี้ทำสิ่งนี้ได้: ตัวเปรียบเทียบและตัวเปรียบเทียบ "
"บางครั้งคุณจำเป็นต้องจัดเรียงวัตถุ ไม่ใช่ตัวเลข ตัวอย่างเช่น สมมติว่าคุณมีรายชื่อบุคคล และคุณต้องการจัดเรียงตามอายุ เรามีอินเทอร์เฟซที่เปรียบเทียบได้สำหรับสิ่งนี้"
"ให้ฉันแสดงตัวอย่างให้คุณเห็นก่อน จากนั้นทุกอย่างจะชัดเจนขึ้น:"
public class Woman implements Comparable<Woman>
{
public int age;
public Woman(int age) {
this.age = age;
}
public int compareTo(Woman o)
{
return this.age - o.age;
}
}
public static void main(String[] args )
{
ArrayList<Woman> women = new ArrayList<Woman>();
women.add(new Woman(18));
women.add(new Woman(21));
women.add(new Woman(5));
Collections.sort(women);
}
"ในการจัดเรียงออบเจกต์ คุณต้องรู้วิธีเปรียบเทียบก่อน สำหรับสิ่งนี้ เราใช้ Comparable อินเทอร์เฟซ Comparableเป็นแบบทั่วไป ซึ่งหมายความว่ายอมรับอาร์กิวเมนต์ประเภท ซึ่งมีเมธอดทั่วไปเพียงวิธีเดียว: เปรียบเทียบถึง(T o) วิธีการนี้เปรียบเทียบวัตถุปัจจุบัน (นี้) และวัตถุที่ส่งผ่านเป็นอาร์กิวเมนต์ (o) กล่าวอีกนัยหนึ่ง เราต้องใช้วิธีนี้ในชั้นเรียนของเรา แล้วใช้เพื่อเปรียบเทียบวัตถุปัจจุบัน (สิ่งนี้) กับวัตถุที่ส่งผ่าน "
"และการเปรียบเทียบทำงานอย่างไร ฉันคาดหวังว่ามันจะคืนค่าจริงหรือเท็จขึ้นอยู่กับว่าวัตถุที่ส่งผ่านนั้นมีค่ามากกว่าหรือเล็กกว่า"
"สิ่งต่าง ๆ มีความซับซ้อนมากขึ้นที่นี่ วิธีการเปรียบเทียบเพื่อไม่คืนค่าจริง/เท็จ แต่จะส่งคืนค่า int ซึ่งจริง ๆ แล้วทำเพื่อความเรียบง่าย
"เมื่อคอมพิวเตอร์ต้องการตรวจสอบว่าตัวเลขหนึ่งมากกว่าอีกจำนวนหนึ่งหรือไม่ คอมพิวเตอร์ก็แค่ลบตัวเลขที่สองออกจากตัวเลขแรก แล้วดูที่ผลลัพธ์ หากผลลัพธ์เป็น 0 แสดงว่าตัวเลขนั้นเท่ากัน หากผลลัพธ์น้อยกว่าศูนย์ แล้วจำนวนที่สองจะมากกว่า และถ้าผลลัพธ์มากกว่าศูนย์ ตัวเลขแรกก็จะมากกว่า"
"ใช้ตรรกะเดียวกันนี้ ตามข้อมูลจำเพาะ วิธีการเปรียบเทียบต้องคืนค่าศูนย์หากวัตถุที่เปรียบเทียบมีค่าเท่ากัน หากวิธีการเปรียบเทียบส่งกลับตัวเลขที่มากกว่าศูนย์ แสดงว่าวัตถุของเรามีค่ามากกว่าวัตถุที่ส่งผ่าน "หากการเปรียบเทียบถึง เมธอดส่งคืนตัวเลขที่น้อยกว่าศูนย์ จากนั้น 'ค่านี้' จะน้อยกว่าวัตถุที่ส่งผ่าน"
"นั่นเป็นเรื่องที่แปลกเล็กน้อย"
"ใช่ แต่ถ้าคุณกำลังเปรียบเทียบออบเจกต์โดยอิงจากคุณสมบัติตัวเลขบางอย่าง คุณก็สามารถคืนค่าผลต่างระหว่างออบเจกต์เหล่านั้นได้โดยการลบสิ่งหนึ่งออกจากอีกสิ่งหนึ่ง เหมือนกับที่ทำในตัวอย่างด้านบน"
public int compareTo(Woman o)
{
return this.age - o.age;
}
"ฉันคิดว่าฉันเข้าใจทุกอย่าง แต่อาจจะไม่ แต่เกือบทุกอย่าง"
"เยี่ยมมาก ตอนนี้เรามาพิจารณาปัญหาเชิงปฏิบัติกันดีกว่า สมมติว่าคุณเขียนเว็บไซต์เจ๋งๆ สำหรับทำเสื้อผ้าผู้หญิงในประเทศจีน คุณใช้คลาส Woman เพื่ออธิบายลูกค้าของคุณ คุณสร้างหน้าเว็บที่มีตารางที่คุณสามารถดูได้ทั้งหมด . แต่มีปัญหา… "
"วัตถุ Woman ของคุณไม่เพียงแต่ประกอบด้วยอายุเท่านั้น แต่ยังมีข้อมูลอื่นๆ อีกจำนวนมาก เช่น ชื่อ นามสกุล ส่วนสูง น้ำหนัก จำนวนลูก และอื่นๆ"
"ตารางผู้ใช้มีหลายคอลัมน์ และนี่คือคำถาม: คุณจะจัดเรียงผู้ใช้ของคุณตามเกณฑ์ต่างๆ ได้อย่างไร ตามน้ำหนัก ตามอายุ ตามนามสกุล"
"อืม ใช่ ฉันมักจะเห็นตารางที่ให้คุณจัดเรียงตามคอลัมน์ แล้วคุณจะทำอย่างไร"
"สำหรับสิ่งนี้ เรามีอินเทอร์เฟซที่สองที่ฉันอยากจะบอกคุณเกี่ยวกับวันนี้: อินเทอร์เฟซตัวเปรียบเทียบ นอกจากนี้ยังมีวิธีการเปรียบเทียบ แต่ต้องใช้สองอาร์กิวเมนต์ ไม่ใช่หนึ่ง: int เปรียบเทียบ (T o1, T o2) นี่คือวิธีการ ผลงาน:"
public class Woman
{
public int age;
public int childrenCount;
public int weight;
public int height;
public String name;
public Woman(int age) {
this.age = age;
}
}
public static void main(String[] args )
{
ArrayList<Woman> women = new ArrayList<Woman>();
women.add(new Woman(18));
women.add(new Woman(21));
women.add(new Woman(5));
Comparator<Woman> compareByHeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.height - o2.height;
}
};
Collections.sort(women, compareByHeight);
}
"อินเทอร์เฟซ Comparator ไม่ได้ซ่อนตรรกะการเปรียบเทียบวัตถุภายในคลาสของวัตถุที่กำลังเปรียบเทียบ แต่จะนำไปใช้ในคลาสที่แยกต่างหากแทน"
"ดังนั้น ฉันสามารถสร้างคลาสหลายคลาสที่ใช้อินเทอร์เฟซ Comparator และให้แต่ละคลาสเปรียบเทียบคุณสมบัติที่แตกต่างกัน น้ำหนักเป็นหนึ่ง อายุเป็นอีกส่วน และส่วนสูงเป็นสาม"
"ใช่ มันง่ายและสะดวกมาก"
"เราเรียก เมธอด Collections.sortโดยส่งรายการของวัตถุและวัตถุพิเศษอื่นเป็นอาร์กิวเมนต์ที่สอง ซึ่งใช้อิน เทอร์เฟซ Comparatorและบอกวิธีเปรียบเทียบคู่ของวัตถุอย่างถูกต้องในกระบวนการเรียงลำดับ"
"อืม ฉันคิดว่าฉันเข้าใจทุกอย่างแล้ว ขอฉันลองดูก่อน สมมติว่าฉันต้องจัดเรียงผู้ใช้ตามน้ำหนัก มันก็จะประมาณนี้:"
Comparator<Woman> compareByWeight = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.weight - o2.weight;
}
};
Collections.sort(women, compareByWeight);
"ใช่แน่นอน"
"เยี่ยมมาก แต่ถ้าฉันต้องการเรียงลำดับกลับกันล่ะ"
"ลองคิดดูสิ คำตอบนั้นง่ายมาก!"
"เข้าใจแล้ว! แบบนี้:"
return o1.weight - o2.weight;
return o2.weight – o1.weight;
"ถูกต้อง ทำได้ดีมาก"
"และถ้าฉันต้องการจัดเรียงตามนามสกุล ฉันจะจัดเรียงสตริงได้อย่างไร Bilaabo"
"คลาส String ใช้เมธอดของ expandTo แล้ว คุณเพียงแค่เรียกมันว่า:"
Comparator<Woman> compareByName = new Comparator<Woman>() {
public int compare(Woman o1, Woman o2) {
return o1.name.compareTo(o2.name);
}
};
Collections.sort(women, compareByName);
"นั่นเป็นบทเรียนที่ดี บิลาโบ ขอบคุณมาก"
"และขอบคุณคุณเพื่อนของฉัน!"
GO TO FULL VERSION