1. Trang chủ
  2. » Công Nghệ Thông Tin

giáo trình java tóm tắt - collections

14 976 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 14
Dung lượng 180,5 KB

Nội dung

Iterator cho phép lấy các phần tử trong collection từ đầu đến hết mà không cần quan tâm tới chỉ số và thứ tự của chúng..  Interface RandomAccess cho biết ta có thể truy cập đến một phần

Trang 1

Java Collections Framework

Java Collections Framework 1

1 Giới thiệu chung 1

2 List 2

3 Các interface Iterable, Iterator và Enumerator 9

4 Set 11

5 Map 14

1 Giới thiệu chung

Array là cách nhanh và dễ nhất để lưu trữ các loại dữ liệu dạng mảng Tuy nhiên, array có một nhược điểm là kích thước cố định Dĩ nhiên là ta có thể "thay đổi kích thước" của array bằng cách tạo ra một array mới rồi sao chép dữ liệu qua đó, nhưng việc này sẽ tốn thời gian và công sức

Để khắc phục nhược điểm trên của array, Java đã xây dựng một dạng dữ liệu gọi chung là collection, được đặt trong package java.util

Các đối tượng collection có khả năng lưu trữ dữ liệu dạng mảng như array, ngoài ra nó còn cho phép thêm và xóa các phần tử một cách tùy ý Dĩ nhiên là khi đó collection sẽ ko thể chạy nhanh và dễ dùng như array

Trong Java, collection được cài đặt trong Collections Framework Collections Framework bao gồm hai phần chính là collection và map Việc mô tả các chức năng chung của các collection được quy định trong interface Collection, Collection lại được chia thành hai loại chính là List và Set, ngoài ra còn vài interface phụ khác Còn các map được đại diện bởi interface Map

Dưới đây là sơ đồ quan hệ của Java Collections Framework (chỉ có một số interface và class chính)

Trang 2

Hình 1: Collections Framework

2 List

List là một bộ phận của Java Collections, list được đại diện bởi interface List Interface

List được kế thừa từ interface Collection Dưới List là lớp AbstractList, dưới nữa

là các lớp Vector, AbstractSequentalList, ArrayList, LinkedList, Stack,

Ở đây xin giới thiệu về Vector, các class khác cũng có cách dùng và tính năng tương tự

HashSet

AbstractCollection AbstractSet

WeakHashMap

TreeSet

ArrayList

AbstractList

List

Vector AbstractSequentalList

AbstractMap

HashMap

TreeMap

HashTable

Dictionary

Properties

Trang 3

2.1 Lớp Vector

2.1.1 Giới thiệu

Vector là một collection dạng List, được tạo ra bằng cách extend class AbstractList,

AbstractList lại được extend từ AbstractCollection Ngoài ra Vector còn implement từ các interface Serializable, Cloneable, Iterable, List, RandomAccess

và dĩ nhiên không thể thiếu interface Collection

 Class AbstractCollection là một lớp ảo, trong đó khai báo các thuộc tính và phương thức cơ bản cho các đối tượng dạng collection

 Class AbstractList là một lớp ảo, trong đó khai báo các thuộc tính và phương thức cơ bản cho các đối tượng dạng list (bao gồm mảng, danh sách liên kết,…) để phân biệt với các đối tượng dạng set (tập hợp)

 Interface Serializable cho biết đối tượng Vector có khả năng biến đổi thành một dãy byte dữ liệu (VD: để ghi vào file) và phục hồi từ dãy byte dữ liệu (VD:

để đọc từ file) Chi tiết về object serialization sẽ được trình bày trong một phần riêng

 Interface Cloneable cho biết đối tượng Vector có thể tạo ra bản sao của nó thông qua phương thức Object clone()

 Interface Iterable cho biết đối tượng Vector có thể tạo ra đối tượng Iterator Iterator cho phép lấy các phần tử trong collection từ đầu đến hết mà không cần quan tâm tới chỉ số và thứ tự của chúng

 Interface List cho biết Vector lưu các phần tử một cách có thứ tự (sequence) và cho phép tìm kiếm các phần tử List cũng nói rằng Vector cho phép lưu những phần tử trùng nhau List dùng để phân biệt với Set (tập hợp)

 Interface RandomAccess cho biết ta có thể truy cập đến một phần tử bất kỳ trong

