Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Sử dụng Multimap để code hiệu quả hơn
Java Collection Framework
Java collection framework
mang đến cho lập trình viên hầu hết các kiểu cấu trúc dữ liệu: List, Set, Map, Stack, Queue
với vô số các implementations để lựa chọn phù hợp với mục đích sử dụng, một số được dùng rất phổ biến là ArrayList, HashMap, HashSet,...
Trên thực tế với những kiểu cấu trúc dữ liệu trên là đủ cho phần lớn các xử lý liên quan tới collection
, nhưng đôi khi lại không được hiệu quả cho lắm.
Ví dụ về phân loại books theo type
Chúng ta có một list các loại book được phân loại theo type, dưới đây là cách thông thường, tạo một HashMap
với key
là book type và value
là các list loại book cùng type.
Class Book
public class Book {
private BookType type;
private String name;
// Constructor, getters
@Override
public String toString() {
return "Book [type=" + type + ", name=" + name + "]";
}
public enum BookType {
PROGRAMING(1), DESIGN(2);
private int code;
private BookType(int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
}
Phân loại books theo type
List<Book> books = Arrays.asList(
new Book(BookType.PROGRAMING, "Procedural Programming"),
new Book(BookType.PROGRAMING, "Object-Oriented Programming"),
new Book(BookType.PROGRAMING, "Functional programming"),
new Book(BookType.DESIGN, "Domain Driven Design"),
new Book(BookType.DESIGN, "Object-Oriented Design"),
new Book(BookType.DESIGN, "Test Driven Design"));
Map<Integer, List<Book>> booksInType = new HashMap<>(2);
for (Book book : books) {
List<Book> bookList = booksInType.get(book.getType().getCode());
if (bookList == null) {
bookList = new ArrayList<>();
booksInType.put(book.getType().getCode(), bookList);
}
bookList.add(book);
}
System.out.println(booksInType.get(BookType.PROGRAMING.getCode()));
System.out.println(booksInType.get(BookType.DESIGN.getCode()));
Kết quả thu được
[Book [type=PROGRAMING, name=Procedural Programming], Book [type=PROGRAMING, name=Object-Oriented Programming], Book [type=PROGRAMING, name=Functional programming]]
[Book [type=DESIGN, name=Domain Driven Design], Book [type=DESIGN, name=Object-Oriented Design], Book [type=DESIGN, name=Test Driven Design]]
Rõ ràng cách làm trên là khá dài dòng và không thực sự hiệu quả, việc khai báo Map<Integer, List<Book>> booksInType = new HashMap<>(2);
trông khá không "gọn mắt" và việc sử dụng thêm if
để kiểm tra và khởi tạo một ArrayList
chứa các loại book cùng type cũng bất tiện.
Sử dụng Google Guava's Multimap
Thật may là có một kiểu cấu trúc dữ liệu phù hợp trong tình huống này hơn là Map
, đó là Multimap
, kiểu cấu trúc dữ liệu mà 1 key
có thể được dùng với nhiều values
.
Thư viện Google Guava
cung cấp một số loại Multimap
mà chúng ta có thể sử dụng để giải quyết một cách ngắn gọn.
Multimap<Integer, Book> booksInType = ArrayListMultimap.create();
for (Book book : books) {
booksInType.put(book.getType().getCode(), book);
}
System.out.println(booksInType.get(BookType.PROGRAMING.getCode()));
System.out.println(booksInType.get(BookType.DESIGN.getCode()));
Và kết quả thu được là giống nhau, nhưng số lượng code ngắn gọn hơn khá nhiều.
Google Guava cũng cung cấp một số kiểu cấu trúc dữ liệu khác như Multiset, BiMap, Table, ... mà chúng ta có thể áp dụng để code trở lên ngắn gọn hơn, dễ đọc hơn.




