Class Vector<E>
Vector là một lớp trong Java thuộc Java Collections Framework và nằm trong gói java.util. Tương tự như ArrayList, Vector cũng là một mảng động dùng để lưu trữ các đối tượng. Một trong những điểm khác biệt chính giữa Vector và ArrayList là Vector được đồng bộ hóa (synchronized).
Cách hoạt động của Vector
Thêm phần tử:
↳ Khi thêm một phần tử vào Vector, nó sẽ kiểm tra xem mảng hiện tại có đủ dung lượng không.
↳ Nếu có đủ dung lượng, phần tử sẽ được thêm vào mảng tại chỉ số kế tiếp.
↳ Nếu không đủ dung lượng, Vector sẽ tạo ra một mảng mới với kích thước lớn hơn dựa trên capacityIncrement, sao chép các phần tử từ mảng cũ sang mảng mới, và sau đó thêm phần tử mới vào mảng mới.
Truy cập phần tử:
↳ Bạn có thể truy cập phần tử tại một chỉ số cụ thể bằng cách sử dụng phương thức get(int index).
↳ Vector cung cấp truy cập nhanh chóng (O(1)) đến các phần tử nhờ sử dụng mảng.
Xóa phần tử:
↳ Khi xóa một phần tử tại một chỉ số cụ thể, Vector sẽ di chuyển các phần tử phía sau chỉ số đó về phía trước để lấp đầy khoảng trống.
↳ Việc di chuyển các phần tử có thể tốn thời gian (O(n)), vì tất cả các phần tử phía sau phải được dịch chuyển một vị trí về phía trước.
Cập nhật phần tử:
↳ Bạn có thể cập nhật phần tử tại một chỉ số cụ thể bằng cách sử dụng phương thức set(int index, E element).
↳ Vector sẽ thay thế phần tử cũ bằng phần tử mới tại chỉ số đã cho.
↳ Tìm kích thước và kiểm tra tính rỗng:
↳ Phương thức size() trả về số lượng phần tử hiện tại trong Vector.
↳ Phương thức isEmpty() kiểm tra xem Vector có chứa phần tử nào không.
Một số đặc điểm nổi bật của Vector<E>
↳ Quản lý dung lượng: Vector duy trì một dung lượng (capacity) và một giá trị tăng dung lượng (capacityIncrement). Khi thêm phần tử, nếu dung lượng hiện tại không đủ, Vector sẽ tự động tăng dung lượng theo từng khối bằng capacityIncrement.
↳ Đồng bộ hóa: Vector là một lớp đồng bộ hóa, tức là các thao tác trên Vector được bảo vệ để có thể được sử dụng một cách an toàn trong môi trường đa luồng. Tuy nhiên, nếu bạn không cần triển khai đồng bộ hóa (thread-safe), bạn nên sử dụng ArrayList vì nó sẽ có hiệu suất tốt hơn so với Vector.
↳ Truy cập ngẫu nhiên: Vector hỗ trợ truy cập ngẫu nhiên một cách hiệu quả nhờ vào việc triển khai giao diện RandomAccess.
↳ Fail-fast Iterators: Các iterator được trả về bởi lớp Vector là "fail-fast", có nghĩa là nếu có bất kỳ sự thay đổi nào đối với cấu trúc của Vector (như thêm hoặc xóa phần tử) trong khi đang duyệt qua các phần tử, iterator sẽ ném ra ngoại lệ ConcurrentModificationException.
↳ Khuyến nghị sử dụng ArrayList: Kể từ Java 2 (JDK 1.2), Vector đã được cập nhật để triển khai giao diện List và trở thành một phần của Java Collections Framework. Tuy nhiên, nếu không cần sự đồng bộ hóa, nên sử dụng ArrayList thay vì Vector vì ArrayList không đồng bộ hóa và thường có hiệu suất tốt hơn.
Khai báo Class Vector<E> trong Java
Để sử dụng Class Vector<E>, bạn cần import gói java.util vào đầu file Java của mình. Gói này cung cấp các lớp và giao diện để làm việc với các collection trong Java.
Cú pháp câu lệnh import:
Cú Pháp
import java.util.Vector;
Cú pháp khai báo Class Vector<E>:
Cú Pháp
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
Dưới đây là giải thích chi tiết về cú pháp khai báo này:
↳ public: Lớp Vector có thể được truy cập từ bất kỳ đâu trong chương trình.
↳ class: Từ khóa để khai báo một lớp trong Java.
↳ Vector<E>: Tên lớp là Vector, dùng generic E đại diện cho kiểu phần tử mà danh sách chứa.
↳ extends AbstractList<E>: Vector kế thừa từ lớp AbstractList, một lớp trừu tượng (abstract class) cung cấp các triển khai cơ bản của giao diện List. Điều này có nghĩa là Vector có thể tận dụng các phương thức đã được định nghĩa trong AbstractList và cũng có thể ghi đè (override) chúng nếu cần.
↳ implements List<E>: Vector triển khai giao diện List, có nghĩa là nó phải cung cấp các phương thức được định nghĩa trong giao diện List, chẳng hạn như thêm, xóa, hoặc truy cập các phần tử theo chỉ số (index).
↳ implements RandomAccess: Vector cũng triển khai giao diện RandomAccess, điều này cho thấy rằng Vector hỗ trợ truy cập ngẫu nhiên hiệu quả (bằng chỉ số). Giao diện này chỉ là một chỉ dẫn cho các nhà phát triển và JVM rằng Vector cung cấp truy cập phần tử nhanh chóng, tương tự như mảng.
↳ implements Cloneable: Vector có thể được sao chép (clone) nhờ triển khai giao diện Cloneable. Điều này có nghĩa là bạn có thể tạo ra một bản sao của Vector bằng phương thức clone().
↳ implements Serializable: Vector có thể được tuần tự hóa (serialization), cho phép đối tượng Vector được chuyển thành một chuỗi byte và được lưu trữ hoặc truyền qua mạng.
Các trường (fields) trong lớp Vector
Khi làm việc với lớp Vector trong Java – một triển khai danh sách đồng bộ hóa (synchronized list) kế thừa từ AbstractList và triển khai List, RandomAccess, Cloneable, Serializable – việc hiểu rõ các trường nội bộ của nó là rất quan trọng. Các trường này quy định cách Vector quản lý bộ nhớ và lưu trữ các phần tử. Dưới đây là mô tả chi tiết về các trường chính:
↳ protected int capacityIncrement: Một số nguyên bảo lưu số lượng mà dung lượng của vector tăng tự động khi kích thước của nó lớn hơn dung lượng hiện tại. Khi một vector đạt đến giới hạn dung lượng của nó, nó sẽ tự động tăng kích thước bằng cách thêm một số lượng phần tử mới. Giá trị mặc định của capacityIncrement là 10.
↳ protected int elementCount: Một số nguyên biểu thị số lượng phần tử hợp lệ trong vector. Nó không nhất thiết phải bằng với kích thước của mảng elementData.
↳ protected Object[] elementData: Một mảng đối tượng chứa các phần tử của vector. Kích thước của mảng này có thể lớn hơn hoặc bằng elementCount.
Các constructor của lớp Vector
Khi bạn làm việc với Vector trong Java – một lớp triển khai List đồng bộ (synchronized), việc khởi tạo đúng cách là bước đầu tiên để sử dụng nó hiệu quả. Vector cung cấp nhiều constructor khác nhau, cho phép bạn tạo một Vector rỗng, khởi tạo từ một Collection sẵn có, hoặc định rõ dung lượng ban đầu và mức độ tăng trưởng. Dưới đây là chi tiết về các constructor mà bạn có thể sử dụng:
↳ Vector(): Tạo một vector rỗng với dung lượng ban đầu là 10 và tăng trưởng dung lượng mặc định là 0.
↳ Vector(Collection<? extends E> c): Tạo một vector chứa các phần tử từ một bộ sưu tập khác.
↳ Vector(int initialCapacity): Tạo một vector rỗng với dung lượng ban đầu được chỉ định và tăng trưởng dung lượng bằng 0.
↳ Vector(int initialCapacity, int capacityIncrement): Tạo một vector rỗng với dung lượng ban đầu và tăng trưởng dung lượng được chỉ định.
Ví dụ
// Tạo một vector rỗng với dung lượng ban đầu là 10 và tăng trưởng dung lượng mặc định là 0
Vector<String> vector1 = new Vector<>();
// Tạo một vector chứa các phần tử từ một bộ sưu tập khác
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Vector<Integer> vector2 = new Vector<>(numbers);
// Tạo một vector rỗng với dung lượng ban đầu được chỉ định và tăng trưởng dung lượng bằng 0
Vector<Character> vector3 = new Vector<>(20);
// Tạo một vector rỗng với dung lượng ban đầu và tăng trưởng dung lượng được chỉ định
Vector<Double> vector4 = new Vector<>(15, 5); // Dung lượng ban đầu là 15, tăng trưởng 5 đơn vị mỗi khi cần thiết
Lưu ý:
↳ Vector là một lớp cũ hơn và ít được sử dụng hơn so với ArrayList trong Java hiện đại. ArrayList thường được ưu tiên hơn vì nó có hiệu suất tốt hơn và dễ sử dụng hơn.
↳ Nếu bạn cần sử dụng Vector, hãy đảm bảo hiểu rõ các trường và phương thức của nó để sử dụng đúng cách.
Các phương thức chính trong lớp Vector
Nếu bạn cần sử dụng Vector, hãy đảm bảo hiểu rõ các trường và phương thức của nó để sử dụng đúng cách. Một số phương thức của Vector, như addElement() và elements(), là di sản từ các phiên bản cũ của Java và không được khuyến khích sử dụng nữa. Dưới đây là danh sách tất cả các phương thức của Class Vector<E> trong Java:
↳ boolean add(E e): Thêm phần tử được chỉ định vào cuối danh sách. Trả về true nếu thêm thành công.
↳ void add(int index, E element): Thêm phần tử vào đúng vị trí index. Các phần tử phía sau sẽ được đẩy sang phải.
↳ boolean addAll(Collection<? extends E> c): Lấy tất cả phần tử từ collection c (ví dụ: ArrayList, HashSet,...) và thêm chúng vào cuối Vector theo đúng thứ tự ban đầu. Trả về true nếu có thay đổi.
↳ boolean addAll(int index, Collection<? extends E> c): Các phần tử từ collection c sẽ được chèn vào tại vị trí index, đẩy các phần tử cũ sang phải. Trả về true nếu thêm thành công.
↳ void addElement(E obj): Tương tự add(E e), nhưng là phương thức cũ (được dùng nhiều trong các phiên bản Java trước đây).
↳ int capacity(): Trả về dung lượng hiện tại của vector.
↳ void clear(): Xóa tất cả các phần tử khỏi vector.
↳ Object clone(): Tạo một bản sao của vector.
↳ boolean contains(Object o): Trả về true nếu Vector chứa phần tử được chỉ định. Kiểm tra xem phần tử đó có tồn tại trong Vector hay không.
↳ boolean containsAll(Collection<?> c): Trả về true nếu Vector chứa tất cả phần tử của Collection được chỉ định. So sánh các phần tử trong Collection truyền vào, và kiểm tra xem chúng đều có trong Vector hay không.
↳ void copyInto(Object[] anArray): Sao chép các thành phần của vector vào một mảng.
↳ E elementAt(int index): Lấy phần tử tại vị trí index trong vector.
↳ Enumeration<E> elements(): Trả về một enumeration (một dạng iterator cũ hơn) của các thành phần trong vector.
↳ void ensureCapacity(int minCapacity): Tăng dung lượng của vector để đảm bảo nó có thể chứa ít nhất số lượng phần tử đã chỉ định.
↳ boolean equals(Object o): So sánh hai vector để xem chúng có bằng nhau hay không.
↳ E firstElement(): Lấy phần tử đầu tiên của vector.s
↳ void forEach(Consumer<? super E> action): Thực hiện hành động đã cho cho mỗi phần tử trong vector.
↳ E get(int index): Lấy phần tử tại vị trí index trong vector.
↳ int hashCode(): Trả về giá trị mã băm cho vector này.
↳ int indexOf(Object o): Trả về chỉ số (vị trí) của lần xuất hiện đầu tiên của phần tử được chỉ định trong Vector. Nếu phần tử tồn tại, trả về vị trí đầu tiên của nó (bắt đầu từ 0). Nếu không có, trả về -1.
↳ int indexOf(Object o, int index): Trả về chỉ số của lần xuất hiện đầu tiên của phần tử được chỉ định, bắt đầu tìm từ vị trí index. Nếu phần tử không được tìm thấy sau vị trí đó, trả về -1.
↳ void insertElementAt(E obj, int index): Chèn phần tử obj vào vị trí index trong vector.
↳ boolean isEmpty(): Kiểm tra xem vector có rỗng hay không.
↳ Iterator<E> iterator(): Trả về một iterator để duyệt các phần tử trong danh sách theo đúng thứ tự.
↳ ListIterator<E> listIterator(): Trả về một ListIterator để duyệt danh sách theo thứ tự (từ đầu đến cuối), và cho phép di chuyển hai chiều (lên hoặc xuống danh sách).
↳ ListIterator<E> listIterator(int index): Trả về một ListIterator bắt đầu duyệt từ vị trí index chỉ định.
↳ E lastElement(): Lấy phần tử cuối cùng của vector.
↳ int lastIndexOf(Object o): Trả về chỉ số (vị trí) của lần xuất hiện cuối cùng của phần tử được chỉ định trong Vector.
↳ int lastIndexOf(Object o, int index): Trả về vị trí xuất hiện cuối cùng của phần tử được chỉ định, bắt đầu tìm ngược lại từ vị trí index.
↳ E remove(int index): Xóa phần tử tại vị trí chỉ định trong Vector.
↳ boolean remove(Object o): Xóa lần xuất hiện đầu tiên của phần tử được chỉ định trong Vector.
↳ boolean removeAll(Collection<?> c): Xóa tất cả phần tử trong Vector mà có trong Collection được chỉ định.
↳ void removeAllElements(): Xóa toàn bộ phần tử trong Vector và đặt kích thước về 0.
↳ boolean removeElement(Object obj): Xóa phần tử đầu tiên xuất hiện của đối tượng obj trong vector.
↳ void removeElementAt(int index): Phương thức này xóa phần tử tại chỉ số được chỉ định trong Vector.
↳ boolean removeIf(Predicate<? super E> filter): Xóa tất cả các phần tử thỏa mãn điều kiện filter.
↳ void replaceAll(UnaryOperator<E> operator): Thay thế mỗi phần tử trong vector bằng kết quả của việc áp dụng toán tử lên phần tử đó.
↳ boolean retainAll(Collection<?> c): Giữ lại chỉ những phần tử trong vector này cũng có trong collection c.
↳ E set(int index, E element): Thay thế phần tử tại vị trí chỉ định bằng phần tử mới.
↳ void setElementAt(E obj, int index): Đặt phần tử mới vào vị trí chỉ định trong Vector.
↳ void setSize(int newSize): Thiết lập kích thước của vector.
↳ int size(): Trả về số lượng phần tử trong vector.
↳ void sort(Comparator<? super E> c): Sắp xếp vector theo bộ so sánh đã cho.
↳ Spliterator<E> spliterator(): Tạo một Spliterator duyệt qua các phần tử trong vector.
↳ List<E> subList(int fromIndex, int toIndex): Trả về một view của một phần của vector.
↳ Object[] toArray(): Phương thức này trả về một mảng kiểu Object[] chứa tất cả phần tử trong Vector, theo đúng thứ tự.
↳ <T> T[] toArray(T[] a): Phương thức này trả về một mảng chứa tất cả các phần tử của Vector, với kiểu runtime của mảng là kiểu của tham số truyền vào.
↳ String toString(): Trả về một chuỗi biểu diễn vector.
↳ void trimToSize(): Giảm dung lượng của vector xuống bằng với kích thước hiện tại.
Ví dụ về cách sử dụng các phương thức thêm phần tử
Dưới đây là ví dụ minh họa cho từng phương thức của lớp Vector trong Java, liên quan đến việc thêm phần tử vào danh sách:
Ví dụ: Example.java
import java.util.ArrayList;
import java.util.Vector;
public class Example {
public static void main(String[] args) {
// Tạo một Vector với kiểu dữ liệu Integer
Vector<Integer> vector = new Vector<>();
// Sử dụng phương thức add(E e): Thêm phần tử vào cuối danh sách
vector.add(10);
vector.add(20);
vector.add(30);
System.out.println("Vector sau khi thêm các phần tử bằng add(E e): " + vector);
// Sử dụng phương thức add(int index, E element): Chèn phần tử vào vị trí index
vector.add(1, 15); // Chèn 15 vào vị trí thứ 1 (giữa 10 và 20)
System.out.println("Vector sau khi chèn 15 vào vị trí index 1: " + vector);
// Sử dụng phương thức addAll(Collection<? extends E> c): Thêm tất cả các phần tử của một collection vào cuối danh sách
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(40);
arrayList.add(50);
vector.addAll(arrayList);
System.out.println("Vector sau khi thêm tất cả phần tử từ một ArrayList: " + vector);
// Sử dụng phương thức addAll(int index, Collection<? extends E> c): Thêm tất cả các phần tử của một collection vào vị trí index
ArrayList<Integer> anotherList = new ArrayList<>();
anotherList.add(5);
anotherList.add(7);
vector.addAll(0, anotherList); // Thêm các phần tử vào đầu danh sách
System.out.println("Vector sau khi thêm tất cả phần tử từ một collection vào vị trí index 0: " + vector);
// Sử dụng phương thức addElement(E obj): Thêm phần tử vào cuối danh sách (phương thức cũ)
vector.addElement(60);
System.out.println("Vector sau khi thêm phần tử bằng addElement(E obj): " + vector);
// Sử dụng phương thức insertElementAt(E obj, int index): Chèn phần tử vào vị trí index
vector.insertElementAt(25, 3); // Chèn 25 vào vị trí thứ 3
System.out.println("Vector sau khi chèn 25 vào vị trí index 3: " + vector);
}
}
Kết quả của chương trình là:
Vector sau khi chèn 15 vào vị trí index 1: [10, 15, 20, 30]
Vector sau khi thêm tất cả phần tử từ một ArrayList: [10, 15, 20, 30, 40, 50]
Vector sau khi thêm tất cả phần tử từ một collection vào vị trí index 0: [5, 7, 10, 15, 20, 30, 40, 50]
Vector sau khi thêm phần tử bằng addElement(E obj): [5, 7, 10, 15, 20, 30, 40, 50, 60]
Vector sau khi chèn 25 vào vị trí index 3: [5, 7, 10, 25, 15, 20, 30, 40, 50, 60]
Ví dụ về cách sử dụng các phương thức xóa phần tử
Dưới đây là ví dụ về cách sử dụng các phương thức xóa phần tử trong lớp Vector:
Ví dụ: Example.java
import java.util.ArrayList;
import java.util.Vector;
import java.util.function.Predicate;
public class Example {
public static void main(String[] args) {
// Tạo một Vector với kiểu dữ liệu Integer và thêm các phần tử vào
Vector<Integer> vector = new Vector<>();
vector.add(10);
vector.add(20);
vector.add(30);
vector.add(40);
vector.add(50);
// In Vector ban đầu
System.out.println("Vector ban đầu: " + vector);
// Sử dụng phương thức removeAll(Collection<?> c): Xóa tất cả các phần tử của danh sách này cũng có trong collection c
ArrayList<Integer> removeList = new ArrayList<>();
removeList.add(20);
removeList.add(40);
vector.removeAll(removeList);
System.out.println("Vector sau khi xóa tất cả các phần tử có trong removeList: " + vector);
// Sử dụng phương thức removeAllElements(): Xóa tất cả các phần tử trong danh sách
vector.removeAllElements();
System.out.println("Vector sau khi xóa tất cả các phần tử: " + vector);
// Tạo lại Vector và thêm các phần tử vào
vector.add(10);
vector.add(20);
vector.add(30);
vector.add(40);
vector.add(50);
// Sử dụng phương thức removeElement(Object obj): Xóa phần tử đầu tiên tìm thấy có giá trị bằng obj
vector.removeElement(30);
System.out.println("Vector sau khi xóa phần tử 30: " + vector);
// Sử dụng phương thức removeElementAt(int index): Xóa phần tử tại vị trí index
vector.removeElementAt(1); // Xóa phần tử tại vị trí index 1 (20)
System.out.println("Vector sau khi xóa phần tử tại vị trí index 1: " + vector);
// Sử dụng phương thức removeIf(Predicate<? super E> filter): Xóa tất cả các phần tử thỏa mãn điều kiện filter
vector.removeIf(new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
return t > 40; // Xóa tất cả các phần tử lớn hơn 40
}
});
System.out.println("Vector sau khi xóa tất cả các phần tử lớn hơn 40: " + vector);
}
}
Kết quả của chương trình là:
Vector sau khi xóa tất cả các phần tử có trong removeList: [10, 30, 50]
Vector sau khi xóa tất cả các phần tử: []
Vector sau khi xóa phần tử 30: [10, 20, 40, 50]
Vector sau khi xóa phần tử tại vị trí index 1: [10, 40, 50]
Vector sau khi xóa tất cả các phần tử lớn hơn 40: [10, 40]
Ví dụ về cách sử dụng các phương thức truy vấn phần tử
Dưới đây là ví dụ về cách sử dụng các phương thức truy vấn của lớp Vector với kiểu dữ liệu String:
Ví dụ: Example.java
import java.util.Vector;
public class Example {
public static void main(String[] args) {
// Tạo một Vector với kiểu dữ liệu String và thêm các phần tử vào
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
vector.add("Date");
vector.add("Apple"); // Thêm phần tử "Apple" thêm một lần nữa
// In Vector ban đầu
System.out.println("Vector ban đầu: " + vector);
// Sử dụng phương thức get(int index): Lấy phần tử tại vị trí index
String elementAtIndex2 = vector.get(2);
System.out.println("Phần tử tại vị trí index 2: " + elementAtIndex2);
// Sử dụng phương thức contains(Object o): Kiểm tra xem danh sách có chứa phần tử o hay không
boolean containsBanana = vector.contains("Banana");
System.out.println("Danh sách có chứa 'Banana' không: " + containsBanana);
// Sử dụng phương thức indexOf(Object o): Trả về chỉ số của lần xuất hiện đầu tiên của o
int indexOfCherry = vector.indexOf("Cherry");
System.out.println("Chỉ số của lần xuất hiện đầu tiên của 'Cherry': " + indexOfCherry);
// Sử dụng phương thức indexOf(Object o, int index): Trả về chỉ số của lần xuất hiện đầu tiên của o bắt đầu từ vị trí index
int indexOfAppleFromIndex2 = vector.indexOf("Apple", 2);
System.out.println("Chỉ số của lần xuất hiện đầu tiên của 'Apple' bắt đầu từ vị trí index 2: " + indexOfAppleFromIndex2);
// Sử dụng phương thức lastIndexOf(Object o): Trả về chỉ số của lần xuất hiện cuối cùng của o
int lastIndexOfApple = vector.lastIndexOf("Apple");
System.out.println("Chỉ số của lần xuất hiện cuối cùng của 'Apple': " + lastIndexOfApple);
// Sử dụng phương thức lastIndexOf(Object o, int index): Trả về chỉ số của lần xuất hiện cuối cùng của o bắt đầu từ vị trí index
int lastIndexOfAppleFromIndex3 = vector.lastIndexOf("Apple", 3);
System.out.println("Chỉ số của lần xuất hiện cuối cùng của 'Apple' bắt đầu từ vị trí index 3: " + lastIndexOfAppleFromIndex3);
// Sử dụng phương thức isEmpty(): Kiểm tra xem danh sách có rỗng hay không
boolean isEmpty = vector.isEmpty();
System.out.println("Danh sách có rỗng không: " + isEmpty);
// Sử dụng phương thức size(): Trả về số lượng phần tử trong danh sách
int size = vector.size();
System.out.println("Số lượng phần tử trong danh sách: " + size);
// Sử dụng phương thức firstElement(): Lấy phần tử đầu tiên
String firstElement = vector.firstElement();
System.out.println("Phần tử đầu tiên: " + firstElement);
// Sử dụng phương thức lastElement(): Lấy phần tử cuối cùng
String lastElement = vector.lastElement();
System.out.println("Phần tử cuối cùng: " + lastElement);
}
}
Kết quả của chương trình là:
Phần tử tại vị trí index 2: Cherry
Danh sách có chứa 'Banana' không: true
Chỉ số của lần xuất hiện đầu tiên của 'Cherry': 2
Chỉ số của lần xuất hiện đầu tiên của 'Apple' bắt đầu từ vị trí index 2: 4
Chỉ số của lần xuất hiện cuối cùng của 'Apple': 4
Chỉ số của lần xuất hiện cuối cùng của 'Apple' bắt đầu từ vị trí index 3: 0
Danh sách có rỗng không: false
Số lượng phần tử trong danh sách: 5
Phần tử đầu tiên: Apple
Phần tử cuối cùng: Apple
Ví dụ về cách sử dụng các phương thức thay đổi phần tử
Dưới đây là ví dụ minh họa các phương thức thay đổi của lớp Vector với kiểu dữ liệu String:
Ví dụ: Example.java
import java.util.Vector;
import java.util.function.UnaryOperator;
public class Example {
public static void main(String[] args) {
// Tạo một Vector với kiểu dữ liệu String và thêm các phần tử vào
Vector<String> vector = new Vector<>();
vector.add("Apple");
vector.add("Banana");
vector.add("Cherry");
vector.add("Date");
vector.add("Elderberry");
// In Vector ban đầu
System.out.println("Vector ban đầu: " + vector);
// Sử dụng phương thức set(int index, E element): Thay thế phần tử tại vị trí index
vector.set(2, "Blueberry");
System.out.println("Vector sau khi thay thế phần tử tại vị trí index 2 bằng 'Blueberry': " + vector);
// Sử dụng phương thức setElementAt(E obj, int index): Thay thế phần tử tại vị trí index (tương tự set(int index, E element))
vector.setElementAt("Coconut", 3);
System.out.println("Vector sau khi thay thế phần tử tại vị trí index 3 bằng 'Coconut': " + vector);
// Sử dụng phương thức replaceAll(UnaryOperator<E> operator): Thay thế mỗi phần tử bằng kết quả của việc áp dụng toán tử lên phần tử đó
vector.replaceAll(new UnaryOperator<String>() {
@Override
public String apply(String s) {
return s.toUpperCase(); // Chuyển tất cả các phần tử thành chữ hoa
}
});
System.out.println("Vector sau khi thay thế mỗi phần tử bằng chữ hoa: " + vector);
}
}
Kết quả của chương trình là:
Vector sau khi thay thế phần tử tại vị trí index 2 bằng 'Blueberry': [Apple, Banana, Blueberry, Date, Elderberry]
Vector sau khi thay thế phần tử tại vị trí index 3 bằng 'Coconut': [Apple, Banana, Blueberry, Coconut, Elderberry]
Vector sau khi thay thế mỗi phần tử bằng chữ hoa: [APPLE, BANANA, BLUEBERRY, COCONUT, ELDERBERRY]
Ví dụ về cách sử dụng listIterator(int index) với Vector
Dưới đây là ví dụ về cách sử dụng phương thức listIterator(int index) của lớp Vector với kiểu dữ liệu Double:
Ví dụ: Example.java
import java.util.ListIterator;
import java.util.Vector;
public class Example {
public static void main(String[] args) {
// Tạo một Vector với kiểu dữ liệu Double và thêm các phần tử vào
Vector<Double> vector = new Vector<>();
vector.add(1.1);
vector.add(2.2);
vector.add(3.3);
vector.add(4.4);
vector.add(5.5);
// In Vector ban đầu
System.out.println("Vector ban đầu: " + vector);
// Sử dụng phương thức listIterator(int index): Trả về một list iterator bắt đầu từ vị trí index
ListIterator<Double> listIterator = vector.listIterator(2); // Bắt đầu từ vị trí index 2
System.out.println("Duyệt qua các phần tử bắt đầu từ vị trí index 2:");
// Duyệt qua các phần tử bằng ListIterator
while (listIterator.hasNext()) {
Double element = listIterator.next();
System.out.println("Phần tử: " + element);
}
// Duyệt ngược lại với ListIterator
System.out.println("Duyệt ngược qua các phần tử:");
while (listIterator.hasPrevious()) {
Double element = listIterator.previous();
System.out.println("Phần tử: " + element);
}
}
}
Kết quả của chương trình là:
Duyệt qua các phần tử bắt đầu từ vị trí index 2:
Phần tử: 3.3
Phần tử: 4.4
Phần tử: 5.5
Duyệt ngược qua các phần tử:
Phần tử: 5.5
Phần tử: 4.4
Phần tử: 3.3
Phần tử: 2.2
Phần tử: 1.1
Ví dụ về cách sử dụng spliterator() với Vector
Dưới đây là ví dụ về cách sử dụng phương thức spliterator() của lớp Vector để tạo một Spliterator và duyệt qua các phần tử với kiểu dữ liệu Double:
Ví dụ: Example.java
import java.util.Spliterator;
import java.util.Vector;
import java.util.function.Consumer;
public class Example {
public static void main(String[] args) {
// Tạo một Vector với kiểu dữ liệu Double và thêm các phần tử vào
Vector<Double> vector = new Vector<>();
vector.add(1.1);
vector.add(2.2);
vector.add(3.3);
vector.add(4.4);
vector.add(5.5);
// In Vector ban đầu
System.out.println("Vector ban đầu: " + vector);
// Sử dụng phương thức spliterator(): Tạo một Spliterator duyệt qua các phần tử
Spliterator<Double> spliterator = vector.spliterator();
System.out.println("Duyệt qua các phần tử với Spliterator:");
// Duyệt qua các phần tử bằng Spliterator
spliterator.forEachRemaining(new Consumer<Double>() {
@Override
public void accept(Double element) {
System.out.println("Phần tử: " + element);
}
});
}
}
Kết quả của chương trình là:
Duyệt qua các phần tử với Spliterator:
Phần tử: 1.1
Phần tử: 2.2
Phần tử: 3.3
Phần tử: 4.4
Phần tử: 5.5
Ví dụ về cách sử dụng sort(Comparator<? super E> c) với Vector
Dưới đây là ví dụ về cách sử dụng phương thức sort(Comparator<? super E> c) của lớp Vector để sắp xếp danh sách theo một bộ so sánh (Comparator) với kiểu dữ liệu Double:
Ví dụ: Example.java
import java.util.Comparator;
import java.util.Vector;
public class Example {
public static void main(String[] args) {
// Tạo một Vector với kiểu dữ liệu Double và thêm các phần tử vào
Vector<Double> vector = new Vector<>();
vector.add(3.3);
vector.add(1.1);
vector.add(4.4);
vector.add(2.2);
vector.add(5.5);
// In Vector ban đầu
System.out.println("Vector ban đầu: " + vector);
// Sử dụng phương thức sort(Comparator<? super E> c): Sắp xếp danh sách theo bộ so sánh đã cho
vector.sort(new Comparator<Double>() {
@Override
public int compare(Double d1, Double d2) {
// So sánh theo thứ tự giảm dần
return d2.compareTo(d1);
}
});
// In Vector sau khi sắp xếp
System.out.println("Vector sau khi sắp xếp giảm dần: " + vector);
}
}
Kết quả của chương trình là:
Vector sau khi sắp xếp giảm dần: [5.5, 4.4, 3.3, 2.2, 1.1]
Ví dụ Vector với đối tượng do người dùng định nghĩa
Dưới đây là ví dụ về cách sử dụng phương thức subList(int fromIndex, int toIndex) của lớp Vector với đối tượng do người dùng định nghĩa. Ví dụ này tạo một Vector chứa các đối tượng Person, sau đó sử dụng subList để lấy một phần của danh sách.
Ví dụ: Example.java
import java.util.List;
import java.util.Vector;
// Đối tượng Person do người dùng định nghĩa
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + " (" + age + " Tuổi)";
}
}
public class Example {
public static void main(String[] args) {
// Tạo một Vector chứa các đối tượng Person
Vector<Person> vector = new Vector<>();
vector.add(new Person("Alice", 30));
vector.add(new Person("Bob", 25));
vector.add(new Person("Charlie", 35));
vector.add(new Person("Diana", 28));
vector.add(new Person("Edward", 40));
// In Vector ban đầu
System.out.println("Vector ban đầu:");
for (Person person : vector) {
System.out.println(person);
}
// Sử dụng phương thức subList(int fromIndex, int toIndex): Trả về một view của một phần của danh sách
List<Person> subList = vector.subList(1, 4); // Lấy các phần tử từ chỉ số 1 đến chỉ số 3 (4 không bao gồm)
// In subList
System.out.println("\nSubList (từ chỉ số 1 đến 3):");
for (Person person : subList) {
System.out.println(person);
}
}
}
Kết quả của chương trình là:
Alice (30 Tuổi)
Bob (25 Tuổi)
Charlie (35 Tuổi)
Diana (28 Tuổi)
Edward (40 Tuổi)
SubList (từ chỉ số 1 đến 3):
Bob (25 Tuổi)
Charlie (35 Tuổi)
Diana (28 Tuổi)
Ví dụ về cách sử dụng các phương thức equals(Object o) và hashCode()
Dưới đây là ví dụ về cách sử dụng các phương thức equals(Object o) và hashCode() của lớp Vector với kiểu dữ liệu String. Ví dụ này so sánh hai đối tượng Vector và lấy mã băm của chúng:
Ví dụ: Example.java
import java.util.Vector;
public class Example {
public static void main(String[] args) {
// Tạo hai Vector với kiểu dữ liệu String và thêm các phần tử vào
Vector<String> vector1 = new Vector<>();
vector1.add("Apple");
vector1.add("Banana");
vector1.add("Cherry");
Vector<String> vector2 = new Vector<>();
vector2.add("Apple");
vector2.add("Banana");
vector2.add("Cherry");
Vector<String> vector3 = new Vector<>();
vector3.add("Date");
vector3.add("Elderberry");
vector3.add("Fig");
// So sánh hai Vector
System.out.println("Vector1 và Vector2 có bằng nhau không? " + vector1.equals(vector2)); // True
System.out.println("Vector1 và Vector3 có bằng nhau không? " + vector1.equals(vector3)); // False
// Lấy mã băm của Vector
System.out.println("Mã băm của Vector1: " + vector1.hashCode());
System.out.println("Mã băm của Vector2: " + vector2.hashCode());
System.out.println("Mã băm của Vector3: " + vector3.hashCode());
}
}
Kết quả của chương trình là:
Vector1 và Vector3 có bằng nhau không? false
Mã băm của Vector1: -78891027
Mã băm của Vector2: -78891027
Mã băm của Vector3: -867153243
Như vậy, chúng ta đã xem xét các phương thức chính của lớp Vector. Dù Vector cung cấp đầy đủ các chức năng quản lý danh sách và đảm bảo an toàn luồng, nhưng điều quan trọng cần nhớ là nó thường không được khuyến khích sử dụng trong các ứng dụng Java hiện đại do hiệu suất kém hơn so với ArrayList (trong môi trường đơn luồng) và CopyOnWriteArrayList hoặc các cấu trúc Collections.synchronizedList (trong môi trường đa luồng). Việc hiểu về Vector giúp bạn nhận diện các mã nguồn cũ và biết lý do tại sao các lựa chọn thay thế hiện đại lại được ưu tiên.