Vector thông qua chỉ số (index), và việc truy cập này không tốn thời gian xử lý (chính xác hơn là thời gian xử lý không đáng kể và như nhau với mọi vị trí) Điều này cho thấy Vector không phải là danh sách liên kết mà là sự phát triển của array Trong phần sau, các constructor của Vector sẽ cho ta thấy rõ điều này

 Interface Collection cho biết Vector có khả năng chứa đựng dữ liệu dạng mảng

và cho phép thêm/xóa các phần tử

Trang 4

Hình 2 Vị trí của Vector trong Java Collections Framework

Ngoài Vector, ta còn có thể dùng ArrayList Nhìn chung ArrayList tương tự như

Vector, ngoại trừ việc nó không có tính năng đồng bộ (synchronize - bảo đảm tính nhất quán dữ liệu khi chạy trong ứng dụng đa tiểu trình)

2.1.2 Các constructor

Trước khi đi vào các constructor, ta cần điểm qua các thuộc tính quan trọng của Vector,

đó là initialCapacity, capacityIncrement và size

 initialCapacity: là sức chứa khởi đầu của Vector Ví dụ nếu

initialCapacity = 10 thì Vector được tạo ra sẽ có khả năng chứa 10 phần tử Nếu trong quá trình hoạt động, số phần tử thêm vào vượt quá sức chứa (capacity) thì Vector sẽ tự gia tăng sức chứa

 capacityIncrement: là độ gia tăng sức chứa của Vector khi số phần tử thêm vào vượt quá sức chứa hiện tại Quy ước: Nếu độ tăng nhỏ hơn 1 có nghĩa là sức chứa sẽ tăng gấp đôi mỗi khi cần thiết

 size: là số phần tử hiện có trong Vector Do đó, size không thể vượt quá sức chứa (capacity)

Iterable

Collection

List

AbstractCollection

AbstractList

Vector

Stack

Serializable Cloneable RandomAccess

Trang 5

Bảng dưới đây là các constructor của Vector.

Vector()

Đây là constructor default Constructor này sẽ tạo

ra một đối tượng Vector với sức chứa mặc định là

10, độ tăng sức chứa là 0 (nghĩa là tăng gấp đôi khi cần tăng)

Vector(int initialCapacity)

Constructor này tạo ra một Vector với sức chứa khởi đầu là initialCapacity, độ tăng sức chứa là

0 (nghĩa là tăng gấp đôi khi cần tăng)

Vector(int initialCapacity,

int capacityIncrement)

Constructor này tạo ra một Vector với sức chứa khởi đầu là initialCapacity, độ tăng sức chứa là

capacityIncrement (nếu capacityIncrement nhỏ hơn 1 thì Vector sẽ là tăng gấp đôi sức chứa khi cần tăng)

Vector(Collection c) Constructor này tạo ra một Vector với các phần tử

có sẵn trong Collection c

Bảng 1 Các constructor của lớp Vector

2.1.3 Các phương thức chính

Bảng dưới đây là các phương thức thường dùng của Vector Chi tiết xin xem thêm trong Java API Documents

Object get(int index) Trả về object ở vị trí index (bắt đầu từ 0)

void set(int index, Object e) Thay thế về object ở vị trí index bởi e

void add(Object e) Chèn phần tử e vào cuối Vector

void add(int index, Object e) Chèn phần tử e vào vị trí index

Object lastElement() Trả về phần từ cuối cùng của Vector

Object remove(int index) Xóa và trả về phần tử tại vị trí index

int size()

Trả về số phần tử đang có trong Vector

Lưu ý: cần phân biệt số phần tử (size) với sức chứa (capacity)

boolean remove(Object e) Xóa handle quản lý đối tượng e trong Vector

Nếu trong Vector có nhiều handle cùng quản lý

e thì chỉ có handle đầu tiên bị xóa Nếu trong Vector không có handle nào quản lý e thì sẽ trả

Trang 6

về false, khi đó Vector sẽ không bị thay đổi gì.

Enumeration elements() Trả về một đối tượng Enumeration chứa các

phần tử trong Vector

Iterator iterator() Trả về một đối tượng Iterator chứa các phần tử

