สวัสดีอีกครั้ง! :) ในบทเรียนที่แล้ว เราได้ทำความคุ้นเคยกับโครงสร้างข้อมูลเช่นอาร์เรย์ (อาร์เรย์ Java) เรียนรู้วิธีสร้างอาร์เรย์ กรอกข้อมูล และเรียนรู้วิธีจัดเก็บอาร์เรย์ในหน่วยความจำ วันนี้เราจะมาดูงานและตัวอย่างการทำงานกับอาร์เรย์ที่คุณมักจะพบเจอในการทำงานจริง ตัวอย่างเช่น ลองจินตนาการถึงสถานการณ์นี้: เรามีอาร์เรย์ 10 หมายเลขที่เขียนแบบสุ่มลำดับ
เราเกิดไอเดียขึ้นมา เหลือเพียงการเขียนโค้ดเท่านั้น มันจะมีลักษณะเช่นนี้:
//array Java, example
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
หน้าที่ของเราคือการจัดเรียงอาร์เรย์นี้จากน้อยไปมาก: จากตัวเลขที่น้อยที่สุดไปหามากที่สุด ในที่สุดมันก็ควรมีลักษณะเช่นนี้:
[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
เราจะทำเช่นนี้ได้อย่างไร? งานนี้ไม่ใช่เรื่องจิ๊บจ๊อย เราไม่เคยทำมาก่อน :/ มีไอเดียอะไรบ้าง? ลองเดาสิ นี่คือสิ่งที่เราสามารถทำได้ เช่น:
- วนซ้ำองค์ประกอบทั้งหมดของอาร์เรย์ เปรียบเทียบแต่ละองค์ประกอบกับองค์ประกอบถัดไป (
[0]
กับ[1]
,[1]
กับ[2]
,[2]
กับ[3]
ฯลฯ ) หากองค์ประกอบอาร์เรย์ปัจจุบันมีขนาดใหญ่กว่าองค์ประกอบถัดไป เราจะสลับองค์ประกอบเหล่านั้นและไปยังองค์ประกอบถัดไป ถ้าไม่ก็ปล่อยไว้เหมือนเดิมแล้วเดินหน้าต่อไป - ดังนั้น หลังจากที่ผ่านองค์ประกอบของอาร์เรย์ครั้งแรก ค่าที่ใหญ่ที่สุด (167) จะรับประกันว่าจะอยู่ในเซลล์สุดท้าย
- ตอนนี้เรามาดูองค์ประกอบทั้งหมดของอาร์เรย์อีกครั้งโดยเริ่มจากองค์ประกอบที่มีดัชนี
[0]
แต่จนถึงองค์ประกอบสุดท้าย (จำนวนที่ใหญ่ที่สุดอยู่ในตำแหน่งแล้ว) และทำการเปรียบเทียบและสลับแบบเดียวกัน
ในตอนท้าย เราจะมีค่าสูงสุดเป็นอันดับสอง (99) ในเซลล์สุดท้าย - เรามาทำซ้ำงานนี้หลายๆ ครั้งตามที่เรามีองค์ประกอบลบหนึ่งตัวในอาร์เรย์

public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
for (int i = numbers.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
/* Compare the elements in pairs,
if they are in the wrong order,
then swap them */
if (numbers[j] > numbers[j + 1]) {
int tmp = numbers[j];
numbers[j] = numbers[j + 1];
numbers[j + 1] = tmp;
}
}
}
}
}
อืม... มันดูซับซ้อนนิดหน่อย -_- แม้ว่าหลักการทำงานทั่วไปจะชัดเจน แต่คุณก็ต้องเขียนโค้ดค่อนข้างมากเพื่อแก้ปัญหาที่ดูเหมือนง่ายเช่นนี้ โอเค บางทีเราอาจจะประเมินตัวเองสูงไปหรือเปล่า? อาจเป็นไปได้ว่างานที่เราทำนั้นยากเกินไปสำหรับเราจนถึงตอนนี้ มาลองทำสิ่งที่ง่ายกว่านี้กัน ตัวอย่างเช่น ลองใช้อาร์เรย์ของตัวเลขเดียวกัน
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
งานของเราคือการคัดลอกเนื้อหาไปยังอาร์เรย์อื่น
int [] numbersCopy = new int[10];
ลองคิดดูว่าคุณจะทำเช่นนี้โดยใช้ความรู้เกี่ยวกับอาร์เรย์ที่คุณมีอยู่แล้วได้อย่างไร ตัวอย่างเช่น คุณสามารถวนซ้ำอาร์เรย์numbers
และเขียนองค์ประกอบทีละรายการลงในnumbersCopy
:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = new int[10];
for (int i = 0; i < numbers.length; i++) {
numbersCopy[i] = numbers[i];
}
}
}
เราทำเสร็จแล้วไม่มากก็น้อย! ดูเหมือนว่าปัญหาจะได้รับการแก้ไขแล้ว แต่ขอย้ำอีกครั้งว่า หากจำเป็นต้องดำเนินการบ่อยครั้ง โค้ดก็จะมีลูปที่เหมือนกันหลายชุด ในความเป็นจริง ปัญหาเหล่านี้และปัญหาอื่น ๆ ได้รับการแก้ไขโดยผู้สร้าง Java มานานแล้ว และเราไม่จำเป็นต้อง "สร้างวงล้อใหม่" และเขียนโค้ดบางส่วนสำหรับวิธีแก้ปัญหาของเราเอง
คลาสอาร์เรย์ Java
คลาส Java พิเศษจะช่วยคุณแก้ไขปัญหาทั่วไปเมื่อทำงานกับอาร์เรย์ -Arrays
. มีการเพิ่มเมธอดในคลาสนี้เพื่อแก้ไขปัญหาทั่วไปที่โปรแกรมเมอร์ Java พบในการทำงาน ตัวอย่างเช่นงานในการเรียงลำดับอาร์เรย์ซึ่งเราเองพยายามหาวิธีแก้ปัญหาสามารถแก้ไขได้ในบรรทัดเดียว:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
}
}
วิธีการArrays.sort()
เรียงลำดับอาร์เรย์ ยิ่งไปกว่านั้น อัลกอริธึมที่ฝังอยู่ในนั้นยังทำให้มีประสิทธิภาพมากกว่าโค้ดที่เราเขียนอีกด้วย เอาต์พุตคอนโซล:
[-234, -2, 16, 26, 35, 43, 80, 92, 99, 167]
โปรดทราบ: ในการแปลงอาร์เรย์เป็นสตริง เราใช้วิธีคลาสอื่นArrays
- อาร์เรย์ JavaArrays.toString()
เองไม่ได้แทนที่. ดังนั้นถ้าคุณเพียงแค่เขียน toString()
System.out.println(numbers.toString());
toString()
วิธี การเรียน จะถูกเรียกว่าObject
. ในกรณีของอาร์เรย์ ผลลัพธ์จะเป็นดังนี้:
[I@4554617c
ตอนนี้เราจะไม่ลงรายละเอียดว่าเหตุใดข้อสรุปจึงเป็นเช่นนี้ สิ่งสำคัญคือ นี่ไม่ใช่สิ่งที่เราต้องการอย่างชัดเจน แต่ Arrays.toString() ทำในสิ่งที่เราต้องการ อย่างไรก็ตาม ปัญหาของเราเกี่ยวกับการคัดลอกก็แก้ไขได้อย่างง่ายดายในชั้นเรียนเช่นกันArrays
:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOf(numbers, numbers.length);
System.out.println(Arrays.toString(numbersCopy));
}
}
ไปยังวิธีที่Arrays.copyOf()
เราส่งผ่านอาร์เรย์ดั้งเดิมของเรา (ซึ่งเราต้องคัดลอกค่า) และความยาวของอาร์เรย์ใหม่ที่เราคัดลอกข้อมูลไป ในกรณีนี้ เราระบุเป็นความยาวnumbers.length
เนื่องจาก เราต้องการคัดลอกอาร์เรย์ทั้งหมด หากเราต้องการคัดลอกเฉพาะองค์ประกอบแรกๆ เราสามารถระบุความยาวที่น้อยลงสำหรับอาร์เรย์ใหม่ได้:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOf(numbers, 4);
System.out.println(Arrays.toString(numbersCopy));
}
}
ที่นี่เราได้ระบุความยาวของอาร์เรย์ใหม่เป็น 4 ดังนั้นเฉพาะ 4 องค์ประกอบแรกเท่านั้นnumbers
ที่จะถูกคัดลอกไปยังอาร์เรย์ใหม่ เอาต์พุตคอนโซล:
[167, -2, 16, 99]
อย่างไรก็ตาม หากคุณต้องการคัดลอกส่วนหนึ่งของอาร์เรย์ แต่ไม่ใช่จากจุดเริ่มต้น แต่ "จากตรงกลาง" Arrays
คุณก็สามารถทำได้เช่นกัน:
public class Main {
public static void main(String[] args) {
int[] numbers = {167, -2, 16, 99, 26, 92, 43, -234, 35, 80};
int [] numbersCopy = Arrays.copyOfRange(numbers, 2,6);
System.out.println(Arrays.toString(numbersCopy));
}
}
บทสรุป:
[16, 99, 26, 92]
คัดลอก ตัวเลขจากเซลล์สอง ( รวม ) ถึงหก ( ไม่รวม ) ลงในอาร์เรย์ใหม่ นอกจากนี้ เราอาจจำเป็นต้องเปรียบเทียบสองอาร์เรย์ด้วยกัน เช่นเดียวกับวิธีการนี้toString()
ตัวอาร์เรย์เองจะไม่แทนที่วิธีการequals()
นั้น ดังนั้นหากเราลองเปรียบเทียบกันดังนี้:
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
int[] numbers2 = {1, 2, 3};
System.out.println(numbers.equals(numbers2));
}
}
false
เราได้ รับ ผลลัพธ์ Object.equals()
ท้ายที่สุดแล้ววิธีการ เปรียบเทียบลิงก์จะถูกเรียกว่า และแน่นอนว่ามันแตกต่างออกไป! แต่เราจำเป็นต้องเปรียบเทียบเนื้อหาของอาร์เรย์ ไม่ใช่ลิงก์ คลาสนี้Arrays
มีเมธอดที่ถูกแทนที่equals()
ซึ่งทำสิ่งที่เราต้องการ:
public class Main {
public static void main(String[] args) {
int[] numbers = {1, 2, 3};
int[] numbers2 = {1, 2, 3};
System.out.println(Arrays.equals(numbers, numbers2));
}
}
บทสรุป:
true
อย่างไรก็ตามคลาสArrays
ทำงานได้สำเร็จไม่เพียง แต่กับอาร์เรย์ธรรมดาเท่านั้น แต่ยังใช้กับอาร์เรย์สองมิติด้วย:
public class Main {
public static void main(String[] args) {
int[][] numbers = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[][] numbersCopy = Arrays.copyOf(numbers, numbers.length);
System.out.println("Are these two-dimensional arrays equal to each other?");
System.out.println(Arrays.deepEquals(numbers, numbersCopy));
System.out.println(Arrays.deepToString(numbersCopy));
}
}
บทสรุป:
Равны ли эти двумерные массивы между собой?
true
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
อย่างที่คุณเห็นวิธีArrays.copyOf()
การจัดการกับการคัดลอกอาเรย์สองมิติ โปรดทราบว่าในกรณีนี้ เมื่อคัดลอกอาร์เรย์สองมิติ จะเกิดสิ่งที่เรียกว่า "สำเนาตื้น" และสำหรับการเปรียบเทียบอาร์เรย์สองมิติและส่งออกไปยังคอนโซล จะมีการจัดเตรียมวิธีการพิเศษไว้ - deepEquals
และdeepToString()
; ในอนาคต คุณจะเห็นมากกว่าหนึ่งครั้ง (และพอใจกับสิ่งนี้) ที่ผู้สร้าง Java มองเห็นสถานการณ์ทั่วไปมากมายที่โปรแกรมเมอร์พบเมื่อทำงาน และนำโซลูชันสำเร็จรูปมาใช้กับพวกเขาในภาษา การใช้โซลูชั่นเหล่านี้ง่ายกว่าและสะดวกกว่าการประดิษฐ์ล้อใหม่มากใช่ไหม? :) อย่าลืมอ่านเอกสารประกอบของชั้นเรียนบนArrays
เว็บไซต์Oracle ขอให้โชคดีกับการเรียนของคุณ!
GO TO FULL VERSION