1 / 35

ArrayList

ArrayList. คล้าย array แต่ไม่เหมือน. ใช้ index ในการเข้าถึงสมาชิกแต่ละตัวได้ จัดการขยายขนาดได้เองโดยอัตโนมัติ มีเมธอดสำหรับใส่ของในอาร์เรย์ตรงไหนก็ได้ เมธอดนั้นเป็นไปตาม List Interface แต่ก็มีเมธอดของมันเองด้วย clone ensureCapacity trimToSize ใส่ได้แต่ Object เท่านั้น.

sonel
Download Presentation

ArrayList

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ArrayList

  2. คล้าย array แต่ไม่เหมือน • ใช้ index ในการเข้าถึงสมาชิกแต่ละตัวได้ • จัดการขยายขนาดได้เองโดยอัตโนมัติ • มีเมธอดสำหรับใส่ของในอาร์เรย์ตรงไหนก็ได้ • เมธอดนั้นเป็นไปตาม List Interface แต่ก็มีเมธอดของมันเองด้วย • clone • ensureCapacity • trimToSize • ใส่ได้แต่ Object เท่านั้น

  3. ตัวอย่างเมธอด • public ArrayList(int initialCapacity) • Throw IllegalArgumantException ถ้า initialCapacity <0 • ArrayList<String>name = new ArrayList<String>(100); • ถ้าเราไม่บอกขนาด อาร์เรย์ลิสต์ที่สร้างจะจุได้ 10 สมาชิก

  4. คอนสตรัคเตอร์อีกแบบ • public ArrayList(Collection<? Extends E> c) • เอาของจาก c มาใส่ในอาร์เรย์ลิสต์ของเราที่สร้างใหม่ • ลำดับของสมาชิกก็เอาตามลำดับสมาชิกของ c • อาร์เรย์ลิสต์ที่สร้างจะมีขนาด 110% ของ c • Worst time = O(n) • ชนิดของสมาชิกจาก c ต้องเป็นชนิดเดียวกับในอาร์เรย์ลิสต์ หรือไม่ก็ต้องเป็นสับคลาส • ถ้าเรามี womanList ซึ่งจุของประเภท Woman ซึ่งเป็นสับคลาสของ People • เราสามารถสร้าง อาร์เรย์ลิสต์ของ People ได้จาก womanList • ArrayList<People>a = new ArrayList<People>(womanList);

  5. จริงๆแล้วเป็นการสร้างพอยต์เตอร์ไปยังของใน c เท่านั้น นี่ถือว่าเป็น shallow copy แบบหนึ่ง • อีกแบบคือใช้เมธอด clone() • ArrayList<People>a = (ArrayList<People>)womanList.clone(); • Shallow copy มี reference ต่างหากจากตัวต้นฉบับ แต่ถ้าภายในมีออบเจ็กต์ พอยต์เตอร์ของออบเจ็กต์นั้นจะชี้ไปที่สิ่งเดียวกับต้นฉบับ • จะไม่เหมือนกับการใช้ a = womanList; เพราะอันนี้จะให้ a ชี้ไปที่ womanList เลย

  6. Shallow copy womanList w1 w3 w2 a

  7. womanList MRS.X w1 w2 w3 a MR.A.J. Shallow copy (2) • จากหน้าที่แล้ว ถ้าเราเรียกใช้ • womanList.add(new People(“MRS.X”)); กับ • a.add(new People(“MR.A.J.”)) จะได้

  8. new ArrayList<People>(womanList); กับ • (ArrayList<People>)womanList.clone(); • จริงๆจะต่างกันนิดนึง • การโคลนจะได้จำนวนช่องอาร์เรย์เท่าเดิม • แต่การใช้ copy constructor อาร์เรย์จะมีขนาด 110% เทียบกับของเดิม

  9. อาร์เรย์ธรรมดาก็มีการก็อปปี้อาร์เรย์ธรรมดาก็มีการก็อปปี้ • System.arraycopy(array1, i, array2, i2, 3); • ก็อปปี้จาก array1 ที่ indexi • ไปที่ array2 โดยเริ่มที่ index i2 • ก็อปปี้ไป 3 ตัว

  10. public boolean add(E element) • เอาของใส่ท้ายอาร์เรย์ลิสต์ • Worst time = O(n), Avg time = constant • รีเทิร์น true เมื่อของได้ถูกใส่จริงๆ (แบบนี้ก็ true ตลอด)

  11. public E get(int index) • รีเทิร์นสมาชิก ณ ตำแหน่งที่บอก • Throw indexOutOfBoundsException ถ้า size()<=index, หรือ index<0

  12. public E set(int index, E element) • แทนที่สมาชิกตัวที่ index ด้วย element • รีเทิร์นสมาชิกเก่าที่เก็บที่ index นี้ • Throw indexOutOfBoundsException ถ้า size()<=index หรือ index<0 • Worst time = constant

  13. public void add(int index, E element) • แทรก element เข้าไป ณ ตำแหน่ง index • สมาชิกตัวอื่นต้องเลื่อนตำแหน่งไป • Worst time = O(n) • Throw indexOutOfBoundsException ถ้า size()< index หรือ index<0

  14. public E remove(int index) • เอาสมาชิก ณ ตำแหน่ง index ออกไป • สมาชิกข้างขวาต้องเลื่อนมาแทนที่ • รีเทิร์นสมาชิกตัวที่เอาออก • Throw indexOutOfBoundsException ถ้า size()<=index หรือ index<0

  15. public int indexOf(Object element) • หาค่าที่เหมือนกับ element ตัวแรกในอาร์เรย์ลิสต์ • รีเทิร์น ดัชนีของค่านั้นในอาร์เรย์ลิสต์ หรือ -1 ถ้าหาไม่เจอ • เทียบค่าว่าเหมือนหรือไม่ด้วยเมธอด equals() • Worst time = O(n)

  16. ArrayList class heading • public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable • มีฟิลด์ • private transient E[ ] elementData; • Transient หมายถึงไม่เซฟตัวอาร์เรย์ตอนทำ serialization แต่เซฟสมาชิกนะ • private int size;

  17. ตัวอย่างโค้ดภายในคอนสตรัคเตอร์ตัวอย่างโค้ดภายในคอนสตรัคเตอร์ public ArrayList (int initialCapacity) { elementData = new Object [initialCapacity]; } public ArrayList ( ) { this (10); }

  18. public ArrayList(Collection<? extends E> c) { this((c.size()*110)/100); // โตขึ้น 10% Iterator i = c.iterator( ); while (i.hasNext( )) elementData[size++] = i.next(); }

  19. ตัวอย่างโค้ดภายใน เมธอด add(E element) public boolean add(E element){ ensureCapacity(size+1); //ขยายอาร์เรย์ถ้าจำเป็น elementData[size++] = element; return true; }

  20. public void ensureCapacity(int min) { modcount++; //ดูหน้าถัดไป int oldCapacity = elementData.length; if(min>oldCapacity){ //ความจุใหม่ใหญ่กว่าเก่า E oldData[] = elementData; int newCapacity = (oldCapacity*3)/2+1; //ให้ขยาย 50% if(newCapacity < minCapacity) //ถ้ายังขยายไม่พอ newCapacity = min; // ก็ให้ขนาดตามอินพุตไปเลย elementData = (E) new Object[newCapacity]; System.arrayCopy(oldData,0,elementData,0,size); } }

  21. modCount • มีในแต่ละคลาส ArrayList, LinkedList, TreeMap, TreeSet, HashMap, HashSet • ของ ArrayList นั้น inherit มาจาก AbstractList • เปลี่ยนค่าเมื่อมีการเปลี่ยนแปลงคือมีการ insert หรือ remove จาก ArrayList นี้ • อิเทอเรเตอร์แต่ละตัวก็มี expectedModCount ต่างหาก • เปลี่ยนค่าเมื่ออิเทอเรเตอร์ตัวนั้นเปลี่ยนของในคอลเลคชั่น เช่น itr.remove() • modCount ก็จะเปลี่ยนด้วย • ถ้าสองฟิลด์นี้ไม่เท่ากันเมื่อไร แสดงว่ามีการเปลี่ยนคอลเลคชั่นด้วยเมธอดที่ไม่ใช่ของอิเทอเรเตอร์ระหว่างที่อิเทอเรเตอร์มีการใช้งานอยู่ เช่นเปลี่ยนโดยเทรดอื่น • ทุกๆการเปลี่ยนแปลงของอิเทอเรเตอร์เอง จะมีการเรียกใช้ if (modCount!=expectedModCount) throw new ConcurrentModificationException(); Fail fast

  22. modCount & expectedModCount (ต่อ) ตัวอย่างการใช้อิเทอเรเตอร์ที่ไม่ดี public ModCountDriver( ) { ArrayList list = new ArrayList( ); list.add (“yes”); Iterator itr = list. iterator( ); list.add (“good”); itr.next( ); // exception thrown at this point } สร้างอิเทอเรเตอร์ modCount++, แต่ expectedModCount เท่าเดิม next นี่จึงใช้ไม่ได้

  23. เวลาของ ensureCapacity • Worst time = การก็อปปี้อาร์เรย์ = O(n) • Avg time = • ต้องเรียก add ไป n/3 ครั้งก่อน ถึงจะมีการก็อปปี้อาร์เรย์ • ฉะนั้น ต้องเรียก add ไป (n/3)+1 ครั้ง จึงจะเกิดการก็อปปี้ n สมาชิก • จำนวนการก็อปปี้ ต่อการเรียก add หนึ่งครั้งจึงเฉลี่ยเป็น n/((n/3)+1) • ประมาณ 3 ครั้ง • Avg time = constant

  24. โค้ดของเมธอดโคลน public Object clone() { try { ArrayList v = (ArrayList)super.clone(); // copies size v.elementData = new Object[size]; System.arraycopy(elementData, 0, v.elementData, 0, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } }

  25. ตัวอย่างการใช้งาน สมมติเราต้องการทำอะไรต่างๆดังนี้ • สร้าง ArrayList ซึ่งมี n สมาชิก • ลูป n ครั้ง ใส่สมาชิกซึ่งเป็น Double (i) โดย i เริ่มจาก 0 ลงไปท้ายลิสต์ • ใส่ new Double (7.8) ที่ index n/2 • เอาสมาชิกที่ตำแหน่ง 2n / 3 ทิ้งไป • เอา 2.5 คูณกับสมาชิกตัวกลางของลิสต์ • พริ้นต์ค่าภายในลิสต์ทั้งหมดออกมา

  26. 1 2 • public void processInput (String s) { • int n = Integer.parseInt (s); • ArrayList myList = new ArrayList (n); • for (int i = 0; i < n; i++) • myList.add (new Double (i)); • myList.add (n / 2, new Double (7.8)); • myList.remove (2 * n / 3); • double d = ((Double)myList.get (n / 2)).doubleValue( ) • * 2.5; • myList.set (n / 2, new Double (d)); • gui.println (myList) ; • } 3 4 5 6

  27. การใช้งาน ArrayList – VeryLongIntฟิลด์ในคลาส VeryLongInt • protected ArrayList<Integer> digits; • แต่ละสมาชิกจะมีเลขหนึ่งหลักเท่านั้น

  28. การใช้งาน ArrayList –VeryLongInt class • public VeryLongInt(String s) • สร้าง VeryLongInt ขึ้นมาจาก String • Throw NullPointerException ถ้า s == null • VeryLongInt a = new VeryLongInt(“5629?3”); • จะได้ค่า 56293 เก็บไว้ใน a • Worst time = O(string length) ไม่ใช่เลขจึงทิ้งได้

  29. โค้ดของ VeryLongInt(String s) • ลูปไปตามคาแร็กเตอร์แต่ละตัว • ถ้าคาแร็กเตอร์เป็นตัวเลข ให้ลบด้วย ‘0’เพื่อให้ได้ค่าแท้จริงออกมา • เอาเลขที่ได้ใส่อาร์เรย์ลิสต์

  30. public VeryLongInt(String s){ final char LOWEST_DIGIT_CHAR = ‘0’; digits = new ArrayList<Integer>(s.length()); char c; int digit; for(int i = 0; i<s.length(); i++){ c = s.charAt(i); if(Character.isDigit(c)){ digit = c - LOWEST_DIGIT_CHAR; digits.add(digit); // auto convert } } } Avg time & worst time = O(n) Avg time = constant, Worst time = constant เพราะไม่มีการเปลี่ยนขนาด

  31. public String toString() • Return String ที่แทน VeryLongInt object นี้ • 56293 จะกลายเป็น [5,6,2,9,3] • Worst time = O(จำนวนหลักเลข) public String toString(){ return digits.toString();//เรียกใช้เมธอดของอาร์เรย์ลิสต์ }

  32. public void add(VeryLongInt otherVeryLong) • บวกสอง VeryLongInt • Worst time = O(จำนวนหลักเลขของตัวที่มีจำนวนหลักมากที่สุด) • Throw NullPointerException ถ้า otherVeryLong == null

  33. โค้ดของ add(VeryLongInt otherVeryLong) • บวกทีละหลัก เริ่มจากหลักหน่วย (เหมือนบวกเลขปกติ) เอาผลที่บวกแต่ละหลักนั้นใส่อาร์เรย์ลิสต์อีกตัวที่ชื่อว่า sumDigits • ถ้าเรามี 135 กับ 79 เราจะได้ผลใน sumDigits เป็น 412 เพราะว่าหลักหน่วยถูกนำไปใส่ sumDigits เสียก่อน ดังนั้นต้องมีการรีเวิร์สสมาชิกใน sumDigits • จะได้ 214 เป็นคำตอบที่แท้จริง

  34. public void add(VeryLongInt otherVeryLong){ final int BASE = 10; int largerSize, partialSum, carry = 0; ArrayList<Integer>sumDigits= new ArrayList<Integer>(); if(digits.size()>otherVeryLong.digits.size()) largerSize= digits.size(); else largerSize = otherVeryLong.digits.size(); for(int i=0; i<largerSize; i++){ partialSum = least(i) + otherVeryLong.least(i) + carry; carry = partialSum / BASE ; sumDigits.add(partialSum % BASE); } if(carry==1) sumDigits.add(carry); //ไงๆหลักสูงสุดก็มี carry ได้ค่าเดียว Collections.reverse(sumDigits); digits = sumDigits; } หลักที่ i เริ่มจากหลักหน่วย O(n) Constant time

  35. protected int least(int i){ if(i>=digits.size()) return 0; return digits.get(digits.size()-i-1); } Constant time

More Related