trong Vector

Bảng 2 Các phương thức thường dùng của lớp Vector

2.2 Vector hỗn tạp

Như đã nói trên, do Object là lớp "cha" của mọi lớp khác trong Java, nên nếu ta tạo ra một mảng các Object (thực chất là mảng các handle kiểu Object) thì mảng đó sẽ có khả năng chứa mọi loại đối tượng (thông qua up-cast)

Trong collection, các phần tử của chúng cũng đều là các handle kiểu Object Nên collection (cụ thể là Vector) cũng có khả năng chứa mọi loại đối tượng

Khi một mảng (hoặc collection) chứa nhiều đối tượng không cùng loại (nghĩa là không cùng lớp) ta nói đó là mảng (hoặc collection) hỗn tạp Khi đó phải thật cẩn thận khi sử dụng để tránh lỗi down-cast

Cách xửlý và kiểm tra với mảng hỗn tạp và collection hỗn tạp là tương tự nhau: upcast khi thêm phần tử mới và down-cast khi dùng phần tử, kèm theo đó là kiểm tra tính hợp lệ của down-cast

2.2.1 Ví dụ về Vector hỗn tạp

Trong ví dụ này, ta tạo ra Vector V chứa phân số (lớp PhanSo) và học sinh (lớp HocSinh) PhanSo và HocSinh là hai lớp độc lập (không extend nhau)

Vector V=new Vector();

HocSinh hs=new HocSinh();

hs.Nhap();

V.add(new PhanSo()); // Up-cast PhanSo-Object

((PhanSo)V.lastElement()).Nhap(); // Down-cast Object-PhanSo

V.add(new HocSinh()); // Up-cast HocSinh-Object

((HocSinh)V.lastElement()).Nhap(); // Down-cast Object-HocSinh

Như vậy, Vector V sẽ chứa 3 handle kiểu Object, trong đó có 2 handle quản lý HocSinh

và 1 handle quản lý PhanSo

2.2.2 Lỗi down-cast

Đoạn code này được thực thi ngay sau đoạn code tạo Vector ở trên Nó sẽ gây ra lỗi ép kiểu khi down-cast

/* !!! Đoạn code gây lỗi down-cast !!! */

for(int i=0;i<V.size();i++)

((HocSinh)V.get(i)).Xuat();

Trang 7

Ban đầu, ta thêm vào V hai đối tượng HocSinh và một PhanSo Đối tượng PhanSo là do handle thứ 1 (tính từ 0) quản lý

Trong đoạn code lỗi, ta ép kiểu tất cả các handle của V từ Object về HocSinh và gọi phương thức xuất Do đó, handle thứ 1 là handle quản lý PhanSo cũng sẽ bị ép về

HocSinh, đây là nguyên nhân gây lỗi down-cast

Lưu ý: đôi khi trong Vector hỗn tạp, ta có thể gọi thực thi các phương thức của từng phần tử một cách "vô tư" mà không hề bị lỗi down-cast Xem ví dụ sau:

/* !!! Dùng Vector hỗn tạp mà ko bị lỗi down-cast !!! */

for(int i=0;i<V.size();i++)

System.out.println(V.get(i).toString());

Lý do: phương thức toString() đã có từ lớp Object nên việc gọi tới nó mà không cần

ép kiểu là hoàn toàn hợp lệ

2.2.3 Từ khóa instanceof

Để tránh lỗi down-cast khi dùng mảng hỗn tạp, ta cần kiểm tra kiểu của đối tượng do handle quản lý (bằng từ khóa instanceof) rồi mới down-cast

for(int i=0;i<V.size();i++)

{

if (V.get(i) instanceof HocSinh) // Kiểm tra kiểu của V[i]

((HocSinh)V.get(i)).Xuat(); // Down-cast Object-HocSinh

else

if (V.get(i) instanceof PhanSo) // Kiểm tra kiểu của V[i]

((PhanSo)V.get(i)).Xuat(); // Down-cast Object-PhanSo

System.out.println();

}

2.3 Vector định kiểu

2.3.1 Bao bọc

Như đã nêu trên, Vector có khả năng lưu trữ mọi loại đối tượng Trong hoàn cảnh cụ thể,

