TỔNG QUAN
CẤU TRÚC ĐIỀU KHIỂN
VÒNG LẶP
CHUỖI VÀ MẢNG
COLLECTIONS
THƯ VIỆN QUAN TRỌNG
HƯỚNG ĐỐI TƯỢNG
XỬ LÝ LUỒNG
EXCEPTION
LÀM VIỆC VỚI FILE
THAM KHẢO
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

HashSet trong Java

Trong bài này, tôi sẽ hướng dẫn đến các bạn tìm hiểu loại Class Collection tiếp theo - đó là HashSet trong Java. Nội dung của bài này sẽ mô tả đặc điểm, các phương thức thường dùng của Collection này. Với mỗi phương thức được liệt kê, tôi sẽ đưa ra ví dụ đơn giản để cho các bạn nắm bắt được. Cuối bài này tôi sẽ đưa ra một số bài tập để các bạn luyện tập!

1. Đặc điểm

HashSet là Class triển khai phổ biến nhất của Set Interface nên nó sẽ có một vài đặc điểm và phương thức tương đồng với Set. Như đã nói trong bài Tổng quan về Collection trong Java, thứ tự các phần tử trong HashSet không dựa theo thứ tự lúc thêm vào và giá trị của các phần tử này là duy nhất. 

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

2. Initial capacity và Load factor trong HashSet

Trong HashSet, chúng ta có 2 yếu tố ảnh hưởng trực tiếp tới hiệu suất của nó là Initial capacity (kích thước khởi tạo) và Load factor (tạm gọi là hệ số tải).

  • Kích thước của 1 HashSet là số lượng bucket có trong HashSet (bucket ở đây là nơi mà chúng ta lưu trữ các value của HashSet). Kích thước khởi tạo của HashSet là kích thước ngay tại thời điểm nó được khởi tạo và mặc định là 24 = 16 và nó sẽ tăng lên gấp đôi khi kích thước của HashSet đạt đến ngưỡng, ví dụ kích thước của HashSet sẽ tăng lên 25 = 32, 26 = 64, 27 = 128 ứng với từng ngưỡng mà nó đạt được.
  • Hệ số tải là chỉ số để đo xem đến ngưỡng nào thì kích thước (capacity) của HashSet sẽ tự động tăng lên. Giá trị mặc định của hệ số tải là 0.75f.

Vậy làm thế nào để tính ngưỡng của HashSet? Để tính ngưỡng của 1 HashSet chúng ta sẽ áp dụng theo công thức sau:

Threshold = Current capacity * Load factor 

, trong đó Threshold là ngưỡng mà chúng ta cần tính, Current capacity và Load lactor lần lượt là kích thước hiện tại và yếu tố tải của HashSet.

Ví dụ: Giả sử 1 HashSet được khởi tạo với kích thước ban đầu là 16 và yếu tố tải là 0.75 thì ngưỡng của HashSet này sẽ = 16 * 0.75 = 12. Con số 12 này có nghĩa là kích thước của HashSet này sẽ tăng từ 16 lên 32 sau khi phần tử thứ 12 được thêm vào trong HashSet đó.

Ý nghĩa của Initial capacity và Load factor đối với hiệu suất của HashSet: Đây là 2 yếu tố chính ảnh hưởng tới hiệu suất hoạt động của HashSet, vì vậy việc lựa chọn kích thước ban đầu và hệ số tải phù hợp sẽ giúp cho hiệu suất hoạt động của HashSet đạt hiệu quả tốt trong những yêu cầu phức tạp mà chúng ta gặp phải khi lập trình với HashSet.

3. Các thao tác cơ bản trên HashSet

Tạo mới một HashSet

Để khai báo một HashSet, chúng ta cần phải import gói thư viện java.util.HashSet của Java. Cú pháp import như sau:

Cú pháp
// Khai báo HashSet
// thì import gói thư viện java.util.HashSet
import java.util.HashSet;
public class TênClass {
	// ...
}


Sau đây là ví dụ cách tạo mới một HashSet trong Java:

Ví dụ
public static void main(String[] args) {
	// khai báo 1 HashSet có tên là hashSetInt
	// có kiểu là Integer 
	HashSet<Integer> hashSetInt = new HashSet<>();
		
	// khai báo 1 Hashset có kích thước khởi tạo = 32
	HashSet<Character> hashSetChar = new HashSet<>(32);
		
	// khai báo 1 HashSet có kích thước khởi tạo = 16
	// và yếu tố tải = 0.75f (mặc định)
	HashSet<String> hashSetString = new HashSet<>(16, 0.75f);
		
	// khai báo 1 HashSet được tạo thành từ 1 Collection khác
	HashSet<Float> hashSetFloat = new HashSet<>(new TreeSet<>());
}

Hiển thị các phần tử có trong HashSet.

Để hiển thị các phần tử có trong HashSet, chúng ta có các cách như sau:

Hiển thị theo tên HashSet.

Ví dụ
public static void main(String[] args) {
	// khai báo 1 HashSet có tên là hashSet
	// có kiểu là String 
	HashSet<String> hashSet = new HashSet<>();
		
	// thêm các phần tử vào hashSet sử dụng phương thức add()
	hashSet.add("JAVA");
	hashSet.add("JSP");
	hashSet.add("STRUTS");
	hashSet.add("HIBERNATE");
	hashSet.add("JSP");
	hashSet.add("JAVA");
 
	// hiển thị các phần tử có trong hashSet
	// trong hashSet có 2 phần tử là "JAVA" 
	// mà các phần tử trong 1 HashSet là không trùng nhau
	// nên sẽ chỉ có 1 phần tử "JAVA" được hiển thị.
	System.out.println("Các phần tử có trong hashSet là: ");
	System.out.println(hashSet);
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du hien thi HashSet theo ten PNG

Sử dụng vòng lặp for cải tiến duyệt theo đối tượng trong HashSet.

Ví dụ
public static void main(String[] args) {
	// khai báo 1 HashSet có tên là hashSet
	// có kiểu là String 
	HashSet<String> hashSet = new HashSet<>();
		
	// thêm các phần tử vào hashSet sử dụng phương thức add()
	hashSet.add("ONE");
	hashSet.add("TWO");
	hashSet.add("THREE");
	hashSet.add("FOUR");;
 
	// hiển thị các phần tử có trong hashSet
	// bằng cách sử dụng vòng lặp for duyệt theo đối tượng
	// trong đó kiểu dữ liệu của biến str
	// phải trùng với kiểu dữ liệu của hashSet
	System.out.println("Các phần tử có trong hashSet là: ");
	for (String str : hashSet) {
		System.out.print(str + "\t");
	}
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du hien thi HashSet su dung for cai tien PNG

Sử dụng Iterator.

Để sử dụng được Iterator chúng ta cần phải import gói thư viện java.util.Iterator của Java:

Ví dụ
public static void main(String[] args) {
	// khai báo 1 HashSet có tên là hashSet
	// có kiểu là Integer 
	HashSet<Integer> hashSet = new HashSet<>();
		
	// thêm các phần tử vào hashSet sử dụng phương thức add()
	hashSet.add(1);
	hashSet.add(2);
	hashSet.add(1);
	hashSet.add(6);
 
	// khai báo một Iterator có kiểu là Integer
	Iterator<Integer> iterator = hashSet.iterator();
		
	// hiển thị các phần tử có trong linkedList
	// bằng cách sử dụng Iterator
	System.out.println("Các phần tử có trong hashSet là: ");
	while (iterator.hasNext()) {
		System.out.print(iterator.next() + "\t");
	}
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du hien thi HashSet su dung iterator PNG

Thêm phần tử vào trong HashSet

Thêm phần tử sử dụng phương thức add().

Ví dụ
public static void main(String[] args) {
	int number;
	HashSet<Integer> hashSetInteger = new HashSet<>();
	Scanner scanner = new Scanner(System.in);
				
	// thêm các phần tử vào hashSetInteger
	hashSetInteger.add(0);
	hashSetInteger.add(3);
	hashSetInteger.add(1);
	hashSetInteger.add(4);
	hashSetInteger.add(2);
	hashSetInteger.add(8);
				
	// hiển thị các phần tử trong hashSetInteger
	System.out.println("Các phần tử trong hashSetInteger: ");
	System.out.println(hashSetInteger);
				
	System.out.println("Nhập phần tử cần thêm: ");
	number = scanner.nextInt();
				
	// thêm một phần tử mới vào hashSetInteger từ bàn phím
	// nếu phần tử đó đã tồn tại thì thông báo đã tồn tại
	// ngược lại thì thêm vào
	if (!hashSetInteger.contains(number)) {
		hashSetInteger.add(number);
		System.out.println("Thêm thành công!");
		System.out.println("Các phần tử trong hashSetInteger sau khi thêm: ");
		System.out.println(hashSetInteger);
	} else {
		System.out.println("Phần tử " + number + " đã tồn tại!");
	}
}
	

Kết quả sau khi biên dịch chương trình:

ketqua vi du them phan tu HashSet PNG

Xóa phần tử

Để xóa một phần tử khỏi HashSet, chúng ta sẽ sử dụng phương thức remove(). Ví dụ dưới đây sẽ sử dụng phương thức remove() để xóa một phần tử bất kỳ trong hashSetString:

Ví dụ
public static void main(String[] args) {
	String name;
	HashSet<String> hashSetString = new HashSet<>();
	Scanner scanner = new Scanner(System.in);
				
	// thêm các phần tử vào hashSetString
	hashSetString.add("Wilson");
	hashSetString.add("Nike");
	hashSetString.add("Volvo");
	hashSetString.add("Kia");
	hashSetString.add("Lenovo");
	hashSetString.add("Lenovo");
				
	// hiển thị các phần tử trong hashSetString
	System.out.println("Các phần tử trong hashSetString: ");
	System.out.println(hashSetString);
						
	System.out.println("Nhập phần tử cần xóa: ");
	name = scanner.nextLine();
				
	// nếu phần tử cần xóa 
	// có tồn tại hashSetString thì sẽ thông báo xóa thành công
	// và hiển thị các phần tử còn lại
	// ngược lại thông báo xóa không thành công
	if (hashSetString.contains(name)) {
		hashSetString.remove(name);
		System.out.println("Xóa thành công!");
		System.out.println("Các phần tử còn lại trong hashSetString:");
		System.out.println(hashSetString);
	} else {
		System.out.println("Xóa không thành công!");
	}
}
	

Kết quả sau khi biên dịch chương trình:

Trường hợp 1: Xóa phần tử thành công:

ketqua vi du xoa phan tu HashSet su dung remove thanh cong PNG

Trường hợp 2: Xóa phần tử thất bại:

ketqua vi du xoa phan tu HashSet su dung remove that bai PNG

Để xóa tất cả các phần tử có trong HashSet, chúng ta sẽ sử dụng phương thức clear() có sẵn của Java. Ví dụ:

Ví dụ
public static void main(String[] args) {
	float fNumber;
	HashSet<Float> hashSetFloat = new HashSet<>();
			
	// thêm các phần tử vào hashSetFloat
	hashSetFloat.add(7.14f);
	hashSetFloat.add(19.14f);
	hashSetFloat.add(1.11f);
	hashSetFloat.add(20.14f);
				
	// xóa toàn bộ các phần tử trong hashSetFloat
	// sử dụng phương thức clear()
	hashSetFloat.clear();
			
	// sau khi xóa thì trong hashSetFloat
	// sẽ không có phần tử nào
	// phương thức isEmpty() dưới đây sẽ kiểm tra 
	// nếu hashSetFloat không có giá trị
	// thì sẽ hiển thị thông báo "Không có phần tử"
	if (hashSetFloat.isEmpty()) {
		System.out.println("Không có phần tử.");
	}
}
	

Kết quả sau khi biên dịch chương trình:

ketqua vi du xoa phan tu HashSet su dung clear PNG

Chuyển đổi HashSet thành mảng (Array)

Để chuyển đổi 1 HashSet thành mảng, chúng ta sẽ sử dụng phương thức toArray() có sẵn của Java.

Ví dụ
public static void main(String[] args) {
	// Tạo 1 HashSet có tên là hashSetString
	HashSet<String> hashSetString = new HashSet<String>();
	
	hashSetString.add("Element 1");
	hashSetString.add("Element 2");
	hashSetString.add("Element 3");
	hashSetString.add("Element 4");
	 
	System.out.println("CÁc phần tử của hashSetString là: " + hashSetString);
	
	// Tạo 1 mảng có tên là array và có cùng kiểu dữ liệu với hashSetString
	// số phần tử của hashSetString là số phần tử của array
	String[] array = new String[hashSetString.size()];
	    
	// chuyển hashSetString thành mảng sử dụng toArray()
	hashSetString.toArray(array);
	 
	// Hiển thị các phần tử của array
	System.out.println("Các phần tử của array: ");
	for(String temp : array){
		System.out.println(temp);
	}
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du chuyen HashSet sang Array PNG

3. Ví dụ tổng hợp

 Viết chương trình thực hiện các công việc sau:

  • Khai báo 1 HashSet có kiểu dữ liệu là String. Sau đó thêm vào HashSet này tên của các loại trái cây được nhập bất kỳ từ bàn phím.
  • Hiển thị số phần tử có trong HashSet vừa tạo.
  • Nhập vào tên 1 loại trái cây và kiểm tra loại trái cây đó có tồn tại trong HashSet này hay không. Nếu có thì thông báo có tìm thấy, ngược lại thì thông báo không tìm thấy.
  • Xóa 1 loại trái cây bất kỳ trong HashSet đó và hiển thị các phần tử còn lại.
  • Tạo 1 List mới có cùng kiểu dữ liệu với HashSet và thêm các phần tử của List này. Sau đó thêm các phần tử của List này vào trong HashSet ban đầu và hiển thị lại HashSet này sử dụng Iterator.
  • Xóa các phần tử của List có trong HashSet và hiển thị lại HashSet.

Ví dụ
public static void main(String[] args) {
	String fruitName;
	int n;
	Scanner scanner = new Scanner(System.in);

	// Tạo 1 HashSet có tên là hashSetFruits
	HashSet<String> hashSetFruits = new HashSet<String>();
	
	System.out.println("Nhập vào số phần tử của hashSetFruits: ");
	n = Integer.parseInt(scanner.nextLine());	// hạn chế hiện tượng trôi lệnh
		
	System.out.println("Nhập vào tên các loại trái cây: ");
	for (int i = 0; i < n; i++) {
		System.out.print("Nhập tên loại trái cây thứ " + i + ": ");
		fruitName = scanner.nextLine();
		hashSetFruits.add(fruitName);
	}

	// hiển thị số phần tử của hashSetFruits
	// sử dụng phương thức size()
	System.out.println("Số phần tử của hashSetFruits = " + hashSetFruits.size());
	 
	// tìm loại trái cây
	System.out.println("Nhập tên loại trái cây cần tìm: ");
	String fruitSearch = scanner.nextLine();
	if (hashSetFruits.contains(fruitSearch)) {
		System.out.println("Có trái cây " + fruitSearch + " trong hashSetFruits!");
	} else {
		System.out.println("Không tìm thấy " + fruitSearch);
	}
		
	// Xóa 1 loại trái cây bất kỳ trong HashSet đó và hiển thị các phần tử còn lại.
	System.out.println("Nhập vào tên loại trái cây cần xóa: ");
	String fruitDelete = scanner.nextLine();

	if (hashSetFruits.contains(fruitDelete)) {
		hashSetFruits.remove(fruitSearch);
		System.out.println("Xóa thành công!");
		System.out.println("Các phần tử còn lại trong hashSetFruits: " + hashSetFruits);
	} else {
		System.out.println("Xóa không thành công!");
	}
		
	// Tạo 1 List mới có cùng kiểu dữ liệu với HashSet
	// và thêm các phần tử của List này.
	List<String> listFruits = new ArrayList<>();
	listFruits.add("Apple");
	listFruits.add("Banana");
	listFruits.add("Mango");
	listFruits.add("Apple");

	// thêm các phần tử của List này vào trong HashSet ban đầu 
	// và hiển thị lại HashSet này sử dụng Iterator.
	// sử dụng phương thức addAll()
	hashSetFruits.addAll(listFruits);
	System.out.println("Các phần tử có trong hashSetFruits sau khi thêm: ");
	Iterator<String> iterator = hashSetFruits.iterator();
	while (iterator.hasNext()) {
		System.out.print(iterator.next() + "\t");
	}
		
	// Xóa các phần tử của List có trong HashSet và hiển thị lại HashSet
	// sử dụng phương thức removeAll()
	hashSetFruits.removeAll(listFruits);
	System.out.println("\nCác phần tử có trong hashSetFruits sau khi xóa: " + hashSetFruits);
}

Kết quả sau khi biên dịch chương trình:

ketqua vi du tong hop HashSet PNG

4. Lời kết

Trong bài này, tôi đã giới thiệu cho các bạn đặc điểm, các phương thức thường dùng của HashSet. Sang bài sau chúng ta sẽ tiếp tục tìm hiểu 1 loại Class Collection tiếp theo đó là TreeSet trong Java. Các bạn theo dõi nhé!

Câu hỏi thường gặp liên quan:

Cùng chuyên mục:

Khi nào dùng Default Methods trong Java 8

Khi nào dùng Default Methods trong Java 8

Ở 2 bài trước chúng ta đã tìm hiểu 2 tính năng mới của Java…

Cách chuyển chữ hoa thành chữ thường trong Java

Cách chuyển chữ hoa thành chữ thường trong Java

Trong bài viết này chúng ta sẽ tìm hiểu về cách chuyển đổi chữ in…

Bài tập tính tổng các số tự nhiên trong Java

Bài tập tính tổng các số tự nhiên trong Java

Các số dương 1, 2, 3, 4, ... được gọi là các số tự nhiên,…

Cách chuyển chữ thường thành chữ hoa trong Java

Cách chuyển chữ thường thành chữ hoa trong Java

Trong chuỗi có thể vừa có ký tự thường vừa có ký tự hoa, nhưng…

Cách viết hoa ký tự đầu tiên trong Java

Cách viết hoa ký tự đầu tiên trong Java

Để hiểu được bài này, các bạn cần có kiến thức căn bản về Java…

Hướng dẫn chuyển đổi giờ phút giây trong Java

Hướng dẫn chuyển đổi giờ phút giây trong Java

Để hiểu được chương trình, các bạn cần có kiến thức cơ bản về Java.…

Cách lấy thời gian hiện tại trong Java

Cách lấy thời gian hiện tại trong Java

Để hiểu được bài viết này, các bạn cần có kiến thức cơ bản sau…

Cách làm tròn số trong Java

Cách làm tròn số trong Java

Khi thực hiện tính toán, việc kết quả ra một con số thập phân dài…

Cách tìm ma trận chuyển vị trong Java

Cách tìm ma trận chuyển vị trong Java

Quá trình hoán đổi giữa hàng và cột được gọi là chuyển vị của ma…

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Cách chuyển ArrayList thành mảng và ngược lại trong Java

Để hiểu được bài này, các bạn cần có kiến thức cơ bản về mảng…

Cách nối hai mảng trong Java

Cách nối hai mảng trong Java

Mình sẽ thực hiện hai chương trình nối mảng. Chương trình thứ nhất nối hai…

Cách xóa khoảng trắng của chuỗi trong Java

Cách xóa khoảng trắng của chuỗi trong Java

Mình sẽ thực hiện hai chương trình khác nhau để các bạn có thể hiểu…

In ra tam giác bằng ký tự * và số trong Java

In ra tam giác bằng ký tự * và số trong Java

Mình sẽ giới thiệu cách để in ra các tam giác bằng ký tự *…

Tìm số lớn nhất trong mảng Java

Tìm số lớn nhất trong mảng Java

Các bạn cần tìm hiểu về mảng, cách khởi tạo và in mảng trong Java…

Tìm ước của một số nguyên trong Java

Tìm ước của một số nguyên trong Java

Trong bài viết này chúng ta sẽ tìm hiểu cách tìm tất cả các ước…

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số hoàn hảo trong Java

Cách kiểm tra số đối xứng trong Java

Cách kiểm tra số đối xứng trong Java

Trong bài viết này chúng ta sẽ kiểm tra một số có phải là số…

Đảo ngược một số trong Java

Đảo ngược một số trong Java

Mình sẽ giới thiệu các bạn cách đảo ngược một số sử dụng vòng lặp…

Tìm bội chung nhỏ nhất trong Java

Tìm bội chung nhỏ nhất trong Java

Mình sẽ sử dụng hai cách khác nhau để tìm BCNN. Cách thứ nhất mình…

Cách hoán đổi hai số trong Java

Cách hoán đổi hai số trong Java

Trong phần này mình sẽ sử dụng một biến tạm temp() làm biến trung gian…

Top