HashSet ในภาษา Java

ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับการใช้งาน HashSet ที่ใช้สำหรับเก็บข้อมูลที่ไม่ซ้ำกันในภาษา Java

HashSet เป็นออบเจ็คที่ใช้สำหรับเก็บข้อมูลที่ไม่ซ้ำกัน โดยข้อมูลจะถูกเก็บในรูปแบบของ Hash สำหรับการเปรียบเทียบความเท่ากันของข้อมูล มันเป็นออบเจ็คจากคลาส HashSet ซึ่งคลาสนี้ได้มีการ Implement อินเตอร์เฟซ Set<E> ที่มีเมธอดสำหรับการทำเกี่ยวกับเซ็ต นี่เป็นเนื้อหาในบทนี้

  • การประกาศและใช้งาน HashSet
  • การวนรอบค่าใน HashSet
  • ตัวอย่างการใช้งาน HashSet

การประกาศและใช้งาน HashSet

ในการใช้งาน HashSet เพื่อเก็บข้อมูลที่ไม่ซ้ำกันเราจะต้องประกาศมันก่อน นี่เป็นรูปแบบที่ง่ายที่สุดในการประกาศออบเจ็ค HashSet ในภาษา Java

HashSet<E> set = new HashSet<E>();

ในรูปแบบการใช้งานเป็นการประกาศออบเจ็ค HashSet สำหรับเก็บข้อมูลประเภท E โดยที่ E นั้นสามารถเป็นคลาสใดๆ ในภาษา Java

เนื่องจาก HashSet นั้นเป็นคลาสที่ Implement มาจากอินเตอร์เฟซ Set<E> ดังนั้นในการประกาศออบเจ็ค เราสามารถใช้อินเตอร์เฟซ Set เป็นประเภทของออบเจ็คได้ดังนี้

Set<E> set = new HashSet<E>();

สำหรับตัวอย่างแรกในการใช้งาน HashSet เรามาใช้มันเก็บชื่อของสีซึ่งมีค่าเป็น String และเราจะแนะนำให้คุณรู้กับเมธอดพื้นฐานของ Set นี่เป็นตัวอย่าง

HashSetEx1.java
package com.marcuscode.hashset;

import java.util.HashSet;

public class HashSetEx1 {

    public static void main(String[] args) {

        HashSet<String> names = new HashSet<String>();

        // Add three names to set
        names.add("Metin");
        names.add("Jacob");
        names.add("Chris");

        // Count values in set
        System.out.println("Size: " + names.size());

        // Add same value in set
        names.add("Metin");
        System.out.println("Size: " + names.size());

        // Check if values are in the set
        System.out.println("Contain Metin?: " + names.contains("Metin"));
        System.out.println("Contain Foo?: " + names.contains("Foo"));

        // Remove item from the set
        names.remove("Chris");
        System.out.println("Size: " + names.size());

        // Remove all values from set
        names.clear();
        System.out.println("Is the set empty?: " + names.isEmpty());
        System.out.println("Size: " + names.size());

    }

}

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Size: 3
Size: 3
Contain Metin?: true
Contain Foo?: false
Size: 2
Is the set empty?: true
Size: 0

ในตัวอย่างนี้ เป็นการใช้งาน HashSet สำหรับเก็บชื่อของสีที่เป็น String และแสดงการใช้งานเมธอดพื้นฐานของ HashSet สำหรับการเพิ่ม การลบ และนับจำนวนข้อมูลภายใน Set

HashSet<String> names = new HashSet<String>();

คำสั่งนี้เป็นการสร้างออบเจ็คของ HashSet สำหรับเก็บข้อมูลประเภท String โดยการระบุคลาสของประเภทข้อมูลในวงเล็บ <String> จากนั้นเราสามารถใช้มันในการเก็บค่าของ String ใดๆ ในภาษา Java ได้

names.add("Metin");
names.add("Jacob");
names.add("Chris");

สิ่งแรกที่เราทำหลังจากประกาศออบเจ็คก็คือการเพิ่มข้อมูลเข้าไปยัง HashSet เพื่อเพิ่มข้อมูลเราใช้เมธอด add() เมธอดนี้จะทำการเพิ่มข้อมูลเข้าไปยัง Set หากค่าดังกล่าวไม่มีอยู่ ในตัวอย่างเป็นการเพิ่มสามรายชื่อเข้าไปยังออบเจ็ค names

System.out.println("Size: " + names.size());

เมธอด size() ส่งค่ากลับเป็นจำนวนของข้อมูลทั้งหมดที่ถูกเก็บใน HashSet เราสามารถใช้มันเพื่อนับว่ามีข้อมูลเท่าไหร่ที่ถูกเก็บไปแล้ว ในตัวอย่างเมธอดนี้ส่งค่ากลับเป็น 3

names.add("Metin");
System.out.println("Size: " + names.size());