để tránh rắc rồi về xác định kiểu của các handle trong Vector, ta có thể tạo ra một

"MyVector" của riêng mình với kiểu phần tử cố định và duy nhất Việc này có thể được thực hiện bằng cách tạo ra một đối tượng mới bao bọc đối tượng Vector

Ví dụ, để tạo ra một đối tượng chỉ cho phép lưu trữ các HocSinh, ta có thể làm như sau:

// Lớp MangHocSinh tương tự như Vector nhưng chỉ cho phép lưu trữ và xử // lý cho các đối tượng kiểu HocSinh

public class MangHocSinh

{

// MangHocSinh bao bọc một đối tượng Vector

private Vector lop;

public MangHocSinh()

{

lop=new Vector();

}

Trang 8

/* Cài đặt lại các phương thức lấy dữ liệu */

void ThemHocSinh(HocSinh hs)

{

// Up-cast HocSinh-Object

lop.add(hs);

}

HocSinh LayHocSinh(int i)

{

// Down-cast Object-HocSinh: luôn luôn OK

return (HocSinh)lop.elementAt(i);

}

HocSinh HocSinhCuoiCung()

{

// Down-cast Object-HocSinh: luôn luôn OK

return (HocSinh)lop.lastElement();

}

public int SoHocSinh()

{

return lop.size();

}

public void XoaHocSinh(int i)

{

lop.removeElementAt(i);

}

}

Khi đó, MangHocSinh sẽ được dùng để lưu trữ HocSinh một cách dễ dàng và an toàn

// Tạo mảng học sinh

MangHocSinh mhs=new MangHocSinh();

// Nhập mảng học sinh

for(int i=0;i<3;i++)

{

// Không thể add gì khác ngoài HocSinh vào "Vector" này

mhs.ThemHocSinh(new HocSinh());

// Không cần lo lỗi down-cast nữa

mhs.HocSinhCuoiCung().Nhap();

}

// Xuất mảng học sinh

for(int i=0;i<mhs.SoHocSinh();i++)

{

// Không cần lo lỗi down-cast nữa

mhs.LayHocSinh(i).Xuat();

System.out.println();

}

2.3.2 Generics

Khi làm việc với các Collection, để xử lý trên dữ liệu mà kiểu là chưa biết trước, ta có thể dùng lớp Object và gọi ép kiểu (down-cast, up-cast) khi cần Việc này khiến chương trình sẽ rối rắm và dễ xảy ra lỗi (ClassCastException) Để khắc phục vấn đề này, từ JDK 5, Java bổ sung một tính năng mới gọi là Generics

Với Generics ta không cần phải ép kiểu và kiểm tra kiểu nữa

Ví dụ:

Trang 9

// Khai báo một Vector chứa các HocSinh

Vector<HocSinh>v=new Vector();

// Chèn vào một HocSinh

v.insert(new HocSinh());

// Chèn vào một PhanSo  không cho phép

// v.insert(new PhanSo()); // Dòng lệnh này sẽ bị lỗi

// Nhập dữ liệu cho học sinh vừa chèn (không cần ép kiểu)

v.getLastElement().Nhap();

2.4 Stack

Lớp này kế thừa trực tiếp từ lớp Vector, dùng khi cần truy cập các phần tử theo dạng LIFO ("last in first out" hay "vào sau ra trước")

Các phương thức chính:

Object pop() Lấy phần tử ở đỉnh ra khỏi stack

void push(Object o) Thêm một phần tử vào stack

Object peek() Xem giá trị của phần tử đỉnh của stack mà

không lấy nó ra khỏi stack

Bảng 3 Các phương thức chính của lớp Stack

3 Các interface Iterable, Iterator và Enumerator

3.1 Giới thiệu

Iterable không phải là một bộ phận của Collections Framework, nhưng việc sử dụng nó thường gắn liền với các đối tượng collection

Iterable quy định khả năng duyệt qua các phần tử của collection một cách tuần tự mà không quan tâm tới chỉ số lẫn vị trí của chúng bằng Iterator hoặc Enumeration Điều này giúp việc truy cập trở nên nhanh chóng (đối với các collection dạng danh sách liên kết, so với truy cập qua chỉ số) và tự nhiên hơn

