1. สำหรับการพิจารณาประสิทธิภาพ แนะนำให้ใช้อาร์เรย์
อาร์เรย์ถูกใช้น้อยลงในการพัฒนาโครงการ โดยเฉพาะอย่างยิ่งในการพัฒนาเชิงธุรกิจ ประการแรก อาร์เรย์ไม่มีวิธีการมากมายจากคอลเลกชัน เช่น รายการและการตั้งค่า คุณต้องเขียนอัลกอริทึมการค้นหาและการบวกด้วยตัวเอง ซึ่งก็คือ ยุ่งยากและลำบากมาก อย่างไรก็ตาม เนื่องจากคอลเลกชันเช่น List และ Set ใช้การสนับสนุนทั่วไป ทั้งหมดจึงถูกจัดเก็บไว้ในคลาส wrapper และอาร์เรย์สามารถใช้ประเภทข้อมูลพื้นฐานได้ ความเร็วในการดำเนินการของประเภทข้อมูลพื้นฐานนั้นเร็วกว่าประเภท wrapper มาก และชั้นล่างสุดของคลาสคอลเลกชัน มันยังถูกนำไปใช้ผ่านอาร์เรย์ด้วย
2. หากจำเป็น ให้ใช้อาร์เรย์ที่มีความยาวผันแปรได้
เมื่อเรียนรู้คลาสคอลเลกชั่น หลายๆ คนชอบที่จะเปรียบเทียบความยาวคงที่ของอาร์เรย์กับความยาวผันแปรของประเภทคอลเลคชัน แต่จริงๆ แล้วการเปรียบเทียบนี้ไม่เหมาะสม เมื่อพิจารณาถึงการใช้งานคลาสคอลเลคชัน เช่น ArrayList เราจะเห็นสิ่งนั้นได้จริง สิ่งที่เรียกว่าคอลเลกชันจะยาวขึ้น จริงๆ แล้ว มันแค่ขยายอาเรย์ดั้งเดิมอย่างมีไหวพริบ
คัดลอกรหัสรหัส ดังต่อไปนี้:
สาธารณะคงที่ T [] ข้อมูลขยายความจุ (T [], int newLength) {
// พิจารณาว่าเป็นค่าลบหรือไม่
newLength = newLength < 0 ? 0 : newLength;
// สร้างอาร์เรย์ใหม่ คัดลอกค่าเดิมและระบุความยาว
กลับ Arrays.copyOf (ข้อมูล, newLength);
-
เมื่อข้อกำหนดด้านประสิทธิภาพอยู่ในระดับสูง คุณสามารถพิจารณาการห่อหุ้มอาร์เรย์ได้ ความยาวคงที่ของอาร์เรย์ไม่ใช่ข้อแก้ตัวสำหรับเราที่จะไม่ใช้พวกมัน
3. ระวังสำเนาอาร์เรย์ที่ตื้น
สำเนาตื้นของอาร์เรย์ยังเป็นพื้นฐานของการเขียนโปรแกรม Java สำเนาตื้นหมายความว่าเมื่อคัดลอกอาร์เรย์ ประเภทพื้นฐานจะคัดลอกค่า ในขณะที่ประเภทอ้างอิงจะคัดลอกที่อยู่อ้างอิง ในตัวอย่างข้างต้น อาร์เรย์จะถูกคัดลอกโดยใช้ Arrays.copyOf เป็นสำเนาตื้น ๆ ดังนั้นคุณต้องใส่ใจเมื่อใช้งาน
4. ภายใต้สถานการณ์ที่ชัดเจน ให้ระบุกำลังการผลิตเริ่มต้นสำหรับคอลเลกชัน
ในการใช้งานประจำวันของเรา เนื่องจากประเภทคอลเลกชันจะเปลี่ยนความยาวโดยอัตโนมัติ ค่าเริ่มต้นจะไม่ถูกแนบไปกับคลาสคอลเลกชันเมื่อสร้างวัตถุ ลองใช้ ArrayList ที่เราใช้งานบ่อยที่สุดเป็นตัวอย่างก่อน ถึงความจุแล้ว ณ จุดวิกฤติ อาเรย์พื้นฐานจะเป็น การดำเนินการ copyOf จะสร้างอาร์เรย์ใหม่และความจุของอาร์เรย์ใหม่คือ 1.5 เท่าของอาร์เรย์เก่า และความยาวอาร์เรย์เริ่มต้นคือ 10 เมื่อเรารู้ชัดเจนว่าจำนวนข้อมูลที่จะใส่ในคอนเทนเนอร์นั้นมีมาก เราควรระบุค่าเริ่มต้นเพื่อหลีกเลี่ยงค่าใช้จ่ายด้านประสิทธิภาพที่มากเกินไปซึ่งเกิดจากการใช้เวลา copyOf
5. เลือกอัลกอริธึมที่เหมาะสมที่สุดที่เหมาะสม
การค้นหาค่าสูงสุดหรือค่าต่ำสุดของข้อมูลเป็นความรู้พื้นฐานที่สุดเกี่ยวกับโครงสร้างข้อมูล นอกจากนี้เรายังมีหลายวิธีในการนำไปใช้ใน Java ต่อไปนี้เป็นอัลกอริธึมสองประการ:
คัดลอกรหัสรหัส ดังต่อไปนี้:
int สาธารณะ getMaxByArray (ข้อมูล int []) {
//วิธีค้นหาที่ดำเนินการด้วยตนเองที่ง่ายที่สุด
int สูงสุด = ข้อมูล [0];
สำหรับ (int i = 1, size = data.length; i < size; i++) {
สูงสุด = สูงสุด < ฉัน ? ฉัน : สูงสุด;
-
กลับสูงสุด;
-
คัดลอกรหัสรหัส ดังต่อไปนี้:
int สาธารณะคงที่ getMaxByArray (ข้อมูล int []) {
// เรียงลำดับก่อนแล้วจึงได้บิตสุดท้าย
Arrays.sort (ข้อมูล);
ส่งคืนข้อมูล [data.length - 1];
-
6. กับดักการแปลงอาร์เรย์ประเภทพื้นฐาน!
โปรดสังเกตรหัสต่อไปนี้
คัดลอกรหัสรหัส ดังต่อไปนี้:
โมฆะคงที่สาธารณะ main (String [] args) {
int[] nums = ใหม่ int[] { 1, 2, 3, 4, 5 };
รายการ รายการ = Arrays.asList(nums);
System.out.println(list.size());
//ขนาดเอาต์พุตในขณะนี้คือ 1
-
ผลลัพธ์ที่เราคาดหวังคือการแปลงองค์ประกอบในอาเรย์ให้เป็นคลาสคอลเลกชันผ่าน Arrays.asList แต่ตรงกันข้ามกับที่คาดไว้ เราเพิ่มเฉพาะอาเรย์เท่านั้นและไม่ได้แยกค่าในอาเรย์ ในขณะนี้ หากคอลเลกชันการเพิ่มข้อมูลทั่วไปลงในรายการจะให้ข้อความแสดงข้อผิดพลาดระหว่างการคอมไพล์หรือการเปลี่ยนอาร์เรย์เป็น Integer สามารถแก้ปัญหาได้
7. รายการวัตถุที่สร้างโดยวิธี asList ไม่สามารถเปลี่ยนแปลงได้
จากตัวอย่างข้างต้น เราจะเห็นว่าการใช้เมธอด Arrays.asList สามารถแปลงอาร์เรย์เป็น List ได้ แล้วอะไรคือสิ่งที่พิเศษเกี่ยวกับ List ที่ส่งคืนโดยเมธอด asList โปรดทราบว่า List ที่ส่งคืนไม่รองรับการเปลี่ยนแปลงเนื่องจากเมธอด asList ส่งคืน ไม่ใช่ java.util.ArrayList แต่เป็น Array คลาสภายในส่วนตัวแบบคงที่ในคลาสเครื่องมือ s แม้ว่าจะมีคลาสพาเรนต์เดียวกัน AbstractList เป็น ArrayList แต่เมื่อแทนที่การเพิ่มและวิธีการอื่น UnsupportedOperationException จะถูกส่งออกไป คลาสภายในส่วนตัวแบบคงที่นี้จะใช้ขนาด toArray, Get เท่านั้นที่มีสิ่งเหล่านี้ วิธีการ
8. ใช้วิธีการสำรวจที่แตกต่างกันสำหรับโครงสร้างข้อมูลที่แตกต่างกัน
โปรดดูรหัสต่อไปนี้
คัดลอกรหัสรหัส ดังต่อไปนี้:
โมฆะคงที่สาธารณะ main (String [] args) {
//ต่อไปนี้เป็นวิธีการสำรวจเส้นทางของคอลเลกชัน ArrayList
จำนวน int = 80 * 10,000;
รายการ arrayList = ใหม่ ArrayList(num);
สำหรับ (int i = 0, size = arrayList.size(); i < size; i++) {
arrayList.get(i);
-
//ต่อไปนี้เป็นวิธีการสำรวจเส้นทางของคอลเลกชัน LinkedList
รายการ linkedList = ใหม่ LinkedList();
สำหรับ (จำนวนเต็ม จำนวนเต็ม : linkedList) {
-
-
เหตุใดจึงเลือกวิธีสำรวจเส้นทางที่แตกต่างกันสำหรับ LinkedList และ ArrayList
1. เนื่องจาก ArrayList ใช้อินเทอร์เฟซ RamdomAccess (อินเทอร์เฟซการเข้าถึงแบบสุ่ม) อินเทอร์เฟซ RamdomAccess จึงเป็นอินเทอร์เฟซการทำเครื่องหมายเดียวกันใน Java เป็นอินเทอร์เฟซแบบอนุกรมและแบบ Cloneable ซึ่งหมายความว่าคลาสนี้สามารถเข้าถึงได้แบบสุ่ม สำหรับ ArrayList หมายความว่ามีระหว่างข้อมูล ไม่มีความสัมพันธ์กัน กล่าวคือ ตำแหน่งสองตำแหน่งที่อยู่ติดกันไม่มีความสัมพันธ์แบบพึ่งพาอาศัยกัน และสามารถเข้าถึงได้แบบสุ่ม
2. ไวยากรณ์ foreach ใน Java เป็นการใช้งานที่แตกต่างกันของตัววนซ้ำ (ตัววนซ้ำ) เรารู้ว่าตัววนซ้ำเป็นหนึ่งใน 23 รูปแบบการออกแบบ แต่ตัววนซ้ำจำเป็นต้องทราบความสัมพันธ์ของเวลาระหว่างสององค์ประกอบ ไม่เช่นนั้นจะให้การสนับสนุน hasNext ได้อย่างไร เป็นเพราะองค์ประกอบก่อนหน้านี้จำเป็นต้องพิจารณาว่ามีองค์ประกอบถัดไปอยู่หรือไม่ และความสัมพันธ์นี้ถูกสร้างขึ้นโดยการบังคับ ซึ่งละเมิดลักษณะพิเศษของการเข้าถึงแบบสุ่ม ArrayList
3. ใน LinkedList เนื่องจากถูกจัดเก็บในรูปแบบของรายการที่มีการเชื่อมโยงแบบทวีคูณ การรองรับตัววนซ้ำจึงดีมาก เนื่องจากมีความสัมพันธ์โดยธรรมชาติระหว่างองค์ประกอบสองรายการที่อยู่ติดกันใน LinkedList จึงต้องใช้วิธีสำรวจเส้นทางที่แตกต่างกันสำหรับ LinkedList และ ArrayList ผู้อ่านที่สนใจสามารถลองเข้าถึง LinkedList ในรูปแบบของตัวห้อย และจะพบว่ามีช่องว่างขนาดใหญ่ในด้านประสิทธิภาพระหว่างทั้งสอง
8. เลือก ArrayList หรือ LinkedList เมื่อเหมาะสม
ความแตกต่างที่สำคัญระหว่าง ArrayList และ LinkedList:
1. โครงสร้างข้อมูลพื้นฐานของ ArrayList คืออาร์เรย์ ในขณะที่โครงสร้างพื้นฐานของ LinkedList เป็นรายการที่เชื่อมโยงแบบทวีคูณ
2. เมื่อแทรกข้อมูล เนื่องจาก ArrayList จำเป็นต้องย้ายองค์ประกอบอาร์เรย์ไปข้างหลังหลังจากการแทรกแต่ละครั้ง LinkedList จำเป็นต้องเปลี่ยนโหนดส่วนหัวและโหนดส่วนท้ายเท่านั้นเพื่อให้การดำเนินการแทรกเสร็จสมบูรณ์ ดังนั้นเมื่อการดำเนินการแทรกบ่อยขึ้น LinkedList จึงเป็นทางเลือกที่ดีกว่า
3. เมื่อลบข้อมูล เนื่องจาก ArrayList จำเป็นต้องรักษาลำดับของอาร์เรย์ องค์ประกอบจึงต้องถูกเลื่อนไปข้างหน้าหรือข้างหลังหลังจากการลบ ในขณะที่ LinkedList ยังคงเปลี่ยนโหนดส่วนหัวและส่วนท้าย
4. เมื่ออัปเดต เนื่องจาก LinkedList จะใช้วิธีสำรวจครึ่งทางเพื่อค้นหาองค์ประกอบที่มีตำแหน่งแล้วอัปเดต เมื่อเปรียบเทียบกับการแทนที่องค์ประกอบตัวห้อยที่มีตำแหน่งโดยตรงของ ArrayList ArrayList จึงมีประสิทธิภาพมากกว่าในการอัปเดต
5.LinkedList สามารถจำลองคิวผ่านการดำเนินการ เช่น addFirst และ addLast ของ LinkedList
9. เมื่อรายการเท่ากัน คุณเพียงแค่ต้องสนใจข้อมูลองค์ประกอบเท่านั้น
เพื่อให้เราสามารถโปรแกรมอินเทอร์เฟซเช่น List, Set และ Map ได้อย่างสบายใจ Java ได้แทนที่ equlas ในคลาสคอลเลกชัน ดังนั้นเมื่อเปรียบเทียบว่าสองคอลเลกชันเท่ากันหรือไม่ เราเพียงต้องเปรียบเทียบว่าข้อมูลองค์ประกอบเท่ากันหรือไม่ วิธีนี้จะหลีกเลี่ยงการแก้ไขโค้ด Java ที่ผิดพลาดซึ่งเกิดจากการแทนที่คลาสการใช้งานคอลเลกชัน
คัดลอกรหัสรหัส ดังต่อไปนี้:
โมฆะคงที่สาธารณะ main (String [] args) {
รายการ arrayList = ใหม่ ArrayList();
arrayList.เพิ่ม(1);
arrayList.เพิ่ม(2);
รายการ linkedList = ใหม่ LinkedList();
linkedList.เพิ่ม(1);
linkedList.เพิ่ม(2);
System.out.println(arrayList.equals(linkedList));
// ไม่สนใจการใช้งานเฉพาะเจาะจง ผลลัพธ์จะเป็นจริง
-