ถ้าหากค่าที่เราเพิ่มเข้าไปยัง HashSet ด้วยเมธอด add() นั้นมีอยู่แล้ว ค่าดังกล่าวจะไม่ถูกเพิ่มเข้าไปอีก ดังนั้นในคำสั่งนี้ "Metin" จะไม่ถูกเพิ่มเข้าไปยัง Set อีกครั้ง และสังเกตว่าขนาดของ HashSet ยังคงเท่าเดิม

System.out.println("Contain Metin?: " + names.contains("Metin"));
System.out.println("Contain Foo?: " + names.contains("Foo"));

เพื่อตรวจสอบว่ามีข้อมูลที่ต้องการค้นหาอยู่ภายใน HashSet หรือไม่ เราใช้เมธอด contains() สำหรับการทำงานดังกล่าว เมธอดนี้ส่งค่ากลับเป็น Boolean ว่าค่าที่ต้องการตรวจสอบมีอยู่ใน Set หรือไม่

names.remove("Chris");

เราสามารถลบข้อมูลออกจาก HashSet ได้ด้วยเมธอด remove() เมื่อค่าถูกลบออกไปแล้ว การตรวจสอบว่านี้ด้วยเมธอด contains() จะส่งค่ากลับเป็น false

names.clear();
System.out.println("Is the set empty?: " + names.isEmpty());

ในขณะที่เมธอด remove() สำหรับลบค่าที่ระบุออกจาก HashSet เราสามารถใช้เมธอด clear() เพื่อลบข้อมูลทั้งหมดได้ จากนั้นเราตรวจสอบว่า Set ว่างอยู่หรือไม่ด้วยเมธอด isEmpty() เมธอดนี้ส่งค่ากลับเป็นจริง ถ้าหากจำนวนข้อมูลใน Set นั้นเป็น 0

การวนรอบค่าใน HashSet

ในการวนค่าทั้งหมดภายใน HashSet นั้นเราสามารถใช้เมธอด iterator() ที่ส่งค่ากลับเป็นออบเจ็ค Iterator ที่ใช้ร่วมกับคำสั่ง while loop เพื่อวนรอบค่าใน HashSet ได้

ในตัวอย่างนี้เป็นการวนรอบ HashSet ที่เก็บชื่อของภาษาเขียนโปรแกรม และแสดงค่าที่วนได้ออกทางหน้าจอ นี่เป็นตัวอย่าง

HashSetEx2.java
package com.marcuscode.hashset;

import java.util.HashSet;
import java.util.Iterator;

public class HashSetEx2 {

    public static void main(String[] args) {

        HashSet<String> languages = new HashSet<String>();

        languages.add("Java");
        languages.add("Scala");
        languages.add("Python");
        languages.add("C++");

        Iterator<String> it = languages.iterator();

        while (it.hasNext()) {
            String element = it.next();
            System.out.println(element);
        }
    }

}

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Java
C++
Scala
Python

ในตัวอย่างนี้ เราได้สร้าง HashSet สำหรับเก็บชื่อภาษาเขียนโปรแกรมคอมพิวเตอร์ จากนั้นแสดงค่าทั้งหมดใน Set ออกทางหน้าจอโดยการวนค่าจากออบเจ็ค Iterator ด้วยคำสั่ง while loop

HashSet<String> languages = new HashSet<String>();

และเช่นเดิม เราสร้างออบเจ็ค HashSet โดยระบุประเภทของข้อมูลที่ต้องการเก็บเป็น String เพื่อเก็บชื่อของภาษาเขียนโปรแกรมคอมพิวเตอร์ จากนั้นใช้เมธอด add() เพื่อเพิ่มข้อมูลจำนวน 4 รายชื่อเข้าไปยัง Set

Iterator<String> it = languages.iterator();

เพื่อวนค่าทั้งหมดภายใน HashSet เราสามารถใช้เมธอด iterator() เมธอดนี้ส่งค่ากลับเป็นออบเจ็ค Iterator ที่สามารถใช้วนเอาค่าใน Set ออกมาได้ โดยทั่วไปแล้วมันมักจะถูกใช้กับคำสั่งวนซ้ำ เช่น คำสั่ง while loop เป็นต้น

while (it.hasNext()) {
    String element = it.next();
    System.out.println(element);
}

จากนั้นเราใช้คำสั่ง while loop เพื่อวนเอาค่าในออบเจ็ค Iterator ออกมา โดยการเรียกใช้เมธอด next() เราได้ค่าที่เก็บใน Set มาจากออบเจ็ค Iterator ส่วนเมธอด hasNext() ใช้สำหรับตรวจสอบว่ายังมีข้อมูลเหลือให้วนอยู่อีกหรือไม่

ลำดับการวน: การวนรอบค่าใน HashSet นั้นไม่รับประกันว่าลำดับของการวนจะเหมือนกันทุกรอบเนื่องจากว่า HashSet ไม่ได้เก็บข้อมูลในรูปแบบของลำดับ นี่ก็เพื่อเพิ่มประสิทธิภาพและความเร็วในการเพิ่ม ลบ ตรวจสอบ หรือวนรอบค่าใน Set