Nhìn chung, Enumeration và Iterator là tương tự nhau Ban đầu, JDK chỉ có

Enumeration Iterator được bổ sung vào sau này và là sự cải tiến của Enumeration:

Enumeration chỉ cho phép lấy phần tử và xử lý, còn Iterator cho phép xóa phần tử, ngoài ra các phương thức của Iterator được đặt lại tên cho dễ nhớ hơn

Do là interface, Enumeration và Iterator không thể được tạo ra tùy ý thông qua constructor mà bắt buộc phải được tạo ra từ một collection nào đó (như Vector chẳn hạn) Để tạo ra Enumeration, ta dùng phương thức Enumeration elements(), còn để tạo ra Iterator, ta dùng phương thức Iterator iterator() (như đã để cập trong phần trước)

Ngoài ra, kể từ JDK5, Iterable cho phép truy cập dữ liệu của collection bằng vòng lặp

"for-each" (xem trong phần sau)

Trang 10

3.2 Các phương thức

Enumeration

boolean hasMoreElements()

Cho biết Enumeration này còn phần tử chưa xét tới hay không Trả về true nếu còn

Object nextElement()

Trả về đối tượng kế tiếp đối tượng đang xét Nếu gọi lần đầu thì sẽ trả về phần tử đầu tiên của Enumeration

Iterator

boolean hasNext() Cho biết Iterator này còn phần tử chưa xét

tới hay không Trả về true nếu còn

Object next()

Trả về đối tượng kế tiếp đối tượng đang xét Nếu gọi lần đầu thì sẽ trả về phần tử đầu tiên của Iterator

void remove()

Xóa phần tử đang xét của Iterator Phương thức này chỉ được gọi tối đa một lần ứng với một lời gọi next

Bảng 4 Các phương thức thường dùng của Enumerator và Iterator

3.3 Enumeration vs Vector

Dưới đây ta sẽ xem một ví dụ để thấy rõ sự khác biệt khi dùng Enumeration và

Iterator so với Vector

Xuất ra các phần tử của Vector V - cách thông thường (dùng chỉ số):

// Xuất ra các phần tử của Vector V

for (int i=0; i<V.size(); i++)

System.out.println(V.get(i));

Xuất ra các phần tử của Vector V - dùng Enumeration:

// Xuất ra các phần tử của Vector V – dùng Enumeration

// Cách 1 - for

for (Enumeration E = V.elements(); E.hasMoreElements();)

System.out.println(E.nextElement());

// Cách 2 - while

Enumeration E = V.elements();

while (E.hasMoreElements())

System.out.println(E.nextElement());

Xuất ra các phần tử của Vector V - dùng Iterator:

// Xuất ra các phần tử của Vector V – dùng Enumeration

Ngày đăng: 24/10/2014, 00:34

HÌNH ẢNH LIÊN QUAN

Hình 1: Collections Framework - giáo trình java tóm tắt - collections
Hình 1 Collections Framework (Trang 2)
Hình 2 Vị trí của Vector trong Java Collections Framework - giáo trình java tóm tắt - collections
Hình 2 Vị trí của Vector trong Java Collections Framework (Trang 4)
Bảng 1 Các constructor của lớp Vector - giáo trình java tóm tắt - collections
Bảng 1 Các constructor của lớp Vector (Trang 5)
Bảng dưới đây là các constructor của  Vector . - giáo trình java tóm tắt - collections
Bảng d ưới đây là các constructor của Vector (Trang 5)
Bảng 2 Các phương thức thường dùng của lớp Vector - giáo trình java tóm tắt - collections
Bảng 2 Các phương thức thường dùng của lớp Vector (Trang 6)
Bảng 3 Các phương thức chính của lớp Stack - giáo trình java tóm tắt - collections
Bảng 3 Các phương thức chính của lớp Stack (Trang 9)
Bảng 4 Các phương thức thường dùng của Enumerator và Iterator - giáo trình java tóm tắt - collections
Bảng 4 Các phương thức thường dùng của Enumerator và Iterator (Trang 10)
Bảng 5 Các phương thức chính của interface Set - giáo trình java tóm tắt - collections
Bảng 5 Các phương thức chính của interface Set (Trang 12)

TỪ KHÓA LIÊN QUAN

w