15 tháng 10 2006

Mở rộng lớp ArrayList trong Java

Mảng là một thành phần không thể thiếu trong bất kì ngôn ngữ lập trình nào, Java cũng vậy. Việc tạo và sử dụng một mảng trong Java là vô cùng đơn giản nhưng trong một vài trường hợp, lại chứa đựng những hạn chế. Ví dụ như, bạn cần chứa một danh sách các từ do người dùng thêm vào, hay một danh sách các nhân viên trong công ty nào đó, hay đại loại như vậy. Trong những trường hợp này, bạn không thể biết chính xác mảng sẽ chứa bao nhiêu phần tử, vì thế, không thể sử dụng mảng. Thay vào đó, hãy sử dụng lớp ArrayList, một lớp có công dụng hoàn toàn tương tự như một array nhưng có khả năng tự mở rộng kích thước của nó.

Cách sử dụng lớp ArrayList thì đơn giản mà sách viết về nó thì vô kể nên mình sẽ không nói lại nữa mà sẽ đi vào mục đích chính của bài này, đó là mở rộng nó. Giả sử rằng, bạn cần viết một chương trình quản lí sinh viên chẳng hạn. Một cách bình thường, bạn sẽ phải viết một lớp kiểu như Student với các thuộc tính như tên, tuổi, giới tính... rồi sau đó quản lí chúng trong chương trình với một mảng kiểu Student[] hay một đối tượng ArrayList để quản lí tất cả các sinh viên. Vì số sinh viên có thể là đủ kiểu, có thể lúc này nhiều, lúc này ít,... nên sử dụng ArrayList trong trường hợp này là thích hợp hơn dùng Student[]. Cho tới lúc này, vẫn chưa có gì khó khăn cả B-). Tuy nhiên, việc hay làm nhất của loại chương trình như thế này là giải quyết những yêu cầu kiểu như tìm tất cả những sinh viên có tên là Bình trong toàn bộ sinh viên chẳng hạn. OK, việc này cũng chẳng có gì khó khăn, bạn chỉ cần viết thêm một phương thức, từa tựa thế này là xong:

Thế nếu bây giờ bạn tìm tất cả những sinh viên có tên là An thì làm thế nào? Ồ, chỉ cần sửa lại phương thức trên một chút là xong:

Vẫn chưa có gì khó khăn nhỉ :D ? Thế nếu bây giờ bạn không muốn tìm theo tên mà là tìm tất cả những sinh viên 20 tuổi thì sao nhỉ? Code tiếp chứ sao, viết thêm một phương thức nữa vậy:

Xong rồi hả, vậy bây giờ bạn lại muốn tìm tất cả sinh viên nam thì sao nhỉ? Rồi tất cả sinh viên nam tên Bình tuổi dưới 20, một sinh viên nữ 21 tuổi đầu tiên bắt gặp trong danh sách, hay tất cả sinh viên không phải tên Bình,... thì sao nhỉ? Có lẽ tới lúc này thì cách giải quyết trên đây đã trở thành vô tác dụng và nên lên đường vào sọt rác thì hơn. Phải có cách giải quyết tốt hơn cho những vấn đề kiểu như trên. Tiếc thay, Java không hỗ trợ cho chúng ta trong những vấn đề như thế này (hay là có mà mình không biết nhỉ), đành phải tự tìm giải pháp vậy.

Thử nhìn lại 3 phương thức đã viết trên đây, bạn có thấy chúng giống nhau? Vâng, chúng hoàn toàn tương tự nhau, chỉ có duy nhất một yếu tố khác biệt, đó là câu lệnh if(...){}, là điều kiện để xác định xem một phần tử có thõa mãn yêu cầu hay không. Nhận xét này đưa đến một cách giải quyết khác, với một ý tưởng bắt nguồn từ Prototype.js framework.

Trước tiên, ta hãy tạo một Interface có tên là Condition như sau:

Sau đó tạo một lớp chứa mới kế thừa lớp ArrayList và thêm vào các phương thức của chúng ta:

Giải thích một chút về ý nghĩa của các phương thức:

    • find(Condition cond): tìm phần tử đầu tiên thỏa mãn điều kiện cond và trả về nó, nếu không có phần tử nào trong ArrayList thõa thì trả về null.
      findAll(Condition cond): trả về một đối tượng thuộc lớp MyArrayList chứa tất cả các phần tử trong ArrayList thõa mãn điều kiện cond.
      reject(Condition<E> cond):trả về một đối tượng thuộc lớp MyArrayList chứa tất cả các phần tử trong ArrayList không thõa mãn điều kiện cond.
      partition(Condition<E> cond):trả về một mảng 2 phần tử là đối tượng thuộc lớp MyArrayList, MyArrayList thứ nhất chứa tất cả các phần tử trong ArrayList thõa mãn điều kiện cond, MyArrayList thứ 2 chứa các phần tử còn lại.
  • Ví dụ sử dụng lớp MyArrayList:

    Tới lúc này thì mọi việc có lẽ đã thật sự trở nên dễ dàng hơn rồi nhỉ?

    0 Comments:

    Post a Comment




     

    Copyright 2006| Blogger Templates by GeckoandFly modified and converted to Blogger Beta by Blogcrowds.
    No part of the content or the blog may be reproduced without prior written permission.