logo

Core Java Volume

Trong những ngôn ngữ lập trình nhìn chung, trong C bạn phải fix cỡ của tất cả các mảng ở thời gian dịch. Người lập trình ghét điều này bởi vì nó gây cho họ sự không thoải mái. Có bao nhiêu nhân viên sẽ ở một phòng? Chắc chắn không hơn 100. Điều j sẽ xảy ra nếu như phòng đó có 150 nhân viên? Bạn có muốn lãng phí 90 entries cho các phòng với chỉ có 10 nhân viên?
Source: Core Java Volume 1 (Chapter 5 ­ Generic array list). * Tiện lợi khi dùng array list ­­> nó tự động giãn mảng nếu số lượng các elements là quá  capacity. Nó sẽ tự động tạo 1 array có storage lớn hơn sau đó copy toàn bộ các elements sang  mảng mới.  ­ Có thể trimToSize ­­> bỏ storage tới size của array. Nếu như thêm 1 element mới vào nó sẽ rellocate ­­> vì vậy cần chú ý trước khi dùng this statement. ­ Có thể ensureCapacity ­­> chắc chắn là chỉ chứa 1 số lượng cố định, n ­ 1 array list có sức chứa 100 nhưng lúc ban đầu nó có thể không giữ 1 elements nào cả sau khi  khởi tạo. * Xử lý các elements trong array list. ­ Bạn phải chỉ rõ kích cỡ của mảng. ­ Bạn sử dụng add để add nhiều elements mà bạn muốn. ­ Bạn sử dụng size() thay vì sử dụng length để đếm số phần tử. ­ Bạn sử dụng a.get(i) thay vì xử dụng a để xử lý thành phần. ­ Bạn sử dụng set ­­> replace, not for add. Đến đây tự hỏi tại sao ko dùng vector mà lại dùng array list. Vì lý do như sau: ­ Khi dùng câu lệnh a=b, với a, b là vector thì a sẽ tạo ra 1 vector mới có capacity = capacity của   b. Rồi copy các elements từ b ­­> a ­ Trong khi đó với array list thì a và b cùng trỏ tới 1 array list. * Khả năng tương thích giữa kiểu và Array Lists.  ­­­­­­­­­­­­­­­­­­­­­­ More detail ­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Trong những ngôn ngữ lập trình ­ nhìn chung, trong C ­ bạn phải fix cỡ của tất cả các mảng ở thời gian dịch. Người lập trình ghét điều này bởi vì nó gây cho họ sự không thoải mái. Có bao  nhiêu nhân viên sẽ ở một phòng? Chắc chắn không hơn 100. Điều j sẽ xảy ra nếu như phòng đó  có 150 nhân viên? Bạn có muốn lãng phí 90 entries cho các phòng với chỉ có 10 nhân viên? Trong Java, tình huống này đã trở nên tốt hơn. Bạn có thể thiết lập cỡ của 1 mảng ở thời gian  chạy. int actualSize = ...; Employee[] staff = new Employee[actualSize]; Tất nhiên, code này không phải là hoàn toàn giải quyết được vấn đề định nghĩa mảng động ở thời gian chạy. 1 lần bạn thiết lập cỡ của mảng, bạn không thể thay đổi 1 cách dễ dàng. Thay  vào đó, một cách tốt nhất trong Java với tình huống này là sử dụng class Java khác, được gọi là  ArrayList. Class ArrayList thì tương tự với 1 mảng nhưng nó tự động điều chỉnh sức chưa của nó  khi bạn thêm và xoá các elements mà bạn không cần viết thêm bất cứ code nào. Trong JDK 5.0, ArrayList là class generic với kiểu tham số. Để chỉ rõ kiểu của các objects mà  array list nắm giữ, bạn bổ sung thêm dấu đóng ngoặc nhọn, ví dụ ArrayList. Bạn sẽ thấy ở Chương 13 cách định nghĩa 1 class generic riêng của bạn nhưng bạn không cần biết  nhưng công nghệ được sử dụng trong kiểu ArrayList. Ở đây chúng ta khai báo và xây dựng 1 list mảng các objects Employee: ArrayList staff = new ArrayList(); NOTE: Trước JDK 5.0, không có các generic classes. Thay vào đó, chỉ có 1 class ArrayList "1  vừa với tất cả" giữ các elements có kiểu Object. Nếu bạn phải sử dụng phiên bản cũ của Java,  đơn giản là bản xoá hết các . Bạn có thể sử dụng ArrayList mà không cần có  trong  JDK5.0 và sau này. Nó được xem là kiểu thô mà tham số được xoá. NOTE: Trong các phiên bản cũ của ngôn ngữ lập trình Java, các lập trình viên sử dụng class  Vector đối với các mảng động. Tuy nhiên, ArrayList thì hiệu quả hơn và không có lý do j tốt hơn  để sử dụng class Vector. Bạn sử dụng method add để add các elements vào array list. Ví dụ, đây là cách bạn xác định  các objects employee: staff.add(new Employee("Harry Hacker", ...)); staff.add(new Employee("Tony Tester", ...)); Array List quản lý 1 mảng mà object trỏ tới. Thậm chí, mảng đó chạy ngoài khoảng. Đây là nơi  mà các array list làm việc một cách linh động của chúng: Nếu bạn gọi add và mảng bên trong  đầy thì array list tự động tạo ra 1 mảng lớn hơn và copies tất cả các objects từ mảng nhỏ hơn  sang mảng lớn hơn. Nếu bạn biết hoặc có dự đoán tốt, có bao nhiêu thành phần bạn muốn lưu giữ thì gọi  ensureCapacity trước khi lấp đầy array list: staff.ensureCapacity(100); Nó sẽ xác định 100 objects bên trong mảng. Bạn có thể truyền sức chứa vào hàm dựng ArrayList: ArrayList staff = new ArrayList(100); CAUTION  Xác định 1 array list: new ArrayList(100) // sức chứa là 100 không có cùng phân phối với 1 mảng mới như: new Employee[100] //size là 100 Có sự khác nhau quan trọng giữa sức chứa của 1 array list và cỡ của mảng. Nếu bạn phân phối  1 mảng với 100 entries thì mảng có 100 slots, sẵn sàng cho việc sử dụng. Array list với sức  chứa 100 elements có tiềm năng giữ 100 elements (và thực ra nhiều hơn 100), nhưng khi bắt  đầu, thậm chí sau khi khởi tạo, array list không nắm giữ elements nào cả. Method size trả về số cả elements thực trong array list. Ví dụ: staff.size(); trả về số các elements hiện tại trong array list staff. Đây là tương tự với mảng a: a.length 1 lần bạn chắc chắn rằng array list là cố định, bạn có thể gọi method trimToSize. Method này  điều chỉnh cỡ của bộ nhớ để sử dụng để sử dụng 1 cách chính xác để có khoảng bộ nhớ vừa  với số các elements hiện thời.  1 lần bạn trim cỡ của array list, thêm 1 elements mới sẽ chuyển khối lại, sẽ mất thời gian. Bạn  nên chỉ sử dụng trimToSize khi bạn chắc chắn bạn không sử dụng thêm bất kì elements nào  vào trong array list nữa. C++ Note: class ArrayList thì tương tự với vector trong C++. Cả ArrayList và vector là các kiểu  generic. Nhưng vector C++ overload toán tử [] để thuận tiện trong việc xử lý element. Bởi vì Java  không có overloading toán tử, nó phải sử dụng tường minh. Hơn nữa, C++ vector được copy giá  trị. Nếu a và b là 2 vectors thì khi gán a=b thì a sẽ tạo 1 vector mới với độ dài bằng b và tất cả các elements được copy từ b sang a. Việc gán trong Java là cả a và b cùng trỏ tới 1 array list. java.util.ArrayList 1.2 ­ ArrayList() xây dựng 1 array list rỗng. ­ ArrayList(int initialCapacity)  xây dựng 1 array list với sức chứa cụ thể. Tham số: initialCapacity khởi tạo sức chứa của array list ­ boolean add(T obj)  thêm 1 element vào cuối của array list. Trả về true. Tham số: obj ­ element được added. ­ int size()  trả về số các elements được lưu giữ trong array list. (Nó ko bao h lớn hơn sức chứa của array  list). ­ void ensureCapacity(int capacity) bảo đảm rằng array list có sức chứa để lưu giữ số các elements mà ko cần định vị lại mảng lưu  giữ bên trong nó. Tham số: capacity ­ sức chứa mong muốn. ­ void trimToSize()  giảm sức chứa lưu giữ của array list về kích cỡ hiện tại của nó.    ử  1. X    lý các elements trong    array list.    Không may thay, ko có j là free. Sự tự động trưởng thành thuận tiện cho việc array list dành cú  pháp phức tạp hơn để xử lý các elements. Lý do là class ArrayList không phải là một phần trong  ngôn ngữ lập trình Java, nó chỉ là lợi ích được lập trình bởi vài người và cung cấp trong bộ thư viện chuẩn. Thay vì sử dụng [] để xử lý hay thay đổi các element của 1 mảng, bạn sử dụng method get và  set. Ví dụ, để set element thứ i, bạn sử dụng: staff.set(i, harry); Nó cân bằng với: a = harry; đối với mảng a. (Giống với mảng, chỉ số index bắt đầu từ 0). Để lấy 1 element trong array list, sử dụng: Employee e = staff.get(i); Nó giống với: Employee e = a; Trong JDK 5.0, bạn có thể sử dụng vòng lặp for each với array lists: foreach(Employee e:staff) //do something with e Vòng lặp ứng với for sẽ được viết: for(int i=0; ilist.add(x); } Khi bạn làm, sử dụng method toArray để copy các elements thành 1 mảng. X[] a = new X[list.size()]; list.toArray(a); Caution: Không gọi list.set(i, x) cho đến khi cỡ của array list lớn hơn i. Ví dụ nhìn code lỗi sau: ArrayList list = new ArrayList(100); // sức chứa là 100, size là 0 list.set(0, x); // no element 0 yet Sử dụng method add thay vì dụng set để lấp 1 mảng và sử dụng set chỉ khi dùng thay thể element đã được add. Thay vì bổ sung các elements vào cuối của array list, bạn có thể thêm vào giữa chúng. int n = staff.size()/2; staff.add(n, e); Các elements ở vị trí n và trên được tạo room dành cho new entry. Nếu cỡ mới của array list sau   khi chèn vượt quá sức chứa thì array list realllocate chỗ chứa mảng của nó. Đơn giản, bạn có thể remove 1 element từ giữa của 1 array list. Employee e = staff.remove(n); Các elements ở phía trên sẽ được copy xuống dưới, cỡ của mảng giảm đi 1. Chèn và remove các elements không hiểu quả. Nó ko có j quá lo lắng với các array list nhỏ.   Nhưng nếu bạn lưu giữ nhiều các elements và thường xuyên thêm và remove giữa, xem như sử dụng linked list. Chúng tôi sẽ giải thích về linked list trong Volume 2. Ví dụ 5­4 là sự thay đổi của chương trình EmployeeTest trong chương 4. Mảng Employee[]   được thay thế bởi  ArrayList. Chú ý những sự thay đổi sau: ­ Bạn phải chỉ rõ kích cỡ của mảng. ­ Bạn sử dụng add để add nhiều elements mà bạn muốn. ­ Bạn sử dụng size() thay vì sử dụng length để đếm số phần tử. ­ Bạn sử dụng a.get(i) thay vì xử dụng a để xử lý thành phần. Ví dụ 5­4. ArrayListTest.java 1. import java.util.*; 2. 3. public class ArrayListTest 4. { 5. public static void main(String[] args) 6. { 7. // fill the staff array list with three Employee objects 8. ArrayList staff = new ArrayList(); 9. 10. staff.add(new Employee("Carl Cracker", 75000, 1987, 12, 15)); 11. staff.add(new Employee("Harry Hacker", 50000, 1989, 10, 1)); 12. staff.add(new Employee("Tony Tester", 40000, 1990, 3, 15)); 13. 14. // raise everyone's salary by 5% 15. for (Employee e : staff) 16. e.raiseSalary(5); 17. 18. // print out information about all Employee objects 19. for (Employee e : staff) 20. System.out.println("name=" + e.getName() 21. + ",salary=" + e.getSalary() 22. + ",hireDay=" + e.getHireDay()); 23. } 24. } 25. 26. class Employee 27. { 28. public Employee(String n, double s, int year, int month, int day) 29. { 30. name = n; 31. salary = s; 32. GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); 33. hireDay = calendar.getTime(); 34. } 35. 36. public String getName() 37. { 38. return name; 39. } 40. 41. public double getSalary() 42. { 43. return salary; 44. } 45. 46. public Date getHireDay() 47. { 48. return hireDay; 49. } 50. 51. public void raiseSalary(double byPercent) 52. { 53. double raise = salary * byPercent / 100; 54. salary += raise; 55. } 56. 57. private String name; 58. private double salary; 59. private Date hireDay; 60. } java.util.ArrayList 1.2 ­ void set(int index, T obj)  put giá trị vào trong array list ở index chỉ định, ghi đè nội dung nếu có. Tham số: index ­ vị trí (nằm giữa 0 và size()­1) obj­ giá trị mới. ­ T get(int index)  lấy giá trị lưu ở vị trí index. Tham số: index ­ chỉ số của element để lấy (phải nằm giữa 0 và size() ­ 1) ­ void add(int index index, T obj)  chèn thêm 1 element. Tham số: index: vị trí cần insert (phải nằm giữa 0 và size()) obj: element mới. ­ T remove(int index)  trả về 1 element và đẩy xuống các elements ở trên nó. Remove element được trả về. Tham số: index ­ vị trí của element được remove (phải nằm giữa 0 và size()­1)   2. Kh    năng t   ng thích gi   a ki   u và Array Lists.   ả   ươ   ữ   ể     Khi bạn viết code mới trong JDK 5.0 và sau này, bạn nên sử dụng các kiểu các tham số như ArrayList, đối với array list. Tuy nhiên, bạn có thể sử dụng với code đang tôn tại   bằng cách sử dụng kiểu ArrayList thô. Giả sử rằng bạn có class kế thừa: public class EmployeeDB{ public void update(ArrayList list){ ... } public ArrayList find(String query) { ... } } Bạn có thể truyền 1 arraylist vào method update mà không cần ép kiểu. ArrayList staff = ....; employeeDB.update(staff); Đối tượng staff được truyền vào method update. Caution:  Thậm chí bạn không có lỗi hoặc warning từ compiler, cách gọi này ko thực sự an toàn. Method   update có thể add elements thành array list mà không có kiểu là Employee. Khi những kiểu   elements được lấy, ngoại trừ việc diễn ra. Điều này thật kinh hoàng, nhưng nếu bạn nghĩ về nó,   đặc điểm này là đơn giản nếu nó là trước JDK 5.0. Tính đúng đắn của máy ảo không bao h bị xâm phạm. Trong tình huống này, bạn không mất bảo vệ nhưng bạn cũng không lợi dụng vào   việc kiểm tra của thời gian biên dịch. Ngược lại, khi bạn gán ArrayList thành 1 kiểu, bạn sẽ có warning. ArrayList result = employeeDB.find(query); // yields warning Note: Để xem text warning, compile với lựa chọn ­Xlint:unchecked. Sử dụng ép kiểu không làm warning mất đi. ArrayList result = (ArrayList) employeeDB.find(query); // yields another   warning. Thay vào đó bạn sẽ nhận 1 warning khác, nói cho bạn biết rằng ép kiểu ko thành công. Đây là   hậu quả không mong muốn về giới hạn kiểu của các tham số trong Java. Để phù hợp, compiler   dịch tất cả các kiểu thành các objects trong ArrayList sau khi kiểm tra qui tắc về kiểu nếu không   bị vi phạm. Trong chương trình chạy, tất cả các array lists giống nhau ­ không có các kiểu tham   số trong máy ảo. Như vậy ép kiểu (ArrayList) hay (ArrayList) đều đồng nhất thời   gian chạy kiểm tra. Không có quá nhiều để bạn có thể làm tình huống đó. Khi bạn gây ảnh hưởng tới code, học các   warning từ máy biên dịch và thoả mãn chính bạn rằng warnings thì ko hề nghiêm trọng.
DMCA.com Protection Status Copyright by webtailieu.net