Cấu trúc dữ liệu Java
- 20-12-2023
- Toanngo92
- 0 Comments
Mục lục
Giao diện Enumeration
Enumeration
là một giao diện trong gói java.util
định nghĩa các phương thức để lặp qua các phần tử của một tập hợp. Các phương thức của giao diện Enumeration
như sau:
hasMoreElements()
: Kiểm tra xem enumeration có chứa thêm phần tử nào không.nextElement()
: Trả về phần tử tiếp theo, nếu có, trong enumeration.
Ngoại lệ liên quan đến giao diện này là NoSuchElementException
. Ngoại lệ này sẽ được ném nếu nextElement()
được gọi khi không còn phần tử nào trong enumeration.
Đoạn mã dưới sử dụng một Enumeration
để lặp qua các phần tử của một mảng.
Ví dụ 1:
import java.lang.reflect.Array;
import java.util.Enumeration;
public class CustomEnumeration implements Enumeration {
private final int arraySize;
private int arrayCursor;
private final Object array;
public CustomEnumeration(Object obj) {
arraySize = Array.getLength(obj);
array = obj;
}
@Override
public boolean hasMoreElements() {
return (arrayCursor < arraySize);
}
@Override
public Object nextElement() {
return Array.get(array, arrayCursor++);
}
}
Đoạn mã tạo ra một lớp CustomEnumeration
triển khai giao diện Enumeration
. Constructor của lớp chấp nhận một đối tượng và lưu kích thước và đối tượng đó vào các biến arraySize
và array
tương ứng. Phương thức hasMoreElements()
được ghi đè để trả về true
nếu biến arrayCursor
nhỏ hơn arraySize
. Phương thức nextElement()
được ghi đè để trả về một đối tượng biểu diễn một phần tử trong mảng với chỉ số được xác định bởi biến arrayCursor
. Ví dụ dưới cho thấy class sử dụng custom enumeration được định nghĩa ở ví dụ 1.
Ví dụ 2:
import java.util.Enumeration;
public class EnumerationDemo {
public static void main(String[] args) {
String[] strArray = new String[]{"one", "Two", "Three"};
Enumeration customEnumeration = new CustomEnumeration(strArray);
while (customEnumeration.hasMoreElements()) {
System.out.println(customEnumeration.nextElement());
}
}
}
Phương thức main
trong đoạn mã tạo một thể hiện của CustomEnumeration
được khởi tạo với một mảng. Phương thức hasMoreElements()
trong vòng lặp while
kiểm tra xem có thêm phần tử nào trong mảng không. Nếu phương thức hasMoreElements()
trả về true
, phương thức nextElement()
sẽ in ra phần tử của mảng.
Output:
one
Two
Three
Lớp BitSet
Trong máy tính, một bit là đơn vị dữ liệu nhỏ nhất. Ứng dụng Java thường xuyên cần làm việc với lượng lớn bit và lớp BitSet
được thiết kế cho mục đích đó. Lớp BitSet
là một tập hợp các giá trị bit và có thể thay đổi kích thước theo yêu cầu. Một BitSet
lập chỉ mục cho các bit của nó bằng số nguyên không âm và mỗi bit trong BitSet
có thể được truy cập bằng chỉ mục của nó. Ưu điểm của BitSet
là nó chỉ sử dụng một bit để lưu trữ một giá trị.
Ví dụ:
import java.util.BitSet;
public class BitSetDemo {
public static void main(String[] args) {
BitSet bitSet1 = new BitSet();
BitSet bitSet2 = new BitSet();
bitSet1.set(1);
bitSet1.set(5);
bitSet1.set(8);
bitSet2.set(3);
bitSet2.set(6);
bitSet2.set(9);
System.out.println("Values in bitSet1: " + bitSet1);
System.out.println("Values in bitSet2: " + bitSet2);
}
}
Đoạn mã tạo ra hai đối tượng BitSet
và gọi phương thức set()
để khởi tạo chúng. Cuối cùng, các đối tượng BitSet
được in ra màn hình.
Output:
Values in bitSet1: {1, 5, 8}
Values in bitSet2: {3, 6, 9}
Lớp Stack
Một ngăn xếp là một tập hợp các đối tượng dựa trên nguyên tắc LIFO (Last-in First-out). Trong một ngăn xếp, phần tử cuối cùng được thêm vào, hoặc đẩy vào ngăn xếp là phần tử đầu tiên được loại bỏ, hoặc bật ra khỏi ngăn xếp. Lớp Stack
mở rộng từ lớp Vector
và ngoài các phương thức được kế thừa từ Vector
, Stack
định nghĩa năm phương thức, như liệt kê trong Bảng dưới:
Các Phương thức của Lớp Stack
Phương thức | Mô Tả |
---|---|
empty() | Kiểm tra xem Stack có trống không. |
peek() | Trả về đối tượng ở đỉnh của Stack mà không loại bỏ đối tượng. |
pop() | Trả về đối tượng ở đỉnh của Stack sau khi loại bỏ đối tượng từ Stack . |
push(E item) | Đẩy một đối tượng lên đỉnh của Stack . |
search(Object) | Trả về vị trí của một đối tượng từ đỉnh của Stack . Phương thức này trả về 1 cho đối tượng ở đỉnh ngăn xếp, 2 cho đối tượng bên dưới nó, và cứ như vậy. Nếu không tìm thấy đối tượng, phương thức này trả về -1. |
Ví dụ:
import java.util.Stack;
public class StackDemo {
private static Stack<String> getInitializedStack() {
Stack<String> stack = new Stack<>();
stack.push("obj1");
stack.push("obj2");
stack.push("obj3");
stack.push("obj4");
return stack;
}
public static void main(String[] args) {
Stack<String> initializedStack = StackDemo.getInitializedStack();
System.out.println("Object at top: " + initializedStack.peek());
System.out.println("Position of obj2 from top: " + initializedStack.search("obj2"));
System.out.println("Object popped out: " + initializedStack.pop());
System.out.println("Object at top: " + initializedStack.peek());
System.out.println("Elements in Stack---");
for (String obj : initializedStack) {
System.out.println(obj);
}
}
}
Phương thức getInitializedStack()
của đoạn mã tạo một Stack
và đẩy bốn đối tượng vào nó. Phương thức main()
gọi phương thức peek()
để lấy và in ra đối tượng ở đỉnh của Stack
.
Phương thức search()
lấy và in ra vị trí của đối tượng “obj2” từ đỉnh. Phương thức pop()
đẩy ra phần tử ở đỉnh và phương thức peek()
lấy và in ra phần tử hiện tại ở đỉnh. Cuối cùng, vòng lặp for cải tiến in ra từng phần tử hiện có trong Stack
.
Output:
Object at top: obj4
Position of obj2 from top: 3
Object popped out: obj4
Object at top: obj3
Elements in Stack---
obj3
obj2
obj1
Lớp Từ Điển (Dictionary)
Trong Java collections, một từ điển được sử dụng để lưu trữ các cặp khóa-giá trị. Mỗi khóa và giá trị trong một từ điển là một đối tượng. Lớp Dictionary
trong gói java.util
là lớp trừu tượng cha của tất cả các lớp thực hiện từ điển. Một số ví dụ về các lớp thực hiện từ điển là Hashtable
và Properties
.
Lớp Hashtable
Lớp Hashtable
thực hiện một tập hợp các cặp khóa-giá trị được tổ chức dựa trên mã băm của khóa. Mã băm là một số có dấu xác định khóa. Dựa trên mã băm, khi một cặp khóa-giá trị được thêm vào Hashtable
, nó được lưu trữ vào một bucket cụ thể. Hashtable
có tốc độ đáng kể nhanh so với các từ điển khác. Khi tìm kiếm được thực hiện cho một khóa, Hashtable
chỉ tìm kiếm trong một bucket cụ thể. Do đó, số lượng so sánh khóa giảm đáng kể.
Khi các phần tử được thêm vào Hashtable
, Hashtable
tự động thay đổi kích thước của mình bằng cách tăng dung lượng. Khi dung lượng của Hashtable
đạt đến dung lượng bạn chỉ định trong quá trình tạo, số lượng bucket tăng tự động. Nội tại, số lượng bucket được tăng lên thành số nguyên tố nhỏ nhất, lớn hơn gấp đôi số lượng hiện tại của các bucket trong lớp Hashtable
. Ví dụ, nếu số lượng hiện tại của bucket là 5 và Hashtable
đạt đến dung lượng ban đầu của nó, số lượng bucket sẽ tự động tăng lên thành 11.
Ví dụ:
import java.util.Enumeration;
import java.util.Hashtable;
public class HashtableDemo {
private static Hashtable<String, String> initializeHashtable() {
Hashtable<String, String> hTable = new Hashtable<>();
hTable.put("1", "East");
hTable.put("2", "West");
hTable.put("3", "North");
hTable.put("4", "South");
return hTable;
}
public static void main(String[] args) {
Hashtable<String, String> initializedTable = HashtableDemo.initializeHashtable();
Enumeration<String> e = initializedTable.keys();
System.out.println("---Hashtable Key-Value Pairs---");
while (e.hasMoreElements()) {
String key = e.nextElement();
System.out.println(key + " : " + initializedTable.get(key));
}
e = initializedTable.keys();
System.out.println("---Hashtable Keys---");
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}
e = initializedTable.elements();
System.out.println("---Hashtable Values---");
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}
}
}
Phương thức initializeHashtable()
của đoạn mã tạo một Hashtable
và đặt bốn cặp khóa-giá trị vào nó. Phương thức main()
sử dụng Enumeration
để lặp qua các khóa của Hashtable
và in ra các cặp khóa-giá trị, danh sách các khóa và danh sách giá trị của Hashtable
.
Output:
---Hashtable Key-Value Pairs---
1 : East
2 : West
3 : North
4 : South
---Hashtable Keys---
1
2
3
4
---Hashtable Values---
East
West
North
South
Lớp Properties
Lớp Properties
mở rộng từ Hashtable
để thực hiện một bộ sưu tập các cặp khóa-giá trị, trong đó cả hai loại khóa và giá trị đều là chuỗi. Mặc dù là một lớp con của Hashtable
, lớp Properties
kế thừa phương thức put()
để thêm một cặp khóa-giá trị, nhưng bạn nên tránh sử dụng nó. Điều này là do, nếu bạn thêm một khóa hoặc giá trị không phải là chuỗi, phương thức này sẽ thất bại khi chạy. Thay vào đó, bạn nên sử dụng phương thức setProperty()
để thêm cặp khóa-giá trị và phương thức getProperty()
để truy xuất một cặp khóa-giá trị.
Ví dụ:
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
public class PropertiesDemo {
private static Properties initializeProperties() {
Properties properties = new Properties();
properties.setProperty("1", "East");
properties.setProperty("2", "West");
properties.setProperty("3", "North");
properties.setProperty("4", "South");
return properties;
}
public static void main(String[] args) {
Properties initializedProperties = PropertiesDemo.initializeProperties();
Set<Object> set = initializedProperties.keySet();
Iterator<Object> itr = set.iterator();
while (itr.hasNext()) {
String key = (String) itr.next();
System.out.println("The value of " + key + " is " + initializedProperties.getProperty(key));
}
}
}
Phương thức initializeProperties()
của đoạn mã tạo một đối tượng Properties
và khởi tạo nó với các cặp khóa-giá trị thông qua các lời gọi đến phương thức setProperty()
. Phương thức main()
gọi phương thức keySet()
để trả về một đối tượng Set
chứa một tập hợp các khóa. Phương thức iterator()
trả về một đối tượng Iterator
được sử dụng để lặp qua các cặp khóa-giá trị. Đối với mỗi lần lặp, các cặp khóa-giá trị được in ra thông qua Iterator.next()
và Properties.getProperty()
.
Output:
The value of 1 is East
The value of 2 is West
The value of 3 is North
The value of 4 is South