ตัวอย่างการใช้งาน HashSet

HashSet นั้นเป็นคลาสที่ช่วยอำนวยความสะดวกในการเขียนโปรแกรม เราสามารถนำมันมาประยุกต์ในการแก้ปัญหาต่างๆ ได้ เช่น การดำเนินการพื้นฐานเกี่ยวกับเซ็ต Intersection, Union, Difference หรือ Semantic difference เป็นต้น ในตัวอย่างนี้ จะเป็นการใช้งาน HashSet สำหรับลบค่าที่ซ้ำกันออกจากอาเรย์ นี่เป็นตัวอย่าง

HashSetEx3.java
package com.marcuscode.hashset;

import java.util.HashSet;
import java.util.Iterator;

public class HashSetEx3 {

    public static void main(String[] args) {

        int[] numbers = { 10, 20, 30, 40, 50, 20, 30, 30 };

        // Add numbers to set to make it unique
        HashSet<Integer> set = new HashSet<Integer>();
        for (int i = 0; i < numbers.length; i++) {
            set.add(numbers[i]);
        }

        // Convert set back to array
        int[] uniqueNumbers = new int[set.size()];
        Iterator<Integer> it = set.iterator();

        int index = 0;
        while (it.hasNext()) {
            int element = it.next();
            uniqueNumbers[index++] = element;
        }

        // Display all unique values
        System.out.println("Unique values in array");
        for (int i = 0; i < uniqueNumbers.length; i++) {
            System.out.print(uniqueNumbers[i] + " ");
        } 
    }

}

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Unique values in array
50 20 40 10 30 

ในตัวอย่างนี้ เป็นโปรแกรมสำหรับลบตัวเลขที่ซ้ำกันออกจากอาเรย์ โดยการแปลงอาเรย์ที่มีอยู่ให้เป็น HashSet จากนั้นแปลงมันกลับมาเป็นอาเรย์เช่นเดิม สุดท้ายเราจะได้อาเรย์ที่เหลือเพียงค่าที่ไม่ซ้ำกันเลย

int[] numbers = { 10, 20, 30, 40, 50, 20, 30, 30 };

ในคำสั่งแรกเป็นการประกาศตัวแปรอาเรย์ numbers สำหรับเก็บตัวเลขจำนวนเต็ม จะเห็นว่าในอาเรย์นั้นประกอบไปด้วยตัวเลขที่ซ้ำกันอยู่ สิ่งที่เราต้องการทำคือทำให้ค่าที่ซ้ำกันเหลือเพียงค่าเดียวเท่านั้น

HashSet<Integer> set = new HashSet<Integer>();

จากนั้นเป็นการสร้างออบเจ็ค HashSet สำหรับเก็บตัวเลขจำนวนเต็ม เนื่องจากค่าที่เราต้องการเก็บนั้นมีประเภทข้อมูลเป็น int ดังนั้นคลาสของประเภทข้อมูลนี้คือ Integer สำหรับใช้กำหนดให้กับ Set

for (int i = 0; i < numbers.length; i++) {
    set.add(numbers[i]);
}

จากนั้นใช้คำสั่ง for loop วนรอบอาเรย์และเพิ่มค่าเข้าไปยัง HashSet และในตอนท้ายเราจะได้ค่าที่ไม่ซ้ากันภายในออบเจ็ค set

int[] uniqueNumbers = new int[set.size()];
Iterator<Integer> it = set.iterator();

int index = 0;
while (it.hasNext()) {
    int element = it.next();
    uniqueNumbers[index++] = element;
}

ต่อมาเป็นการแปลงข้อมูลใน HashSet กลับมาเป็นอาเรย์ของตัวเลข เราได้สร้างอาเรย์ของตัวเลข uniqueNumbers จากขนาดของ HashSet จากนั้นใช้ Iterator เพื่อวนรอบค่าใน Set และเพิ่มเข้าไปยังอาเรย์ใหม่ที่สร้างขึ้นมา

System.out.println("Unique values in array");
for (int i = 0; i < uniqueNumbers.length; i++) {
    System.out.print(uniqueNumbers[i] + " ");
} 

ในตอนท้าย เราจะได้รับค่าที่ไม่ซ้ำกันในอาเรย์ uniqueNumbers และใช้คำสั่ง for loop เพื่อวนแสดงค่าทั้งหมดออกทางหน้าจอ

ในบทนี้ คุณได้เรียนรู้การใช้งาน HashSet สำหรับเก็บข้อมูลที่ไม่ซ้ำกันในภาษา Java เราได้พูดถึงการใช้งานเมธอดของ HashSet สำหรับการเพิ่ม ลบ และตรวจสอบค่า และการวนรอบค่าใน HashSet ด้วย Iterator