JavaRush /จาวาบล็อก /Random-TH /new ArrayList(????) จะเริ่มต้นอย่างไรและที่ไหนดีกว่ากัน
Vovan
ระดับ

new ArrayList(????) จะเริ่มต้นอย่างไรและที่ไหนดีกว่ากัน

เผยแพร่ในกลุ่ม
การเขียนโค้ดโดยไม่ใช้เฟรมเวิร์กคอลเลกชันคงจะบ้าไปแล้ว นี่เป็นส่วนที่ยอดเยี่ยมของ Java พร้อมด้วยโซลูชันที่ประณีตมากมาย ที่สำคัญกว่านั้น คุณไม่จำเป็นต้องกังวลเกี่ยวกับขนาด ซึ่งต่างจากอาร์เรย์ ArrayListจะขยายจนกว่าหน่วยความจำจะหมด นักพัฒนาไม่จำเป็นต้องกังวลเกี่ยวกับขนาดเริ่มต้นและ ข้อ ผิด พลาด ArrayIndexOutOfBoundsException แต่จะเกิดอะไรขึ้นถ้ามีเงื่อนไขในการตรวจสอบจำนวนหน่วยความจำ? เราสามารถใช้หน่วยความจำอย่างมีประสิทธิภาพเมื่อทำงานกับคอลเลกชันได้หรือไม่?
คำถามมาตรฐานเกิดขึ้น: จะเริ่มต้นรายการได้อย่างไร? รหัสด้านล่างจะไม่ทำงาน: มันจะส่งผลให้เกิดข้อผิดพลาดในการคอมไพล์: ชื่อ ตัวแปรท้องถิ่นอาจไม่ได้รับการ เตรียมใช้งาน ข้อกำหนดเฉพาะของ Java กำหนดให้ตัวแปรท้องถิ่นทั้งหมด (ซึ่งมีอยู่บนสแต็ก) ต้องเริ่มต้นด้วยค่าที่เหมาะสม นี่คือวิธีที่คุณสามารถทำได้: ไม่ต้องสงสัยเลยว่ารายการจะต้องเริ่มต้นได้ คุณสามารถสร้างรายการในบรรทัดแรกหรือทำบางอย่างที่ชาญฉลาดกว่าและใช้ การเริ่มต้นแบบ Lazy เหมือนที่เราทำใน เมธอด getAllNames( ) ในกรณีนี้ รายการจะถูกสร้างขึ้นเมื่อจำเป็นเท่านั้น - หากไม่ตรงตามเงื่อนไขเริ่มต้น รายการจะไม่ปรากฏบนฮีป เรามาถึงคำถามหลัก: เราควรกำหนดขนาดใดสำหรับรายการ? ทางเลือกที่ดีที่สุดคือระบุขนาดที่แน่นอนให้เขา ตัวอย่างเช่น: ในกรณีนี้ ต้องส่งคืนชื่อ nชื่อ และด้วยเหตุนี้ จึงมีการสร้างคอลเล็กชันขององค์ประกอบ n รายการ อย่างไรก็ตาม ค่าที่แน่นอนของ nไม่เป็นที่รู้จักเสมอไป แม้แต่ในตัวอย่างที่ให้มา จะเกิดอะไรขึ้นถ้า n=1000และมีชื่อให้เลือกเพียง 100 ชื่อเท่านั้น เมื่อทำงานกับคอลเลกชัน วิธีที่ได้รับความนิยมมากที่สุดคือการเรียกตัวสร้างเริ่มต้น หากคุณดูซอร์สโค้ด Java (เวอร์ชัน 1.6) อย่างที่คุณเห็น โดยค่าเริ่มต้นรายการองค์ประกอบ 10 รายการจะถูกสร้างขึ้น นั่นคือเราสามารถใช้ตัวสร้างเริ่มต้นได้อย่างปลอดภัยเมื่อเราไม่ได้วางแผนที่จะจัดเก็บองค์ประกอบมากกว่า 10 รายการในรายการ จะเกิดอะไรขึ้นถ้าคุณพยายามเพิ่มองค์ประกอบที่ 11? ไม่มีอะไรเลวร้าย... องค์ประกอบจะถูกเพิ่มสำเร็จ ดูที่วิธีการ: ขนาด ของอาร์เรย์ถูกควบคุมโดย วิธีการ SureCapacity ขนาดเพิ่มขึ้น 1.5เท่า อาร์เรย์ใหม่จะถูกสร้างขึ้นและองค์ประกอบต่างๆ จะถูกย้ายเข้าไปอยู่ในนั้น หากเราตั้งค่าขนาดเป็น 10 ดังนั้นในองค์ประกอบที่ 11:
public List getAllNames() { List names; if (/*необходимые условия выполнены*/) { names = new ArrayList (); /*заполнение списка*/ } return names; }
List names = null; List names = new ArrayList (); List names = new ArrayList (0); List names = new ArrayList (size);
public List getTopNames (int n) { List names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList (n); /*заполнение списка*/ } return names; }
names = new ArrayList ();

