Iterator Pattern trong Java

0 0 0

Người đăng: Ông Huy Thắng

Theo Viblo Asia

Design Pattern Iterator là một trong những mẫu thiết kế thuộc nhóm Behavioral Patterns trong Java. Mục đích chính của nó là cung cấp một cách để truy cập tuần tự các phần tử trong một tập hợp (collection) mà không để lộ ra cấu trúc bên trong của tập hợp đó.

Iterator Pattern là gì?

Iterator pattern cung cấp một giao diện chuẩn để duyệt qua các phần tử của một tập hợp (collection), như List, Set, Map,... mà không cần biết cấu trúc cụ thể của chúng.

Cấu trúc cơ bản:

  • Iterator: Interface định nghĩa các phương thức như hasNext(), next().
  • ConcreteIterator: Cài đặt cụ thể của Iterator.
  • Aggregate (Collection): Interface chứa phương thức để tạo Iterator.
  • ConcreteAggregate: Tập hợp cụ thể triển khai Aggregate.

Coi như chưa biết các tích hợp sẵn trong java và xây dựng lại từ đầu

// Tạo giao diện Iterator
public interface MyIterator<T> { boolean hasNext(); T next();
} // Tạo giao diện Iterable (tập hợp)
public interface MyIterable<T> { MyIterator<T> iterator();
}

Thiết lập danh sách học sih

import java.util.List; public class StudentCollection implements MyIterable<String> { private List<String> students; public StudentCollection(List<String> students) { this.students = students; } @Override public MyIterator<String> iterator() { return new StudentIterator(); } private class StudentIterator implements MyIterator<String> { private int index = 0; @Override public boolean hasNext() { return index < students.size(); } @Override public String next() { return students.get(index++); } }
}

Sử dụng Iterator

import java.util.Arrays; public class Main { public static void main(String[] args) { StudentCollection students = new StudentCollection( Arrays.asList("Alice", "Bob", "Charlie") ); MyIterator<String> iterator = students.iterator(); while (iterator.hasNext()) { String student = iterator.next(); System.out.println(student); } }
} // Kết quả:
Alice
Bob
Charlie

Trong Java, java.util.Iterator chính là sự hiện thực của pattern này.

List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie"); Iterator<String> iterator = names.iterator(); while (iterator.hasNext()) { String name = iterator.next(); System.out.println(name);
}

Ở đây, ta không cần quan tâm đến cách danh sách được lưu trữ nội bộ (mảng, cây, ...), chỉ cần biết cách lấy phần tử tiếp theo.

Áp dụng thực tế trong Spring Boot

Trong Spring Boot, Iterator pattern được áp dụng rất nhiều — bạn có thể không nhận ra vì nó được ẩn sau các abstraction như Iterable, Stream, Page,...

1. Iterable trong Repository

Các interface như CrudRepository hoặc JpaRepository của Spring Data kế thừa từ Iterable< T >:

public interface UserRepository extends CrudRepository<User, Long> {} @Autowired
private UserRepository userRepository; public void printAllUsers() { for (User user : userRepository.findAll()) { System.out.println(user.getName()); }
}

findAll() trả về Iterable< T > → bạn có thể dùng for-each hoặc Iterator.

2. Pagination trong Spring Data

Page<User> page = userRepository.findAll(PageRequest.of(0, 10));
for (User user : page) { // Iterator được dùng ngầm System.out.println(user.getEmail());
}

Ở đây Page implement Iterable, nên bạn có thể dùng vòng lặp for-each, hoặc .iterator().

3. Custom Iterable Class

Bạn cũng có thể định nghĩa class của riêng mình để implement Iterable< T >:

public class CustomUserList implements Iterable<User> { private List<User> users; public CustomUserList(List<User> users) { this.users = users; } @Override public Iterator<User> iterator() { return users.iterator(); }
} // Sử dụng:
CustomUserList customUsers = new CustomUserList(userList);
for (User user : customUsers) { // xử lý user
}

Thật ra viết bài này đối với Java mình thấy cũng hơi thừa vì giờ có các lib sẵn rồi, thực chất pattern này cũng chỉ là duyệt tuần tự các phần tử của 1 mảng nào đó.

Stream API

Các bạn có thể tìm hiểu thêm trong Java 8+ trở lên sử dụng trong Stream API nhé (Cách hiện đại thay cho Iterator)

list.stream() .filter(x -> x.startsWith("A")) .map(String::toUpperCase) .forEach(System.out::println);

Đây là cách hiện đại và declarative để duyệt, lọc, xử lý dữ liệu — thay thế hoàn toàn cho Iterator trong phần lớn use case.

Spliterator (Java 8)

Là sự nâng cấp của Iterator hỗ trợ duyệt song song (parallel) tốt hơn.

Dùng trong Stream.parallelStream().

Spliterator<String> split = list.spliterator();
split.forEachRemaining(System.out::println);

ListIterator (Iterator hai chiều cho List)

Cho phép duyệt tiến & lùi trong List.

ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) { System.out.println(lit.next());
}
while (lit.hasPrevious()) { System.out.println(lit.previous());
}

Map và Iterator

Map không trực tiếp implement Iterator, nhưng bạn có thể lặp qua entry set:

Map<String, String> map = new HashMap<>();
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println(entry.getKey() + " = " + entry.getValue());
}

Giờ dùng cái nào là hiện đại nhất?

Dùng Stream API (Java 8+) trong hầu hết các trường hợp!

Ví dụ thay vì:

// Cách viết: Imperative (chỉ định cách làm)
for (String item : list) { if (item.startsWith("A")) { System.out.println(item); }
}

Hãy viết:

// Cách viết: Declarative (chỉ định mục tiêu)
list.stream() .filter(s -> s.startsWith("A")) .forEach(System.out::println);

Bình luận

Bài viết tương tự

- vừa được xem lúc

Iterator Design Pattern - Trợ thủ đắc lực của Developers

1. Giới thiệu. . Iterator hay còn gọi là Cursor là một mẫu thiết kế thuộc nhóm hành vi (Behavioral Pattern).

0 0 34

- vừa được xem lúc

[Design Patterns] Iterator Pattern

Iterator là pattern được sử dụng rất phổ biến trong môi trường lập trình Java và .NET.

0 0 30

- vừa được xem lúc

Design Patterns - Iterator

Iterator. Mục đích.

0 0 24

- vừa được xem lúc

Fine-grain refactoring deep dive (5) - Implement constants.

1. Issue.

0 0 26

Strategy Pattern trong Java

Định nghĩa. Strategy Pattern là một trong những behavioral design pattern.

0 0 0

- vừa được xem lúc

Hướng dẫn finetune mô hình LLM đơn giản và miễn phí với Unsloth

Chào mừng các bạn đến với bài viết hướng dẫn chi tiết cách finetune (tinh chỉnh) một mô hình ngôn ngữ lớn (LLM) một cách đơn giản và hoàn toàn miễn phí sử dụng thư viện Unsloth. Trong bài viết này, ch

0 0 3