hocvietcode.com
  • Trang chủ
  • Học lập trình
    • Lập trình C/C++
    • Lập trình HTML
    • Lập trình Javascript
      • Javascript cơ bản
      • ReactJS framework
      • AngularJS framework
      • Typescript cơ bản
      • Angular
    • Lập trình Mobile
      • Lập Trình Dart Cơ Bản
        • Dart Flutter Framework
    • Cơ sở dữ liệu
      • MySQL – MariaDB
      • Micrsoft SQL Server
      • Extensible Markup Language (XML)
      • JSON
    • Lập trình PHP
      • Lập trình PHP cơ bản
      • Laravel Framework
    • Lập trình Java
      • Java Cơ bản
    • Cấu trúc dữ liệu và giải thuật
    • Lập Trình C# Cơ Bản
    • Machine Learning
  • WORDPRESS
    • WordPress cơ bản
    • WordPress nâng cao
    • Chia sẻ WordPress
  • Kiến thức hệ thống
    • Microsoft Azure
    • Docker
    • Linux
  • Chia sẻ IT
    • Tin học văn phòng
      • Microsoft Word
      • Microsoft Excel
    • Marketing
      • Google Adwords
      • Facebook Ads
      • Kiến thức khác
    • Chia sẻ phần mềm
    • Review công nghệ
    • Công cụ – tiện ích
      • Kiểm tra bàn phím online
      • Kiểm tra webcam online
Đăng nhập
  • Đăng nhập / Đăng ký

Please enter key search to display results.

Home
  • Cấu trúc dữ liệu và giải thuật
  • Java Cơ bản
Cấu trúc dữ liệu Java

Cấu trúc dữ liệu Java

  • 20-12-2023
  • Toanngo92
  • 0 Comments

Khái niệm: Cấu trúc dữ liệu là cách tổ chức và lưu trữ dữ liệu để hiệu quả trong việc truy cập và sửa đổi. Việc sử dụng cấu trúc dữ liệu ảnh hưởng trực tiếp hiệu suất và hiệu quả của thuật toán.

Các Cấu trúc Dữ liệu Quan trọng:

  • Mảng (Array)
  • Danh sách Liên kết (LinkedList)
  • Ngăn xếp (Stacks)
  • Hàng đợi (Queues)
  • Cây (Tree)
  • Đồ thị (Graphs)
  • Bảng Băm (Hash Tables)

Mục lục

  • Mảng tĩnh (Arrays)
  • Mảng Động (Dynamic Arrays)
  • Danh sách liên kết
    • Mảng so với LinkedList:
    • ArrayList so với LinkedList:
  • Giới thiệu về cấu trúc dữ liệu dạng cây (Tree)
  • Cấu trúc dữ liệu dạng bản đồ (Map)
    • So sánh giữa HashMap và Hashtable:
  • Cấu trúc dữ liệu Stack (ngăn xếp)
  • Cấu trúc dữ liệu Queue (hàng đợi)
    • Khái Niệm Máy Chủ Hàng Đợi (Queue Server)
      • Các Trường Hợp Sử Dụng Thông Dụng:
      • Ưu Điểm:
      • Ví Dụ:
  • Giao diện Enumeration
  • Lớp BitSet
  • Lớp Stack
  • Lớp Từ Điển (Dictionary)
    • Lớp Hashtable
    • Lớp Properties

Mảng tĩnh (Arrays)

Định nghĩa: Mảng là một tập hợp các phần tử được xác định bởi chỉ mục hoặc khóa.

Đặc tính: Kích thước cố định (nghĩa là bạn không thể dễ dàng thay đổi số lượng phần tử sau khi mảng đã được tạo).

Các loại Mảng:

  • Mảng một chiều: Tương tự như danh sách đơn giản, ví dụ: int[] array = new int[10];.
  • Mảng đa chiều: Cấu trúc phức tạp hơn, ví dụ: int[,] arr = new int[10][10];.

Lợi ích:

  • Truy cập nhanh qua chỉ mục.
  • Cấu trúc đơn giản và triển khai dễ dàng.

Nhược điểm:

  • Kích thước cố định hạn chế tính linh hoạt.
  • Thao tác thay đổi kích thước có thể tốn kém.

Mảng Động (Dynamic Arrays)

Định nghĩa: Mảng động là mảng có thể tự điều chỉnh kích thước khi cần thêm không gian.

Cơ chế: Bắt đầu với kích thước cố định. Khi vượt quá dung lượng, tạo một mảng mới với kích thước gấp đôi và sao chép các phần tử.

Ưu điểm: Kích thước linh hoạt và tự động điều chỉnh kích thước.

Nhược điểm: Việc điều chỉnh kích thước có thể tốn kém.

Triển khai thông dụng: Trong Java, chúng ta sử dụng ArrayList là kiểu dữ liệu cho loại mảng này.

ArrayList<Integer> mangDong = new ArrayList<>();
mangDong.them(1);
mangDong.them(2);
System.out.println(mangDong.kichThuoc()); // Kết quả: 2

Danh sách liên kết

Định nghĩa: Danh sách liên kết là một cấu trúc dữ liệu tuyến tính, trong đó các phần tử được lưu trữ trong các nút, và mỗi nút chỉ đến nút tiếp theo.

Các loại danh sách liên kết:

  • Danh sách liên kết đơn
  • Danh sách liên kết kép
  • Danh sách liên kết vòng

Tính chất của danh sách liên kết:

  • Kích thước động (có thể thay đổi)
  • Thao tác chèn/xóa hiệu quả

Ví dụ:

Tạo tệp Node.java

package linkedlistexam;

public class Node {
    public int data;
    public Node next;

    public Node (int data){
        this.data = data;
        this.next = null;
    }
}

Tạo tệp LinkedList.java

package linkedlistexam;

public class LinkedList {
    private Node head;
    public void insert(int data){
        Node newNode = new Node(data);
        if(head == null){
            head = newNode;
        } else {
            Node temp = head;
            while(temp.next != null){
                temp = temp.next;
            }
            temp.next = newNode;
        }
    }

    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();
        Node temp = head;
        while(temp != null){
            sb.append(temp.data).append(" ");
            temp = temp.next;
        }
        return sb.toString();
    }
}

Tạo tệp Main.java để test:

package linkedlistexam;

public class Main {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        list.insert(5);
        list.insert(10);
        list.insert(15);
        list.insert(20);
        System.out.println("Linked List:");
        System.out.println(list);
    }
}

Mảng so với LinkedList:

So sánh: Mảng có kích thước cố định, trong khi LinkedList có thể tăng động.
Truy cập hiệu quả so với Chèn/Xóa hiệu quả: Mảng cung cấp quyền truy cập hiệu quả (thời gian không đổi), nhưng LinkedList vượt trội về chèn và xóa (thời gian không đổi để thêm/xóa phần tử).

ArrayList so với LinkedList:

So sánh: ArrayList sử dụng mảng động bên trong, trong khi LinkedList dựa trên các nút (node).
Thời gian truy cập tốt hơn so với Chèn/Xóa tốt hơn: ArrayList cung cấp thời gian truy cập tốt hơn (do bộ nhớ liền kề), trong khi LinkedList hoạt động tốt hơn cho việc chèn và xóa (không cần dịch chuyển phần tử)

Giới thiệu về cấu trúc dữ liệu dạng cây (Tree)

Định nghĩa: Cấu trúc dữ liệu phân cấp bao gồm các nút được kết nối bởi các cạnh.

Tính chất:

  • Một nút gốc ở cấp độ cao nhất.
  • Một nút lá được kết nối bằng các cạnh từ các nút cha.
  • Các nút con không có con.

Các loại cây:

  • Cây nhị phân (Binary Tree): Mỗi nút có tối đa hai con.
  • Cây nhị phân tìm kiếm: Cây phân tầng nhị phân với các node được sắp xếp (phần tử con trái < phần tử con phải).
  • Cây tổng quát: Nút có thể có bất kỳ số lượng con nào.

Trường hợp sử dụng:

  • Biểu diễn dữ liệu phân cấp (ví dụ: hệ thống tệp, biểu đồ tổ chức).
  • Các ứng dụng tìm kiếm và sắp xếp (ví dụ: Cây tìm kiếm nhị phân).

Ví dụ cấu trúc dữ liệu dạng cây:

Ví dụ 1: Menu đa cấp (ví dụ: điều hướng website)
Cấp gốc: Trang chủ
Các mục con: Giới thiệu, Dịch vụ, Liên hệ
Các mục con tiếp theo dưới Dịch vụ: Phát triển web, Ứng dụng di động

Ví dụ 2: Mô hình Quận/Huyện
Cấp gốc: Quốc gia
Các mục con: Tỉnh/Thành phố
Các mục con tiếp theo dưới Tỉnh/Thành phố: Thành phố, Quận/Huyện

Ví dụ 3: Sơ đồ tổ chức
Cấp gốc: Giám đốc điều hành (CEO)
Các mục con: Trưởng các phòng ban (Nhân sự, Tài chính, Tiếp thị)
Các mục con tiếp theo dưới các phòng ban: Trưởng nhóm, Nhân viên

import java.util.ArrayList;
import java.util.List;

class TreeNode {
    String data;
    List<TreeNode> children;

    TreeNode(String data) {
        this.data = data;
        this.children = new ArrayList<>();
    }

    void addChild(TreeNode child) {
        children.add(child);
    }
}

public class TreeExample {
    public static void main(String[] args) {
        // Sample tree creation:
        TreeNode root = new TreeNode("CEO");
        TreeNode hrHead = new TreeNode("HR Head");
        root.addChild(hrHead);

        TreeNode financeHead = new TreeNode("Finance Head");
        root.addChild(financeHead);
    }
}

Cấu trúc dữ liệu dạng bản đồ (Map)

Định nghĩa: Một tập hợp các cặp khóa-giá trị, trong đó mỗi khóa ánh xạ đến một giá trị cụ thể.

Các triển khai phổ biến:

  • Hashtable: Bản đồ đồng bộ cho các cặp khóa-giá trị, không cho phép khóa hoặc giá trị null.
  • HashMap: Phiên bản linh hoạt hơn, không đồng bộ, cho phép một khóa null và nhiều giá trị null.

Thuộc tính:

  • Tìm kiếm và truy xuất theo khóa hiệu quả.
  • Mỗi khóa là duy nhất, nhưng giá trị có thể trùng lặp.

Các trường hợp sử dụng:

  • Tra cứu dữ liệu nhanh (ví dụ: lưu trữ thông tin người dùng theo ID).
  • Lưu trữ cấu hình (ví dụ: thiết lập ứng dụng).

Ví dụ HashMap:

import java.util.HashMap;

public class HashMapExample {
    public static void main(String[] args) {
        // Tạo một HashMap
        HashMap<Integer, String> userMap = new HashMap<>();

        // Thêm các cặp khóa-giá trị vào HashMap
        userMap.put(1, "Alice");
        userMap.put(2, "Bob");
        userMap.put(3, "Charlie");
        
        // Cho phép khóa hoặc giá trị null
        userMap.put(null, "NullKeyUser");
        userMap.put(4, null);

        // Lấy và hiển thị các giá trị từ HashMap
        System.out.println("User with ID 1: " + userMap.get(1));
        System.out.println("User with null key: " + userMap.get(null));
        
        // Duyệt qua các cặp khóa-giá trị
        for (Integer key : userMap.keySet()) {
            System.out.println("Key: " + key + ", Value: " + userMap.get(key));
        }
    }
}

Ví dụ Hashtable:

import java.util.Hashtable;

public class HashtableExample {
    public static void main(String[] args) {
        // Tạo một Hashtable
        Hashtable<Integer, String> configMap = new Hashtable<>();

        // Thêm các cặp khóa-giá trị vào Hashtable
        configMap.put(1, "DatabaseURL");
        configMap.put(2, "APIKey");
        configMap.put(3, "Timeout");

        // Không cho phép khóa hoặc giá trị null (sẽ gây ra lỗi nếu cố gắng sử dụng null)
        // configMap.put(null, "NullKeyUser"); // Lỗi: NullPointerException
        // configMap.put(4, null); // Lỗi: NullPointerException

        // Lấy và hiển thị các giá trị từ Hashtable
        System.out.println("Config 1: " + configMap.get(1));
        System.out.println("Config 2: " + configMap.get(2));
        
        // Duyệt qua các cặp khóa-giá trị
        for (Integer key : configMap.keySet()) {
            System.out.println("Key: " + key + ", Value: " + configMap.get(key));
        }
    }
}

So sánh giữa HashMap và Hashtable:

  • HashMap:
    • Cho phép một khóa null và nhiều giá trị null.
    • Không đồng bộ, nhanh hơn khi không yêu cầu sự an toàn luồng (thread safety).
  • Hashtable:
    • Không cho phép khóa hoặc giá trị null.
    • Đồng bộ, an toàn cho các ứng dụng đa luồng nhưng có hiệu suất thấp hơn so với HashMap.

Cấu trúc dữ liệu Stack (ngăn xếp)

Định nghĩa: Một cấu trúc dữ liệu tuyến tính tuân theo nguyên tắc Vào Sau, Ra Trước (LIFO – Last In, First Out).

Các thao tác:

  • push: Thêm một phần tử vào đỉnh của ngăn xếp.
  • pop: Xóa và trả về phần tử ở đỉnh ngăn xếp.
  • peek: Xem phần tử ở đỉnh mà không xóa nó.

Trường hợp sử dụng:

  • Hoàn tác các thao tác trong trình soạn thảo văn bản.
  • Đánh giá các biểu thức số học.
  • Đảo ngược dữ liệu (ví dụ: chuỗi).

Ví dụ:

import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        // Tạo một Stack
        Stack<String> stack = new Stack<>();

        // Thêm các phần tử vào Stack (push)
        stack.push("A");
        stack.push("B");
        stack.push("C");
        
        // Xem phần tử trên cùng của Stack mà không xóa (peek)
        System.out.println("Phần tử trên cùng: " + stack.peek());
        
        // Loại bỏ và trả về phần tử trên cùng (pop)
        System.out.println("Phần tử vừa loại bỏ: " + stack.pop());
        
        // Hiển thị phần tử trên cùng sau khi pop
        System.out.println("Phần tử trên cùng sau pop: " + stack.peek());

        // Duyệt qua các phần tử trong Stack
        System.out.println("Các phần tử còn lại trong stack:");
        for (String element : stack) {
            System.out.println(element);
        }
    }
}

Cấu trúc dữ liệu Queue (hàng đợi)

Định nghĩa: Một cấu trúc dữ liệu tuyến tính tuân theo nguyên tắc Vào Trước, Ra Trước (FIFO – First In, First Out).

Các thao tác:

  • enqueue: Thêm một phần tử vào cuối hàng đợi.
  • dequeue: Xóa và trả về phần tử ở đầu hàng đợi.
  • peek: Xem phần tử ở đầu mà không xóa nó.

Trường hợp sử dụng:

  • Hệ thống xử lý đơn hàng.
  • Xử lý dữ liệu song song.
  • Quản lý các tác vụ trong hàng đợi (ví dụ: công việc in ấn).

Ví dụ:

import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {
    public static void main(String[] args) {
        // Tạo một Queue
        Queue<String> queue = new LinkedList<>();

        // Thêm các phần tử vào Queue (enqueue)
        queue.add("A");
        queue.add("B");
        queue.add("C");

        // Xem phần tử ở đầu hàng đợi mà không xóa (peek)
        System.out.println("Phần tử đầu tiên: " + queue.peek());

        // Loại bỏ và trả về phần tử ở đầu hàng đợi (dequeue)
        System.out.println("Phần tử vừa loại bỏ: " + queue.poll());

        // Hiển thị phần tử ở đầu hàng đợi sau khi dequeue
        System.out.println("Phần tử đầu tiên sau khi loại bỏ: " + queue.peek());

        // Duyệt qua các phần tử còn lại trong Queue
        System.out.println("Các phần tử còn lại trong queue:");
        for (String element : queue) {
            System.out.println(element);
        }
    }
}

Khái Niệm Máy Chủ Hàng Đợi (Queue Server)

Khái niệm: Một hệ thống xử lý các nhiệm vụ theo hàng đợi, thực hiện từng nhiệm vụ một.

Các Trường Hợp Sử Dụng Thông Dụng:

  • Hàng Đợi Tin Nhắn (Messaging Queues): Được sử dụng trong các hệ thống như RabbitMQ, Apache Kafka để xử lý nhiệm vụ không đồng bộ.
  • Máy Chủ In (Print Servers): Quản lý nhiều tác vụ in trong hàng đợi.

Ưu Điểm:

  • Tách biệt các nhà sản xuất nhiệm vụ khỏi các người tiêu thụ nhiệm vụ, cải thiện khả năng mở rộng của hệ thống.
  • Cho phép xử lý các nhiệm vụ theo thứ tự chúng đến.

Ví Dụ:

Hệ thống dịch vụ khách hàng nơi các yêu cầu được xử lý theo hàng đợi.

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ứcMô 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

Bài tập

  • Task 1: Write a function to convert a list of arrays (e.g., categories and subcategories) into a tree structure.
  • Task 2: Implement a function to traverse the tree and print it
  • Task 3: Implement a simple contact list where names (keys) are stored with phone numbers (values) in a HashMap.
  • Task 4: Write functions to add, remove, and search for contacts by name.
  • Task 5: Extend the implementation to allow duplicate phone numbers with different names.
  • Bonus Task: Sort the HashMap entries by key (name) and display the sorted contacts list

Bài tập queue/stack:

Task 1: Reversing a String with Stack

Description:

Write a function that uses a stack to reverse a given string.

  • Sample Input: "hello"
  • Expected Output: "olleh"

Task 2: Implementing a Queue for Task Management

Description:

  • Implement a queue to simulate a task management system where tasks arrive and are processed in FIFO order.
  • Write functions to enqueue new tasks, dequeue and process tasks, and view the current task at the front.

Task 3 (Optional): Queue for Parallel Data Processing

Description:

  • Simulate a server that receives and processes requests in a queue. Implement multithreading to handle multiple tasks in parallel.
  • Bonus: Introduce task priorities (PriorityQueue) to handle high-priority tasks first.

Bài viết liên quan:

Cấu trúc dữ liệu danh sách liên kết (LinkedList)
Cấu trúc dữ liệu Mảng (Array)
Giới thiệu về thuật toán
Định lý thợ (Master Theorem)
Giải thuật Qui hoạch động (Dynamic Programming) 
Giải thuật chia để trị (Divide and Conquer)
Phân tích tiệm cận trong CTDL và giải thuật
Giải thuật tham lam (Greedy Algorithm)
Đệ quy trong lập trình
Thuật toán tìm kiếm nhảy – Jump Search
Thuật toán tìm kiếm nhị phân – binary search
Thuật toán tìm kiếm tuần tự – linear search

THÊM BÌNH LUẬN Cancel reply

Dịch vụ thiết kế Wesbite

NỘI DUNG MỚI CẬP NHẬT

2. PHÂN TÍCH VÀ ĐẶC TẢ HỆ THỐNG

1. TỔNG QUAN KIẾN THỨC THỰC HÀNH TRIỂN KHAI DỰ ÁN CÔNG NGHỆ THÔNG TIN

Hướng dẫn tự cài đặt n8n comunity trên CyberPanel, trỏ tên miền

Mẫu prompt tạo mô tả chi tiết bối cảnh

Một số cải tiến trong ASP.NET Core, Razor Page, Model Binding, Gabbage collection

Giới thiệu

hocvietcode.com là website chia sẻ và cập nhật tin tức công nghệ, chia sẻ kiến thức, kỹ năng. Chúng tôi rất cảm ơn và mong muốn nhận được nhiều phản hồi để có thể phục vụ quý bạn đọc tốt hơn !

Liên hệ quảng cáo: [email protected]

Kết nối với HỌC VIẾT CODE

© hocvietcode.com - Tech888 Co .Ltd since 2019

Đăng nhập

Trở thành một phần của cộng đồng của chúng tôi!
Registration complete. Please check your email.
Đăng nhập bằng google
Đăng kýBạn quên mật khẩu?

Create an account

Welcome! Register for an account
The user name or email address is not correct.
Registration confirmation will be emailed to you.
Log in Lost your password?

Reset password

Recover your password
Password reset email has been sent.
The email could not be sent. Possible reason: your host may have disabled the mail function.
A password will be e-mailed to you.
Log in Register
×