GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
CẤU TRÚC DỮ LIỆU
DATA STRUCTURES
[214331]
JAVA GENERICS
1
/XX
12/3/15
Source: Nguyễn Văn Khiêm
GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
12/3/15
/XX
2
Nội dung chính
Giới thiệu về Generic.
Generic trong Java.
Lớp Generic.
Phương thức Generic.
Giới hạn (bound) của các biến kiểu (Type variables).
Wildcard.
Generic và Máy ảo Java.
Các lớp Generic Collection.
Hạn chế của Generic.
Kết luận.
Bài tập.
GV: NGUYỄN XUÂN VINH
Giới thiệu về Generic
Lập trình Generic được đề xướng bởi ngôn ngữ Ada năm 1983.
Cho phép các giải thuật có thể dựa trên các kiểu được xác định sau, và các kiểu này sẽ được thể hiện khi cần
thiết.
3
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
Định nghĩa các kiểu ở mức trừu tượng.
Các kiểu này có thể được thay thế bằng nhiều kiểu cụ thể (class, interface) khác khi sử dụng.
Hiện nay Generic có trong Ada, Java, Template trong C++, C#, Visual Basic, .Net, Eiffel và Haskell
4
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
Generic trong Java
Trước jdk1.5:
•
Trước jdk1.5:
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
JDK 1.4
Phải ép kiểu
5
/XX
12/3/15
Ném ngoại lệ khi
chạy
GV: NGUYỄN XUÂN VINH
Một giải pháp tồi
Chúng ta có thể tạo class sau chỉ để chứa danh sách Student:
class StudentList {
void add(Student element) { ... }
Student remove(int index) { ... }
6
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
}
Nhưng, khi cần một danh sách chỉ chứa đối tượng Teacher?
Copy-paste?
Sử dụng Generic
•
Từ jdk1.5:
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
Generic trong Java (tt)
Lỗi ngay khi biên dịch
7
/XX
12/3/15
Không phải ép kiểu
8
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
Lớp Generic
Là lớp với một hoặc nhiều biến kiểu.
GV: NGUYỄN XUÂN VINH
Lớp Generic
Là lớp với một hoặc nhiều biến kiểu.
Các biến kiểu khai báo cách
9
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
nhau bởi dấu phẩy
GV: NGUYỄN XUÂN VINH
Lớp Generic
Là lớp với một hoặc nhiều biến kiểu.
Các biến kiểu khai báo cách
10
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
nhau bởi dấu phẩy
Sử dụng các biến kiểu để khai
báo thuộc tính
GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
Lớp Generic(tt)
Lỗi biên dịch
Không cần ép kiểu, không cần
11
/XX
12/3/15
bắt ngoại lệ
GV: NGUYỄN XUÂN VINH
Phương thức Generic
•
Ta có thể định nghĩa một phương thức với các tham số kiểu ngay trong một lớp bình thường hoặc một lớp
12
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
Generic.
Lỗi biên dịch
GV: NGUYỄN XUÂN VINH
Giới hạn của các kiểu biến
Làm thế nào để first
luôn nhỏ hơn
13
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
second?
14
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
Giới hạn của các kiểu biến (tt)
Giải pháp?
Làm sao để T có thể
được so sánh?
15
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
Giới hạn của các kiểu biến (tt)
Lỗi biên dịch
GV: NGUYỄN XUÂN VINH
Giới hạn của các kiểu biến (tt)
•
Cần phải giới hạn T trong Interface Comparable.
16
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
Giới hạn T
GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
12/3/15
/XX
17
Giới hạn của các kiểu biến (tt)
•
Một kiểu biến có thể có nhiều giới hạn.
Giới hạn T vừa có thể so
sánh, vừa có thể sao
chép
GV: NGUYỄN XUÂN VINH
Wildcard
Java cho phép sử dụng các Wildcard để xác định biên của kiểu tham số Generic.
18
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
Được sử dụng khi:
Không biết kiểu Generic là gì.
Các kiểu Generic được khai báo nhưng không được sử dụng.
Chúng ta muốn kiểu Generic là “read-only”.
GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
12/3/15
/XX
19
Bounded Wildcards
Upper bound (Wildcard biên trên)
List<? extends Fruit> items at least Fruits
So, it can contain Fruits and Apple, Oranges, but not Pigs
Lower bound (Wildcard biên dưới)
List<? super Fruit> items most Fruits
So, it can contain Fruits and Objects but not Apples
Unknown bound (Wildcard không biên)
List<?> any items
So, it can contain any things.
GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
12/3/15
/XX
20
Josh Bloch’s Bounded Wildcards Rule
The rule is: PECS (Producer-Extends, Comsumer-Super)
Use <? extends T> when parameterized instance is a T producer (for reading/input)
Use <? super T> when parameterized instance is a T comsumer (for writing/output)
GV: NGUYỄN XUÂN VINH
Josh Bloch’s Bounded Wildcards Rule
Giả sử, cần thêm một lúc nhiều phần tử và Stack<E>
void pushAll(Collection<? extends E> src);
src là một E producer
void popAll(Collection<? super E> dst);
21
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
dst là một E consumer
Có thể pushAll từ Collection<Long> hoặc Collection<Number> bỏ vào Stack<Number>
Có thể popAll từ Collection<Object> hoặc Collection<Number> từ Stack<Number>
GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
12/3/15
/XX
22
Wildcard (tt)
Sử dụng Generic mà
không cần khai báo
kiểu
23
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
Wildcard (tt)
T được khai báo nhưng
không được sử dụng
GV: NGUYỄN XUÂN VINH
MÔN: CẤU TRÚC DỮ LIỆU
Wildcard (tt)
Chúng ta muốn tập nguồn
24
/XX
12/3/15
Lỗi biên dịch
là “read-only”
25
/XX
12/3/15
MÔN: CẤU TRÚC DỮ LIỆU
GV: NGUYỄN XUÂN VINH
Wildcard (tt)
Sử dụng lower bound
OK