Java Generics

4 minute read

VIII. Java Generics:

A. Khái niệm và cú pháp của Generics:

  1. Khái niệm:

    • Generics là một tính năng trong Java cho phép bạn tạo các lớp, phương thức và interface có thể làm việc với bất kỳ kiểu dữ liệu nào.
    • Nó cung cấp một cách để tạo ra các thành phần đa năng, tái sử dụng và an toàn kiểu trong Java.
    • Generics giúp tăng tính linh hoạt, mạnh mẽ và bảo toàn kiểu trong mã của bạn.
  2. Cú pháp:

    • Cú pháp Generics sử dụng các tham số kiểu (type parameters) được đặt trong dấu ngoặc nhọn <T> sau tên lớp, phương thức hoặc interface.
    • Tham số kiểu có thể được sử dụng trong khai báo và triển khai để chỉ ra kiểu dữ liệu chính xác mà các thành phần của lớp, phương thức hoặc interface sẽ làm việc với.
    • Ví dụ cú pháp:
      1
      2
      3
      4
      5
      6
      7
      
      public class MyClass<T> {
          // Code của lớp
      }
      
      public <T> void myMethod(T param) {
          // Code của phương thức
      }
      
  3. Ví dụ sử dụng Generics:

    • Tạo một lớp hoạt động với mọi kiểu dữ liệu:
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      public class Box<T> {
          private T data;
      
          public void setData(T data) {
              this.data = data;
          }
      
          public T getData() {
              return data;
          }
      }
      
    • Sử dụng lớp Box với các kiểu dữ liệu khác nhau:
      1
      2
      3
      4
      5
      6
      7
      
      Box<Integer> intBox = new Box<>();
      intBox.setData(10);
      int data = intBox.getData(); // Không cần ép kiểu
      
      Box<String> strBox = new Box<>();
      strBox.setData("Hello");
      String str = strBox.getData(); // Không cần ép kiểu
      

Generics là một tính năng quan trọng trong Java, giúp tạo ra mã linh hoạt và tái sử dụng. Bằng cách sử dụng Generics, bạn có thể viết mã một cách an toàn hơn và dễ dàng tái sử dụng trong nhiều tình huống khác nhau.

B. Sử dụng Generics với Collections:

Generics được sử dụng rộng rãi trong Java Collections Framework để tạo ra các tập hợp dữ liệu mà có thể làm việc với mọi kiểu dữ liệu. Dưới đây là cách sử dụng Generics với các cấu trúc dữ liệu trong Java Collections:

  1. ArrayList với Generics:

    1
    2
    3
    
    ArrayList<String> stringList = new ArrayList<>();
    stringList.add("Hello");
    stringList.add("World");
    
  2. HashMap với Generics:

    1
    2
    3
    
    HashMap<Integer, String> map = new HashMap<>();
    map.put(1, "One");
    map.put(2, "Two");
    
  3. HashSet với Generics:

    1
    2
    3
    
    HashSet<Double> set = new HashSet<>();
    set.add(3.14);
    set.add(2.718);
    
  4. LinkedList với Generics:

    1
    2
    3
    
    LinkedList<Character> charList = new LinkedList<>();
    charList.add('a');
    charList.add('b');
    
  5. Queue với Generics:

    1
    2
    3
    
    Queue<Integer> queue = new LinkedList<>();
    queue.add(1);
    queue.add(2);
    
  6. PriorityQueue với Generics:

    1
    2
    3
    
    PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
    priorityQueue.add(3);
    priorityQueue.add(1);
    
  7. Stack với Generics:

    1
    2
    3
    
    Stack<String> stack = new Stack<>();
    stack.push("First");
    stack.push("Second");
    

Generics giúp làm cho mã của bạn an toàn hơn và dễ dàng hiểu hơn bằng cách cho phép bạn chỉ định kiểu dữ liệu mà một cấu trúc dữ liệu hoặc phương thức có thể làm việc với. Điều này giúp tránh được lỗi phát sinh từ việc sử dụng kiểu dữ liệu không chính xác và làm cho mã trở nên linh hoạt hơn để sử dụng lại trong các tình huống khác nhau.

C. Generics trong lập trình hướng đối tượng:

Generics trong lập trình hướng đối tượng cho phép bạn tạo ra các lớp, phương thức và interface có thể làm việc với mọi kiểu dữ liệu. Dưới đây là cách Generics được sử dụng trong lập trình hướng đối tượng:

  1. Lớp Generic: Bạn có thể tạo ra các lớp Generic bằng cách sử dụng tham số kiểu.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    public class Box<T> {
        private T data;
    
        public void setData(T data) {
            this.data = data;
        }
    
        public T getData() {
            return data;
        }
    }
    

    Lớp Box ở trên có thể lưu trữ và trả về bất kỳ loại dữ liệu nào mà bạn chỉ định khi tạo đối tượng Box.

  2. Phương thức Generic: Bạn cũng có thể tạo ra các phương thức Generic.

    1
    2
    3
    4
    5
    6
    
    public <T> void printArray(T[] array) {
        for (T item : array) {
            System.out.print(item + " ");
        }
        System.out.println();
    }
    

    Phương thức printArray ở trên có thể in một mảng bất kỳ kiểu dữ liệu nào.

  3. Interface Generic: Tương tự, bạn cũng có thể tạo ra các interface Generic.

    1
    2
    3
    4
    
    public interface Pair<K, V> {
        K getKey();
        V getValue();
    }
    

    Interface Pair ở trên định nghĩa một cặp key-value, trong đó key có kiểu K và value có kiểu V.

  4. Sử dụng Generics trong các cấu trúc dữ liệu: Generics thường được sử dụng trong các cấu trúc dữ liệu như ArrayList, HashMap, LinkedList, v.v.

    1
    2
    
    ArrayList<String> list = new ArrayList<>();
    HashMap<Integer, String> map = new HashMap<>();
    

Generics trong lập trình hướng đối tượng giúp tạo ra mã tái sử dụng và linh hoạt hơn bằng cách cho phép bạn làm việc với nhiều kiểu dữ liệu khác nhau trong cùng một lớp, phương thức hoặc interface. Điều này làm cho mã của bạn trở nên dễ đọc, hiểu và bảo trì hơn.