/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; } public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
  • ขนาดเปลี่ยนเป็น 10 * 3/2 + 1 = 16
  • เพิ่มขึ้นครั้งต่อไป = 16 * 3/2 + 1 = 25
  • เพิ่มขึ้นครั้งต่อไป = 25 * 3/2 + 1 = 39 และต่อๆ ไป
ในกรณีขององค์ประกอบ 100 รายการ JVMจะต้องสร้างอาร์เรย์ใหม่หลายครั้งและคัดลอกองค์ประกอบลงไป เมื่อคำนึงถึงสิ่งนี้ หากมีข้อสันนิษฐานเกี่ยวกับขนาดที่ต้องการของอาเรย์ จะเป็นการดีกว่าถ้าตั้งค่าความจุเริ่มต้นให้ใกล้เคียงกัน ต่อไปนี้เป็นแนวทางในการดำเนินการ:
  1. สร้างคอลเลกชันเฉพาะเมื่อคุณต้องการเท่านั้นไม่เช่นนั้นให้เริ่มต้นเป็นโมฆะหรือใช้Collections.EMPTY_LIST
  2. หากคุณทราบขนาดที่แน่นอนที่ต้องการให้ระบุในตัวสร้างคอลเลกชัน
  3. หากคุณแน่ใจว่าจำนวนองค์ประกอบจะไม่เกิน 10 คุณสามารถใช้ตัวสร้างเริ่มต้นได้ตามสบาย
  4. ความเสี่ยงที่เกี่ยวข้องกับการสร้างคอลเลกชันขนาดศูนย์คือความถี่ในการสร้างอาร์เรย์ใหม่และการคัดลอกข้อมูลอาจสูงขึ้น คุณต้องคิดอย่างรอบคอบว่าการใช้คอลเลกชันขนาดศูนย์จะมีประโยชน์มากหรือไม่
  5. หากคุณเริ่มต้นคอลเลกชันที่มีขนาดใหญ่เกินไปที่จุดเริ่มต้นของวิธีการและต้องการลดขนาดลง ก็จะมีเมธอดtrimToSize()
แน่นอนว่า แนวทางเหล่านี้นำไปใช้เมื่อทำงานกับคอลเลกชันแบบอาเรย์ และไม่มีสิ่งใดที่สมเหตุสมผลในกรณีของรายการที่เชื่อมโยง ในความเป็นจริง ปัญหาเหล่านี้ไม่น่าจะเป็นปัญหาของโปรแกรม แต่ถ้ามีโอกาสที่จะปรับปรุงให้ดีขึ้นอีกสักหน่อย ทำไมไม่ลองใช้มันดู คุณมีเคล็ดลับที่เป็นประโยชน์อื่น ๆ หรือไม่? คุณพบวิธีที่จะทำให้สิ่งต่าง ๆ ทำงานได้ดีขึ้นหรือไม่? หรือทั้งหมดนี้ไม่จำเป็น? คุณคิดอย่างไร?
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION