238 câu hỏi về Java Collection Framework cơ bản
Phần 1: Tổng quan về Java Collection Framework (20 câu)
1. Java Collection là gì?
Trả lời: Là một framework cung cấp các cấu trúc dữ liệu và thuật toán để lưu trữ và xử lý dữ liệu một cách hiệu quả.
2. Những thành phần chính trong Collection Framework là gì?
Trả lời: Các giao diện chính như List
, Set
, Queue
, Map
, và các lớp như ArrayList
, HashSet
, HashMap
, v.v.
3. Sự khác biệt giữa Collection và Collections?
Trả lời: Collection
là một giao diện trong framework, còn Collections
là một lớp tiện ích chứa các phương thức hỗ trợ như sắp xếp, tìm kiếm.
4. Điểm khác biệt giữa List, Set, và Map là gì?
Trả lời:
List
: Cho phép phần tử trùng lặp, có thứ tự.Set
: Không cho phép phần tử trùng lặp, không đảm bảo thứ tự.Map
: Lưu trữ dữ liệu dưới dạng cặp key-value.
5. Giao diện nào là gốc của Collection Framework?
Trả lời: Giao diện Collection
là gốc, trừ Map
(nó không kế thừa Collection
).
6. Iterator là gì?
Trả lời: Là một interface để duyệt qua các phần tử của Collection theo tuần tự.
7. Tại sao nên sử dụng Collection Framework thay vì mảng?
Trả lời: Framework linh hoạt hơn, hỗ trợ các cấu trúc dữ liệu nâng cao, quản lý bộ nhớ hiệu quả, và có các thuật toán tích hợp.
8. Giao diện nào hỗ trợ duyệt ngược và sửa đổi khi duyệt?
Trả lời: ListIterator
.
9. Sự khác biệt giữa Iterator
và ListIterator
?
Trả lời:
Iterator
: Duyệt một chiều.ListIterator
: Duyệt hai chiều, hỗ trợ thêm/xóa phần tử.
10. Collection có thể chứa các phần tử null không?
Trả lời:
List
vàSet
: Có thể chứa null.Map
: Chỉ một key null và nhiều value null.
11. Comparable
và Comparator
là gì?
Trả lời:
Comparable
: Dùng để so sánh thứ tự tự nhiên.Comparator
: Tùy chỉnh so sánh, sử dụng bên ngoài lớp.
12. Tại sao Collection Framework sử dụng Generics?
Trả lời: Để đảm bảo an toàn kiểu dữ liệu tại thời điểm biên dịch, tránh lỗi ClassCastException
.
13. Các lớp Collection có đồng bộ hóa không?
Trả lời: Không, hầu hết các lớp như ArrayList
, HashMap
không đồng bộ hóa. Sử dụng Collections.synchronizedList
để làm đồng bộ.
14. Sự khác biệt giữa fail-fast
và fail-safe
trong Iterator?
Trả lời:
Fail-fast
: Ném ngoại lệ khi Collection bị sửa đổi.Fail-safe
: Không ném ngoại lệ, hoạt động trên bản sao.
15. hashCode()
và equals()
có vai trò gì trong Collection?
Trả lời:
hashCode()
: Xác định vị trí phần tử trong các cấu trúc dữ liệu nhưHashMap
,HashSet
.equals()
: Kiểm tra sự bằng nhau giữa các phần tử.
16. Độ phức tạp của thao tác tìm kiếm trong HashMap là gì?
Trả lời: O(1) trong trường hợp tối ưu.
17. Giao diện Iterable
có chức năng gì?
Trả lời: Cung cấp khả năng duyệt qua các phần tử bằng for-each
.
18. Tại sao Map không kế thừa Collection?
Trả lời: Vì Map hoạt động trên các cặp key-value, không giống cấu trúc dữ liệu Collection thông thường.
19. Các loại Collection không đồng bộ là gì?
Trả lời: ArrayList
, HashMap
, HashSet
.
20. Phân biệt remove()
và clear()
?
Trả lời:
remove()
: Xóa một phần tử cụ thể.clear()
: Xóa toàn bộ Collection.
Phần 2: List Interface và các Implementations (40 câu)
21. List Interface là gì?
Trả lời: List
là một giao diện trong Java Collection Framework, lưu trữ các phần tử theo thứ tự và cho phép trùng lặp.
22. ArrayList hoạt động như thế nào nội bộ?
Trả lời: Dựa trên một mảng động, kích thước mảng tăng gấp 1.5 lần khi đầy.
23. Sự khác biệt giữa ArrayList và LinkedList là gì?
Trả lời:
ArrayList
: Tìm kiếm nhanh hơn, nhưng thêm/xóa chậm khi thay đổi kích thước.LinkedList
: Thêm/xóa nhanh hơn, nhưng tìm kiếm chậm hơn.
24. Khi nào nên sử dụng ArrayList thay vì LinkedList?
Trả lời: Khi cần truy cập ngẫu nhiên nhanh và số lần thêm/xóa ít.
25. Vector là gì?
Trả lời: Là một lớp đồng bộ hóa (synchronized) trong Java, tương tự như ArrayList nhưng chậm hơn.
26. Sự khác biệt giữa Vector và ArrayList?
Trả lời:
Vector
đồng bộ hóa, cònArrayList
không.Vector
tăng kích thước gấp đôi khi đầy,ArrayList
tăng 1.5 lần.
27. Tại sao Vector không được khuyến khích sử dụng?
Trả lời: Vì hiệu suất kém hơn ArrayList
và không cần đồng bộ hóa trong hầu hết các trường hợp.
28. LinkedList có hỗ trợ làm Stack không?
Trả lời: Có, vì LinkedList
thực hiện cả giao diện Deque
.
29. Sự khác biệt giữa add()
và set()
trong List?
Trả lời:
add()
: Thêm phần tử vào danh sách.set()
: Thay thế phần tử tại một vị trí cụ thể.
30. ListIterator là gì?
Trả lời: Là một Iterator nâng cao, hỗ trợ duyệt hai chiều và chỉnh sửa danh sách.
31. ListIterator hỗ trợ những thao tác nào mà Iterator không hỗ trợ?
Trả lời:
Duyệt ngược.
Thêm/xóa/sửa phần tử trong khi duyệt.
32. Làm thế nào để sắp xếp một List?
Trả lời: Sử dụng Collections.sort()
hoặc Stream API.
33. ArrayList có cho phép phần tử null không?
Trả lời: Có, có thể chứa nhiều phần tử null.
34. Làm thế nào để duyệt qua các phần tử của List?
Trả lời: Bằng cách sử dụng vòng lặp for
, for-each
, Iterator
, hoặc ListIterator
.
35. Sự khác biệt giữa subList()
và clone()
trong ArrayList?
Trả lời:
subList()
: Tạo một view (chế độ xem) từ danh sách gốc.clone()
: Tạo một bản sao hoàn toàn mới.
36. Điều gì xảy ra nếu chỉnh sửa danh sách gốc sau khi gọi subList()
?
Trả lời: Sẽ gây ra ngoại lệ ConcurrentModificationException
.
37. Có thể chuyển đổi List thành mảng không?
Trả lời: Có, sử dụng phương thức toArray()
.
38. Phân biệt toArray()
và stream().toArray()
?
Trả lời:
toArray()
: Chuyển đổi trực tiếp thành mảng.stream().toArray()
: Tạo một mảng từ Stream, linh hoạt hơn.
39. ArrayList có đồng bộ hóa không?
Trả lời: Không, cần dùng Collections.synchronizedList()
để đồng bộ hóa.
40. Thêm/xóa phần tử giữa ArrayList và LinkedList, cái nào hiệu quả hơn?
Trả lời:
Thêm/xóa ở giữa: LinkedList hiệu quả hơn do không cần dời các phần tử.
Truy cập ngẫu nhiên: ArrayList nhanh hơn.
41. Làm thế nào để chuyển đổi một List thành Set?
Trả lời: Sử dụng new HashSet<>(list)
.
42. ArrayList có hỗ trợ loại bỏ trùng lặp không?
Trả lời: Không, cần sử dụng Set để loại bỏ trùng lặp.
43. Phương thức nào được sử dụng để xóa tất cả các phần tử trong List?
Trả lời: Phương thức clear()
.
44. Sự khác biệt giữa size()
và capacity()
trong ArrayList?
Trả lời:
size()
: Số lượng phần tử hiện tại.capacity()
: Dung lượng tối đa hiện tại của mảng bên trong.
45. Làm thế nào để thêm tất cả phần tử từ một Collection khác vào List?
Trả lời: Sử dụng addAll()
.
46. ArrayList có bất biến (immutable) không?
Trả lời: Không, nhưng có thể sử dụng Collections.unmodifiableList()
để tạo danh sách bất biến.
47. Điều gì xảy ra nếu thêm phần tử vào một danh sách bất biến?
Trả lời: Ném ngoại lệ UnsupportedOperationException
.
48. Các phương thức trong List có đảm bảo thứ tự chèn không?
Trả lời: Có, List luôn đảm bảo thứ tự chèn.
49. Cách sử dụng Stream API để lọc phần tử trong List?
Trả lời:
list.stream().filter(e -> e > 10).collect(Collectors.toList());
50. Làm thế nào để đảo ngược thứ tự một List?
Trả lời: Sử dụng Collections.reverse()
.
Phần 3: Set Interface và các Implementations (30 câu)
51. Set Interface là gì?
Trả lời: Là giao diện trong Java Collection Framework, không cho phép phần tử trùng lặp và không đảm bảo thứ tự.
52. Các lớp thực thi phổ biến của Set là gì?
Trả lời:
HashSet
LinkedHashSet
TreeSet
53. Làm thế nào để kiểm tra một Set có trống không?
Trả lời: Sử dụng phương thức isEmpty()
.
54. Sự khác biệt giữa HashSet và LinkedHashSet là gì?
Trả lời:
HashSet
: Không duy trì thứ tự chèn.LinkedHashSet
: Duy trì thứ tự chèn.
55. Tại sao HashSet không cho phép phần tử trùng lặp?
Trả lời: Vì HashSet sử dụng hashCode()
và equals()
để kiểm tra sự tồn tại của phần tử.
56. TreeSet khác với HashSet như thế nào?
Trả lời:
TreeSet
: Sắp xếp các phần tử theo thứ tự tự nhiên hoặc Comparator được chỉ định.HashSet
: Không sắp xếp các phần tử.
57. Khi nào nên sử dụng TreeSet thay vì HashSet?
Trả lời: Khi cần duy trì các phần tử theo thứ tự.
58. Điều gì xảy ra nếu thêm phần tử null vào TreeSet?
Trả lời: Sẽ ném ngoại lệ NullPointerException
vì TreeSet cần so sánh các phần tử.
59. HashSet hoạt động như thế nào nội bộ?
Trả lời: Sử dụng bảng băm (hash table). Các phần tử được lưu trữ dựa trên giá trị hashCode()
.
60. TreeSet sử dụng cấu trúc dữ liệu gì?
Trả lời: Sử dụng cây nhị phân cân bằng (Red-Black Tree).
61. Làm thế nào để loại bỏ trùng lặp từ một List sử dụng Set?
Trả lời:
Set<E> set = new HashSet<>(list);
list.clear();
list.addAll(set);
62. Làm thế nào để duyệt qua các phần tử trong một Set?
Trả lời:
Sử dụng
Iterator
.Hoặc vòng lặp
for-each
.
63. LinkedHashSet có hỗ trợ sắp xếp không?
Trả lời: Không, chỉ duy trì thứ tự chèn, không sắp xếp.
64. Làm thế nào để kiểm tra một phần tử có tồn tại trong Set?
Trả lời: Sử dụng phương thức contains()
.
65. Set có cho phép phần tử null không?
Trả lời:
HashSet
vàLinkedHashSet
: Cho phép một phần tử null.TreeSet
: Không cho phép null.
66. Điều gì xảy ra nếu hai phần tử có cùng hashCode()
nhưng không bằng nhau (equals()
) khi sử dụng HashSet?
Trả lời: Cả hai sẽ được lưu trữ, vì HashSet kiểm tra sự bằng nhau bằng equals()
.
67. Làm thế nào để tạo một Set bất biến (immutable)?
Trả lời:
Set<E> immutableSet = Collections.unmodifiableSet(new HashSet<>(set));
68. Phương thức nào được sử dụng để xóa tất cả phần tử khỏi Set?
Trả lời: Phương thức clear()
.
69. Sự khác biệt giữa add()
và addAll()
trong Set?
Trả lời:
add()
: Thêm một phần tử.addAll()
: Thêm tất cả phần tử từ một Collection khác.
70. TreeSet có thread-safe không?
Trả lời: Không, cần sử dụng Collections.synchronizedSet()
để làm thread-safe.
71. Làm thế nào để chuyển đổi một Set thành List?
Trả lời:
List<E> list = new ArrayList<>(set);
72. LinkedHashSet hiệu quả hơn HashSet trong trường hợp nào?
Trả lời: Khi cần duy trì thứ tự chèn.
73. Điều gì xảy ra nếu thêm một phần tử đã tồn tại vào Set?
Trả lời: Phần tử đó sẽ không được thêm vào.
74. TreeSet có hỗ trợ Comparator không?
Trả lời: Có, TreeSet hỗ trợ sắp xếp tùy chỉnh bằng Comparator.
75. Điều gì xảy ra nếu sửa đổi một phần tử trong Set?
Trả lời: Có thể gây lỗi vì thay đổi giá trị có thể ảnh hưởng đến hashCode()
hoặc thứ tự sắp xếp.
76. Làm thế nào để tìm sự giao nhau giữa hai Set?
Trả lời:
set1.retainAll(set2);
77. Sự khác biệt giữa retainAll()
và removeAll()
là gì?
Trả lời:
retainAll()
: Giữ lại các phần tử chung giữa hai Collection.removeAll()
: Loại bỏ tất cả các phần tử của một Collection khác.
78. Khi nào nên sử dụng HashSet thay vì TreeSet?
Trả lời: Khi không cần duy trì thứ tự và ưu tiên hiệu suất cao hơn.
79. TreeSet có hỗ trợ duyệt ngược không?
Trả lời: Có, sử dụng descendingIterator()
.
80. Làm thế nào để kiểm tra số phần tử trong Set?
Trả lời: Sử dụng phương thức size()
.
Phần 4: Map Interface và các Implementations
81. Map Interface là gì?
Trả lời: Map
là một giao diện trong Java Collection Framework, lưu trữ dữ liệu dưới dạng cặp key-value, trong đó key là duy nhất.
Dưới đây là phần 4: Map Interface và các Implementations (50 câu):
Phần 4: Map Interface và các Implementations
81. Map Interface là gì?
Trả lời: Map
là một giao diện trong Java Collection Framework, lưu trữ dữ liệu dưới dạng cặp key-value, trong đó key là duy nhất.
82. Sự khác biệt giữa Map và Collection?
Trả lời: Map
lưu trữ cặp key-value và không kế thừa Collection
, trong khi Collection
lưu trữ các phần tử đơn lẻ.
83. Những lớp thực thi phổ biến của Map là gì?
Trả lời:
HashMap
LinkedHashMap
TreeMap
WeakHashMap
ConcurrentHashMap
84. HashMap hoạt động như thế nào nội bộ?
Trả lời: Dựa trên bảng băm (hash table). Các phần tử được lưu trữ dựa trên giá trị hashCode()
của key.
85. Sự khác biệt giữa HashMap và LinkedHashMap?
Trả lời:
HashMap
: Không duy trì thứ tự chèn.LinkedHashMap
: Duy trì thứ tự chèn.
86. TreeMap hoạt động như thế nào?
Trả lời: TreeMap sử dụng cây nhị phân cân bằng (Red-Black Tree) để sắp xếp các phần tử theo thứ tự tự nhiên hoặc theo Comparator được cung cấp.
87. WeakHashMap là gì?
Trả lời: Là một Map sử dụng các khóa weak reference, cho phép các khóa bị thu hồi bởi garbage collector khi không còn được tham chiếu.
88. ConcurrentHashMap khác gì so với HashMap?
Trả lời:
ConcurrentHashMap
thread-safe, hỗ trợ lập trình đa luồng.HashMap
không thread-safe.
89. Map có cho phép null không?
Trả lời:
HashMap
: Cho phép một key null và nhiều value null.TreeMap
: Không cho phép null key.ConcurrentHashMap
: Không cho phép key hoặc value null.
90. Làm thế nào để duyệt qua các phần tử trong Map?
Trả lời:
Sử dụng
keySet()
để duyệt qua key.Sử dụng
entrySet()
để duyệt qua cả key và value.Sử dụng
values()
để duyệt qua value.
91. Sự khác biệt giữa put()
và putIfAbsent()
?
Trả lời:
put()
: Ghi đè value nếu key đã tồn tại.putIfAbsent()
: Chỉ thêm nếu key chưa tồn tại.
92. Làm thế nào để kiểm tra một key có tồn tại trong Map?
Trả lời: Sử dụng containsKey()
.
93. Phương thức computeIfAbsent()
trong Map có tác dụng gì?
Trả lời: Tính toán và thêm giá trị mới vào Map nếu key không tồn tại.
94. Điều gì xảy ra nếu hai key có cùng hashCode()
trong HashMap?
Trả lời: Các phần tử được lưu trữ trong cùng một bucket và phân biệt bằng equals()
.
95. Làm thế nào để tạo một Map bất biến?
Trả lời:
Map<K, V> immutableMap = Collections.unmodifiableMap(new HashMap<>(map));
96. Sự khác biệt giữa clear()
và remove()
trong Map?
Trả lời:
clear()
: Xóa toàn bộ Map.remove()
: Xóa một cặp key-value cụ thể.
97. Khi nào nên sử dụng TreeMap thay vì HashMap?
Trả lời: Khi cần sắp xếp các key theo thứ tự tự nhiên hoặc Comparator tùy chỉnh.
98. Làm thế nào để đếm số phần tử trong Map?
Trả lời: Sử dụng size()
.
99. WeakHashMap có lợi ích gì trong quản lý bộ nhớ?
Trả lời: Giải phóng khóa khỏi bộ nhớ khi không còn tham chiếu, tránh rò rỉ bộ nhớ.
100. ConcurrentHashMap có hỗ trợ fail-fast không?
Trả lời: Không, ConcurrentHashMap sử dụng cơ chế fail-safe.
101. Sự khác biệt giữa get()
và getOrDefault()
trong Map?
Trả lời:
get()
: Trả về null nếu key không tồn tại.getOrDefault()
: Trả về giá trị mặc định nếu key không tồn tại.
102. HashMap có đồng bộ hóa không?
Trả lời: Không, cần dùng Collections.synchronizedMap()
để đồng bộ hóa.
103. LinkedHashMap có ưu điểm gì khi duyệt Map?
Trả lời: Duy trì thứ tự chèn, giúp việc duyệt dễ dàng hơn.
104. Làm thế nào để sắp xếp một Map theo key?
Trả lời: Sử dụng TreeMap
hoặc Stream API.
105. TreeMap có thread-safe không?
Trả lời: Không, cần đồng bộ hóa bên ngoài nếu dùng trong môi trường đa luồng.
106. Điều gì xảy ra nếu thêm một phần tử có key null vào TreeMap?
Trả lời: Ném ngoại lệ NullPointerException
.
107. Làm thế nào để hợp nhất hai Map?
Trả lời: Sử dụng putAll()
hoặc Stream API.
108. Map có thể lưu trữ các phần tử trùng lặp không?
Trả lời: Không trùng lặp key, nhưng value có thể trùng lặp.
109. Làm thế nào để xóa tất cả các phần tử có giá trị null trong Map?
Trả lời:
map.values().removeIf(Objects::isNull);
110. Sự khác biệt giữa hashCode()
và equals()
trong Map?
Trả lời:
hashCode()
: Xác định vị trí bucket trong HashMap.equals()
: Kiểm tra sự bằng nhau giữa các key.
111. Làm thế nào để chuyển đổi Map thành List?
Trả lời: Sử dụng entrySet()
để tạo danh sách các cặp key-value.
112. Khi nào nên sử dụng ConcurrentHashMap?
Trả lời: Khi cần thread-safe với hiệu suất cao trong môi trường đa luồng.
113. Sự khác biệt giữa merge()
và put()
trong Map?
Trả lời:
merge()
: Hợp nhất giá trị hiện tại với giá trị mới theo logic tùy chỉnh.put()
: Thay thế giá trị hiện tại bằng giá trị mới.
114. Điều gì xảy ra nếu sử dụng null
làm key trong HashMap?
Trả lời: Cho phép một key null và lưu trữ nó trong bucket đặc biệt.
115. Tại sao TreeMap chậm hơn HashMap?
Trả lời: Vì TreeMap sử dụng cấu trúc cây để duy trì thứ tự, trong khi HashMap sử dụng bảng băm.
116. Sự khác biệt giữa keySet()
và entrySet()
?
Trả lời:
keySet()
: Trả về tập hợp các key.entrySet()
: Trả về tập hợp các cặp key-value.
117. Làm thế nào để lọc các phần tử trong Map?
Trả lời: Sử dụng Stream API với filter()
.
118. Điều gì xảy ra khi hai thread cùng sửa đổi ConcurrentHashMap?
Trả lời: ConcurrentHashMap quản lý các phân đoạn (segment) để tránh xung đột.
119. Làm thế nào để chuyển Map thành JSON?
Trả lời: Sử dụng thư viện như Jackson hoặc Gson.
120. Điều gì cần lưu ý khi sử dụng key trong Map?
Trả lời: Key nên là immutable để tránh thay đổi hashCode()
và equals()
.
Nếu bạn cần, tôi sẽ tiếp tục với phần 5: Queue và Deque Interface.82. Sự khác biệt giữa Map và Collection?
Trả lời: Map
lưu trữ cặp key-value và không kế thừa Collection
, trong khi Collection
lưu trữ các phần tử đơn lẻ.
83. Những lớp thực thi phổ biến của Map là gì?
Trả lời:
HashMap
LinkedHashMap
TreeMap
WeakHashMap
ConcurrentHashMap
84. HashMap hoạt động như thế nào nội bộ?
Trả lời: Dựa trên bảng băm (hash table). Các phần tử được lưu trữ dựa trên giá trị hashCode()
của key.
85. Sự khác biệt giữa HashMap và LinkedHashMap?
Trả lời:
HashMap
: Không duy trì thứ tự chèn.LinkedHashMap
: Duy trì thứ tự chèn.
86. TreeMap hoạt động như thế nào?
Trả lời: TreeMap sử dụng cây nhị phân cân bằng (Red-Black Tree) để sắp xếp các phần tử theo thứ tự tự nhiên hoặc theo Comparator được cung cấp.
87. WeakHashMap là gì?
Trả lời: Là một Map sử dụng các khóa weak reference, cho phép các khóa bị thu hồi bởi garbage collector khi không còn được tham chiếu.
88. ConcurrentHashMap khác gì so với HashMap?
Trả lời:
ConcurrentHashMap
thread-safe, hỗ trợ lập trình đa luồng.HashMap
không thread-safe.
89. Map có cho phép null không?
Trả lời:
HashMap
: Cho phép một key null và nhiều value null.TreeMap
: Không cho phép null key.ConcurrentHashMap
: Không cho phép key hoặc value null.
90. Làm thế nào để duyệt qua các phần tử trong Map?
Trả lời:
Sử dụng
keySet()
để duyệt qua key.Sử dụng
entrySet()
để duyệt qua cả key và value.Sử dụng
values()
để duyệt qua value.
91. Sự khác biệt giữa put()
và putIfAbsent()
?
Trả lời:
put()
: Ghi đè value nếu key đã tồn tại.putIfAbsent()
: Chỉ thêm nếu key chưa tồn tại.
92. Làm thế nào để kiểm tra một key có tồn tại trong Map?
Trả lời: Sử dụng containsKey()
.
93. Phương thức computeIfAbsent()
trong Map có tác dụng gì?
Trả lời: Tính toán và thêm giá trị mới vào Map nếu key không tồn tại.
94. Điều gì xảy ra nếu hai key có cùng hashCode()
trong HashMap?
Trả lời: Các phần tử được lưu trữ trong cùng một bucket và phân biệt bằng equals()
.
95. Làm thế nào để tạo một Map bất biến?
Trả lời:
Map<K, V> immutableMap = Collections.unmodifiableMap(new HashMap<>(map));
96. Sự khác biệt giữa clear()
và remove()
trong Map?
Trả lời:
clear()
: Xóa toàn bộ Map.remove()
: Xóa một cặp key-value cụ thể.
97. Khi nào nên sử dụng TreeMap thay vì HashMap?
Trả lời: Khi cần sắp xếp các key theo thứ tự tự nhiên hoặc Comparator tùy chỉnh.
98. Làm thế nào để đếm số phần tử trong Map?
Trả lời: Sử dụng size()
.
99. WeakHashMap có lợi ích gì trong quản lý bộ nhớ?
Trả lời: Giải phóng khóa khỏi bộ nhớ khi không còn tham chiếu, tránh rò rỉ bộ nhớ.
100. ConcurrentHashMap có hỗ trợ fail-fast không?
Trả lời: Không, ConcurrentHashMap sử dụng cơ chế fail-safe.
101. Sự khác biệt giữa get()
và getOrDefault()
trong Map?
Trả lời:
get()
: Trả về null nếu key không tồn tại.getOrDefault()
: Trả về giá trị mặc định nếu key không tồn tại.
102. HashMap có đồng bộ hóa không?
Trả lời: Không, cần dùng Collections.synchronizedMap()
để đồng bộ hóa.
103. LinkedHashMap có ưu điểm gì khi duyệt Map?
Trả lời: Duy trì thứ tự chèn, giúp việc duyệt dễ dàng hơn.
104. Làm thế nào để sắp xếp một Map theo key?
Trả lời: Sử dụng TreeMap
hoặc Stream API.
105. TreeMap có thread-safe không?
Trả lời: Không, cần đồng bộ hóa bên ngoài nếu dùng trong môi trường đa luồng.
106. Điều gì xảy ra nếu thêm một phần tử có key null vào TreeMap?
Trả lời: Ném ngoại lệ NullPointerException
.
107. Làm thế nào để hợp nhất hai Map?
Trả lời: Sử dụng putAll()
hoặc Stream API.
108. Map có thể lưu trữ các phần tử trùng lặp không?
Trả lời: Không trùng lặp key, nhưng value có thể trùng lặp.
109. Làm thế nào để xóa tất cả các phần tử có giá trị null trong Map?
Trả lời:
map.values().removeIf(Objects::isNull);
110. Sự khác biệt giữa hashCode()
và equals()
trong Map?
Trả lời:
hashCode()
: Xác định vị trí bucket trong HashMap.equals()
: Kiểm tra sự bằng nhau giữa các key.
111. Làm thế nào để chuyển đổi Map thành List?
Trả lời: Sử dụng entrySet()
để tạo danh sách các cặp key-value.
112. Khi nào nên sử dụng ConcurrentHashMap?
Trả lời: Khi cần thread-safe với hiệu suất cao trong môi trường đa luồng.
113. Sự khác biệt giữa merge()
và put()
trong Map?
Trả lời:
merge()
: Hợp nhất giá trị hiện tại với giá trị mới theo logic tùy chỉnh.put()
: Thay thế giá trị hiện tại bằng giá trị mới.
114. Điều gì xảy ra nếu sử dụng null
làm key trong HashMap?
Trả lời: Cho phép một key null và lưu trữ nó trong bucket đặc biệt.
115. Tại sao TreeMap chậm hơn HashMap?
Trả lời: Vì TreeMap sử dụng cấu trúc cây để duy trì thứ tự, trong khi HashMap sử dụng bảng băm.
116. Sự khác biệt giữa keySet()
và entrySet()
?
Trả lời:
keySet()
: Trả về tập hợp các key.entrySet()
: Trả về tập hợp các cặp key-value.
117. Làm thế nào để lọc các phần tử trong Map?
Trả lời: Sử dụng Stream API với filter()
.
118. Điều gì xảy ra khi hai thread cùng sửa đổi ConcurrentHashMap?
Trả lời: ConcurrentHashMap quản lý các phân đoạn (segment) để tránh xung đột.
119. Làm thế nào để chuyển Map thành JSON?
Trả lời: Sử dụng thư viện như Jackson hoặc Gson.
120. Điều gì cần lưu ý khi sử dụng key trong Map?
Trả lời: Key nên là immutable để tránh thay đổi hashCode()
và equals()
.
Phần 5: Queue và Deque Interface (20 câu)
121. Queue Interface là gì?
Trả lời: Queue
là một giao diện trong Java Collection Framework, thực hiện cấu trúc dữ liệu hàng đợi (FIFO: First In First Out).
122. Những lớp thực thi phổ biến của Queue là gì?
Trả lời:
LinkedList
PriorityQueue
ArrayDeque
123. Sự khác biệt giữa Queue và Stack là gì?
Trả lời:
Queue
: Hoạt động theo nguyên tắc FIFO (First In First Out).Stack
: Hoạt động theo nguyên tắc LIFO (Last In First Out).
124. PriorityQueue là gì?
Trả lời: Là một lớp Queue sắp xếp các phần tử dựa trên thứ tự tự nhiên hoặc Comparator được cung cấp.
125. Khi nào nên sử dụng PriorityQueue?
Trả lời: Khi cần xử lý các phần tử theo thứ tự ưu tiên thay vì thứ tự chèn.
126. Sự khác biệt giữa add()
và offer()
trong Queue là gì?
Trả lời:
add()
: Ném ngoại lệ nếu hàng đợi đầy.offer()
: Trả vềfalse
nếu hàng đợi đầy.
127. Deque Interface là gì?
Trả lời: Deque
là một giao diện mở rộng của Queue, hỗ trợ cả hai chiều (FIFO và LIFO).
128. Những lớp thực thi phổ biến của Deque là gì?
Trả lời:
ArrayDeque
LinkedList
129. Sự khác biệt giữa Deque và Queue?
Trả lời:
Queue
: Chỉ hỗ trợ thao tác ở đầu và cuối hàng đợi theo thứ tự FIFO.Deque
: Hỗ trợ thêm/xóa ở cả hai đầu.
130. ArrayDeque có hỗ trợ thread-safe không?
Trả lời: Không, ArrayDeque không thread-safe.
131. BlockingQueue là gì?
Trả lời: Là một giao diện mở rộng của Queue, hỗ trợ điều phối luồng với khả năng chờ khi hàng đợi đầy hoặc rỗng.
132. Những lớp thực thi của BlockingQueue là gì?
Trả lời:
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
133. Sự khác biệt giữa poll()
và peek()
trong Queue?
Trả lời:
poll()
: Lấy và xóa phần tử đầu tiên.peek()
: Lấy nhưng không xóa phần tử đầu tiên.
134. Điều gì xảy ra khi poll()
được gọi trên một Queue rỗng?
Trả lời: Trả về null
.
135. Làm thế nào để đảo ngược thứ tự của một Queue?
Trả lời: Sử dụng Deque
hoặc chuyển Queue thành List rồi đảo ngược bằng Collections.reverse()
.
136. Làm thế nào để duyệt qua các phần tử trong Queue?
Trả lời:
Sử dụng vòng lặp
for-each
.Hoặc sử dụng
Iterator
.
137. ArrayDeque có hỗ trợ null không?
Trả lời: Không, ArrayDeque không cho phép null.
138. BlockingQueue có an toàn trong môi trường đa luồng không?
Trả lời: Có, nó được thiết kế thread-safe.
139. Khi nào nên sử dụng ArrayDeque thay vì LinkedList?
Trả lời: Khi ưu tiên hiệu suất vì ArrayDeque nhanh hơn LinkedList trong hầu hết các thao tác hàng đợi.
140. Làm thế nào để kiểm tra số phần tử trong Queue?
Trả lời: Sử dụng phương thức size()
.
Phần 6: Thuật toán và Tiện ích trong Collections (30 câu)
141. Thuật toán sắp xếp trong Collections Framework là gì?
Trả lời: Collections.sort()
và List.sort()
sắp xếp các phần tử của List theo thứ tự tự nhiên hoặc Comparator được cung cấp.
142. Sự khác biệt giữa Collections.sort()
và List.sort()
là gì?
Trả lời:
Collections.sort()
: Phương thức tĩnh, hoạt động trên bất kỳ List nào.List.sort()
: Là phương thức mặc định của List, hiệu quả hơn khi làm việc với các lớp List cụ thể.
143. Khi nào nên sử dụng Comparable
thay vì Comparator
?
Trả lời:
Comparable
: Khi muốn định nghĩa thứ tự tự nhiên cho đối tượng.Comparator
: Khi cần tùy chỉnh thứ tự hoặc sử dụng nhiều cách sắp xếp.
144. Cách thực hiện tìm kiếm nhị phân trong Collection là gì?
Trả lời: Sử dụng Collections.binarySearch()
. Dữ liệu phải được sắp xếp trước khi tìm kiếm.
145. Sự khác biệt giữa min()
và max()
trong Collections?
Trả lời:
min()
: Trả về phần tử nhỏ nhất theo thứ tự tự nhiên hoặc Comparator.max()
: Trả về phần tử lớn nhất.
146. Làm thế nào để tạo một danh sách bất biến?
Trả lời: Sử dụng Collections.unmodifiableList()
hoặc List.of()
.
147. Sự khác biệt giữa Collections.synchronizedList()
và CopyOnWriteArrayList
?
Trả lời:
Collections.synchronizedList()
: Đơn giản nhưng có thể gây xung đột khi đọc/ghi đồng thời.CopyOnWriteArrayList
: An toàn hơn, tạo bản sao khi ghi nhưng tốn nhiều bộ nhớ hơn.
148. Làm thế nào để sao chép một Collection?
Trả lời: Sử dụng Collections.copy()
hoặc constructor của Collection như new ArrayList<>(list)
.
149. Phương thức shuffle()
trong Collections có tác dụng gì?
Trả lời: Trộn ngẫu nhiên các phần tử trong một List.
150. Khi nào nên sử dụng reverseOrder()
trong Comparator?
Trả lời: Khi cần sắp xếp các phần tử theo thứ tự ngược lại so với thứ tự tự nhiên.
151. Làm thế nào để tạo một Collection chứa phần tử trùng lặp?
Trả lời: Sử dụng Collections.nCopies()
để tạo một danh sách chứa cùng một phần tử nhiều lần.
152. Sự khác biệt giữa replaceAll()
và fill()
trong Collections?
Trả lời:
replaceAll()
: Thay thế các phần tử dựa trên điều kiện.fill()
: Thay thế tất cả phần tử bằng một giá trị cụ thể.
153. Cách sử dụng Stream API để lọc các phần tử trong List?
Trả lời:
list.stream().filter(e -> e > 10).collect(Collectors.toList());
154. Làm thế nào để duyệt đồng thời hai List?
Trả lời: Sử dụng vòng lặp dựa trên chỉ số:
for (int i = 0; i < Math.min(list1.size(), list2.size()); i++) {
System.out.println(list1.get(i) + " - " + list2.get(i));
}
155. Phương thức rotate()
trong Collections có tác dụng gì?
Trả lời: Xoay vòng các phần tử trong List theo một số bước được chỉ định.
156. Làm thế nào để tìm các phần tử chung giữa hai Collection?
Trả lời: Sử dụng retainAll()
để giữ lại các phần tử chung.
157. Sự khác biệt giữa disjoint()
và retainAll()
?
Trả lời:
disjoint()
: Trả vềtrue
nếu hai Collection không có phần tử chung.retainAll()
: Chỉ giữ lại phần tử chung trong Collection gốc.
158. Làm thế nào để đảm bảo Collection thread-safe?
Trả lời: Sử dụng các phương thức như Collections.synchronizedList()
hoặc các lớp thread-safe như ConcurrentHashMap
.
159. Cách kiểm tra Collection có rỗng không?
Trả lời: Sử dụng phương thức isEmpty()
.
160. Làm thế nào để loại bỏ các phần tử trùng lặp khỏi List?
Trả lời: Sử dụng new ArrayList<>(new HashSet<>(list))
.
161. Phương thức nào được sử dụng để sắp xếp List ngược lại?
Trả lời: Sử dụng Collections.reverseOrder()
với Collections.sort()
.
162. Khi nào nên sử dụng emptyList()
trong Collections?
Trả lời: Khi cần một danh sách bất biến rỗng để tránh lỗi NullPointerException.
163. Sự khác biệt giữa frequency()
và counting()
trong Stream API?
Trả lời:
Collections.frequency()
: Đếm tần suất của một phần tử cụ thể trong Collection.Stream.counting()
: Đếm tổng số phần tử trong Stream.
164. Làm thế nào để nhóm các phần tử trong Collection?
Trả lời: Sử dụng Stream API với Collectors.groupingBy()
.
165. Phương thức swap()
trong Collections có tác dụng gì?
Trả lời: Hoán đổi hai phần tử trong List tại các chỉ số được chỉ định.
166. Làm thế nào để tạo một Collection immutable với một phần tử?
Trả lời: Sử dụng Collections.singletonList(element)
.
167. Sự khác biệt giữa parallelStream()
và stream()
?
Trả lời:
stream()
: Hoạt động tuần tự.parallelStream()
: Hoạt động song song, cải thiện hiệu suất khi xử lý dữ liệu lớn.
168. Làm thế nào để kiểm tra tất cả các phần tử trong Collection có thỏa mãn điều kiện không?
Trả lời: Sử dụng Stream.allMatch()
.
169. Khi nào nên sử dụng replaceAll()
trên List?
Trả lời: Khi cần thay đổi tất cả các phần tử của List dựa trên một điều kiện.
170. Sự khác biệt giữa unmodifiableList()
và emptyList()
là gì?
Trả lời:
unmodifiableList()
: Tạo một danh sách bất biến từ danh sách đã có.emptyList()
: Tạo một danh sách bất biến rỗng.
Phần 7: Performance và Optimization (20 câu)
171. Làm thế nào để chọn đúng Collection trong Java?
Trả lời: Phân tích các yếu tố sau:
Thứ tự: Dùng
List
hoặcLinkedHashSet
nếu cần duy trì thứ tự.Tốc độ: Dùng
HashMap
hoặcHashSet
cho truy cập nhanh.Không trùng lặp: Dùng
Set
hoặcMap
(key phải duy nhất).Đa luồng: Dùng
ConcurrentHashMap
hoặcCopyOnWriteArrayList
.
172. ArrayList và LinkedList, cái nào nhanh hơn?
Trả lời:
ArrayList: Nhanh hơn khi truy cập ngẫu nhiên.
LinkedList: Nhanh hơn khi thêm/xóa phần tử ở giữa hoặc đầu danh sách.
173. Khi nào nên sử dụng HashSet thay vì TreeSet?
Trả lời:
HashSet: Khi không cần duy trì thứ tự và muốn hiệu suất cao.
TreeSet: Khi cần sắp xếp các phần tử.
174. HashMap hoạt động hiệu quả nhất khi nào?
Trả lời: Khi hashCode()
và equals()
của các key được tối ưu để giảm số lượng xung đột (collisions).
175. Làm thế nào để tránh ConcurrentModificationException
trong Collection?
Trả lời:
Sử dụng các lớp thread-safe như
ConcurrentHashMap
,CopyOnWriteArrayList
.Duyệt Collection bằng cách dùng
iterator()
thay vì vòng lặp.
176. Cách tối ưu bộ nhớ khi sử dụng Collection?
Trả lời:
Sử dụng kích thước khởi tạo (
initialCapacity
) phù hợp.Sử dụng
ArrayList
thay vìLinkedList
nếu không cần thao tác thêm/xóa nhiều.Xóa các tham chiếu không cần thiết.
177. Sự khác biệt về hiệu suất giữa Synchronized Collections và Concurrent Collections?
Trả lời:
Synchronized Collections: Chậm hơn do khóa toàn bộ Collection.
Concurrent Collections: Hiệu suất cao hơn vì sử dụng cơ chế phân đoạn hoặc sao chép khi ghi (copy-on-write).
178. Tại sao nên dùng ConcurrentHashMap thay vì Hashtable?
Trả lời:
ConcurrentHashMap: Chỉ khóa từng phân đoạn nhỏ, hiệu suất tốt hơn.
Hashtable: Khóa toàn bộ Map, gây nghẽn khi đa luồng.
179. Làm thế nào để cải thiện hiệu suất sắp xếp trong List?
Trả lời:
Sử dụng
Collections.sort()
với Comparator tối ưu.Sử dụng
parallelStream().sorted()
để tận dụng đa luồng.
180. Hiệu suất của HashSet phụ thuộc vào yếu tố nào?
Trả lời:
Chất lượng của
hashCode()
vàequals()
.Kích thước của bảng băm (
initialCapacity
vàloadFactor
).
181. Khi nào nên sử dụng TreeMap
thay vì HashMap
?
Trả lời: Khi cần duy trì thứ tự của các key hoặc cần các thao tác tìm kiếm theo khoảng giá trị (range queries).
182. Điều gì xảy ra nếu chọn kích thước khởi tạo không phù hợp cho HashMap?
Trả lời:
Quá nhỏ: Tăng số lần rehash, giảm hiệu suất.
Quá lớn: Lãng phí bộ nhớ.
183. Sự khác biệt giữa initialCapacity
và loadFactor
trong HashMap là gì?
Trả lời:
initialCapacity: Kích thước ban đầu của bảng băm.
loadFactor: Tỷ lệ đầy trước khi tăng kích thước (rehash).
184. Cách giảm xung đột (collision) trong HashMap?
Trả lời:
Cải thiện logic
hashCode()
để tạo ra giá trị phân tán tốt hơn.Giảm số lượng phần tử trong một bucket bằng cách tăng
initialCapacity
.
185. Tại sao CopyOnWriteArrayList phù hợp với các thao tác đọc nhiều và ghi ít?
Trả lời: Vì nó tạo bản sao mới khi ghi, đảm bảo thread-safe mà không cần khóa, nhưng việc ghi tốn tài nguyên.
186. Sử dụng Iterator có hiệu quả hơn vòng lặp for thông thường không?
Trả lời: Có, khi làm việc với Collection không hỗ trợ truy cập ngẫu nhiên, như LinkedList
.
187. Khi nào nên dùng PriorityQueue thay vì ArrayList?
Trả lời: Khi cần ưu tiên xử lý các phần tử theo thứ tự ưu tiên thay vì thứ tự chèn.
188. Hiệu suất của TreeSet so với HashSet như thế nào?
Trả lời:
TreeSet: Chậm hơn vì cần duy trì thứ tự thông qua cấu trúc cây.
HashSet: Nhanh hơn vì dựa trên bảng băm.
189. Có thể sử dụng Stream API để tăng hiệu suất không?
Trả lời: Có, với parallelStream()
để tận dụng CPU đa nhân, đặc biệt khi xử lý dữ liệu lớn.
190. Điều gì cần lưu ý khi sử dụng Collections trong môi trường đa luồng?
Trả lời:
Sử dụng các lớp thread-safe như
ConcurrentHashMap
,CopyOnWriteArrayList
.Tránh sửa đổi Collection khi đang duyệt (sử dụng Iterator fail-safe nếu cần).
Phần 8: Advanced Topics (20 câu)
191. Làm thế nào để tạo một Collection tùy chỉnh?
Trả lời: Thực hiện giao diện Collection
hoặc mở rộng các lớp hiện có như AbstractCollection
.
192. Giao diện NavigableSet
là gì?
Trả lời: Là giao diện mở rộng của SortedSet
, cung cấp các phương thức để truy vấn phần tử gần nhất lớn hơn hoặc nhỏ hơn một giá trị cụ thể (e.g., floor()
, ceiling()
).
193. Sự khác biệt giữa NavigableMap
và SortedMap
là gì?
Trả lời:
SortedMap
: Duy trì các phần tử theo thứ tự tự nhiên.NavigableMap
: Mở rộngSortedMap
với các phương thức điều hướng nhưhigherKey()
,lowerKey()
.
194. Cách sử dụng WeakHashMap
trong quản lý bộ nhớ?
Trả lời: Sử dụng WeakHashMap
để lưu trữ các đối tượng tạm thời. Các khóa sẽ được thu hồi bởi garbage collector khi không còn tham chiếu mạnh.
195. Fail-fast Iterator hoạt động như thế nào?
Trả lời: Ném ngoại lệ ConcurrentModificationException
nếu Collection bị thay đổi cấu trúc trong khi duyệt.
196. Làm thế nào để triển khai một Iterator tùy chỉnh?
Trả lời: Thực hiện giao diện Iterator
và định nghĩa các phương thức hasNext()
, next()
, và (tùy chọn) remove()
.
197. Sự khác biệt giữa IdentityHashMap
và HashMap
là gì?
Trả lời:
HashMap
: So sánh key bằngequals()
.IdentityHashMap
: So sánh key bằng==
, dựa trên tham chiếu bộ nhớ.
198. Tại sao nên sử dụng Collections.unmodifiableCollection()
?
Trả lời: Để tạo một Collection bất biến, ngăn ngừa sửa đổi dữ liệu và cải thiện an toàn dữ liệu trong môi trường đa luồng.
199. Giao diện SortedSet
hoạt động như thế nào?
Trả lời: Duy trì phần tử theo thứ tự tự nhiên hoặc Comparator tùy chỉnh. Ví dụ: TreeSet
là một triển khai của SortedSet
.
200. Sự khác biệt giữa AbstractSet
và HashSet
là gì?
Trả lời:
AbstractSet
: Lớp trừu tượng cung cấp các phương thức mặc định choSet
.HashSet
: Lớp cụ thể thực thiSet
dựa trên bảng băm.
201. Khi nào nên sử dụng Collections.checkedCollection()
?
Trả lời: Khi muốn kiểm tra kiểu dữ liệu của phần tử tại thời điểm runtime, giúp phát hiện lỗi sớm trong môi trường Generics.
202. Làm thế nào để sử dụng EnumSet
hiệu quả?
Trả lời: Sử dụng EnumSet
khi làm việc với các giá trị Enum. Nó tối ưu hóa bộ nhớ và hiệu suất so với các Set thông thường.
203. Sự khác biệt giữa ConcurrentSkipListMap
và TreeMap
?
Trả lời:
ConcurrentSkipListMap
: Thread-safe và hiệu suất cao trong môi trường đa luồng.TreeMap
: Không thread-safe.
204. Map.Entry
trong Java là gì?
Trả lời: Là một giao diện để truy cập các cặp key-value trong Map. Ví dụ: entrySet()
trả về một tập hợp các Map.Entry
.
205. Sử dụng Custom Comparator
trong TreeSet như thế nào?
Trả lời:
TreeSet<Integer> set = new TreeSet<>((a, b) -> b - a);
Sắp xếp TreeSet theo thứ tự giảm dần.
206. Cách sử dụng removeIf()
trong Collection?
Trả lời:
list.removeIf(e -> e % 2 == 0);
Xóa tất cả các phần tử chẵn khỏi danh sách.
207. Sự khác biệt giữa ListIterator
và Iterator
?
Trả lời:
Iterator
: Chỉ duyệt một chiều, không chỉnh sửa được Collection.ListIterator
: Duyệt hai chiều, có thể chỉnh sửa Collection.
208. ConcurrentHashMap sử dụng cơ chế gì để đạt được thread-safe?
Trả lời: Sử dụng cơ chế phân đoạn (segmentation) và khóa từng bucket nhỏ thay vì khóa toàn bộ Map.
209. Làm thế nào để tạo một SortedMap
từ một HashMap
?
Trả lời:
Map<K, V> sortedMap = new TreeMap<>(hashMap);
210. Sự khác biệt giữa CopyOnWriteArrayList
và ArrayList
là gì?
Trả lời:
CopyOnWriteArrayList
: Thread-safe, sao chép toàn bộ danh sách khi ghi.ArrayList
: Không thread-safe, nhanh hơn khi làm việc đơn luồng.
Phần 9: Câu hỏi tình huống thực tế (30 câu)
211. Làm thế nào để tìm tất cả các phần tử trùng lặp trong một List?
Trả lời:
Set<Integer> unique = new HashSet<>();
Set<Integer> duplicates = list.stream()
.filter(e -> !unique.add(e))
.collect(Collectors.toSet());
212. Cách đếm số lần xuất hiện của các phần tử trong một List?
Trả lời:
Map<Integer, Long> frequency = list.stream()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
213. Làm thế nào để chuyển đổi một List thành Map với key là phần tử và value là độ dài của phần tử?
Trả lời:
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(e -> e, String::length));
214. Cách kiểm tra xem hai List có phần tử chung không?
Trả lời:
boolean hasCommon = list1.stream().anyMatch(list2::contains);
215. Làm thế nào để tìm phần tử lớn nhất và nhỏ nhất trong một Collection?
Trả lời:
Integer max = Collections.max(list);
Integer min = Collections.min(list);
216. Cách loại bỏ các phần tử null khỏi một List?
Trả lời:
list.removeIf(Objects::isNull);
217. Làm thế nào để hợp nhất hai Map mà không ghi đè giá trị trùng lặp?
Trả lời:
map1.forEach((key, value) -> map2.merge(key, value, (v1, v2) -> v1));
218. Cách tìm phần tử đầu tiên khớp với điều kiện trong một List?
Trả lời:
Optional<Integer> result = list.stream().filter(e -> e > 10).findFirst();
219. Làm thế nào để đảo ngược thứ tự các phần tử trong List?
Trả lời:
Collections.reverse(list);
220. Làm thế nào để sắp xếp một Map theo giá trị?
Trả lời:
Map<String, Integer> sorted = map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(e1, e2) -> e1, LinkedHashMap::new));
221. Làm thế nào để tìm tất cả các phần tử bắt đầu bằng chữ cái 'A' trong một List?
Trả lời:
List<String> result = list.stream().filter(e -> e.startsWith("A")).collect(Collectors.toList());
222. Làm thế nào để phân nhóm các phần tử trong một List theo độ dài của chúng?
Trả lời:
Map<Integer, List<String>> grouped = list.stream()
.collect(Collectors.groupingBy(String::length));
223. Làm thế nào để tạo một Queue từ một List?
Trả lời:
Queue<Integer> queue = new LinkedList<>(list);
224. Cách tạo một Stack từ một Collection?
Trả lời:
Stack<Integer> stack = new Stack<>();
stack.addAll(collection);
225. Làm thế nào để xóa tất cả các phần tử trong Set xuất hiện trong List?
Trả lời:
set.removeAll(list);
226. Làm thế nào để tìm số lượng phần tử duy nhất trong List?
Trả lời:
long uniqueCount = list.stream().distinct().count();
227. Làm thế nào để tách một List lớn thành các List nhỏ hơn?
Trả lời:
List<List<Integer>> partitions = IntStream.range(0, list.size() / size + 1)
.mapToObj(i -> list.subList(i * size, Math.min((i + 1) * size, list.size())))
.collect(Collectors.toList());
228. Làm thế nào để tìm key có giá trị lớn nhất trong Map?
Trả lời:
String maxKey = map.entrySet()
.stream()
.max(Map.Entry.comparingByValue())
.get()
.getKey();
229. Cách xóa phần tử cuối cùng trong LinkedList?
Trả lời:
linkedList.removeLast();
230. Làm thế nào để chuyển đổi một Collection thành mảng?
Trả lời:
Integer[] array = collection.toArray(new Integer[0]);
231. Làm thế nào để tính tổng tất cả các phần tử trong một List số nguyên?
Trả lời:
int sum = list.stream().mapToInt(Integer::intValue).sum();
232. Làm thế nào để kiểm tra xem tất cả các phần tử trong List đều lớn hơn 0?
Trả lời:
boolean allPositive = list.stream().allMatch(e -> e > 0);
233. Làm thế nào để xóa tất cả các phần tử trùng lặp trong List?
Trả lời:
List<Integer> uniqueList = list.stream().distinct().collect(Collectors.toList());
234. Làm thế nào để kiểm tra một List có thứ tự tăng dần không?
Trả lời:
boolean isSorted = IntStream.range(0, list.size() - 1).allMatch(i -> list.get(i) <= list.get(i + 1));
235. Cách gộp nhiều Set thành một Set duy nhất?
Trả lời:
Set<Integer> combined = Stream.of(set1, set2, set3).flatMap(Set::stream).collect(Collectors.toSet());
236. Làm thế nào để chuyển đổi một List thành LinkedHashSet để loại bỏ trùng lặp?
Trả lời:
Set<Integer> set = new LinkedHashSet<>(list);
237. Cách tìm phần tử nhỏ nhất trong một Stream của số nguyên?
Trả lời:
OptionalInt min = list.stream().mapToInt(Integer::intValue).min();
238. Làm thế nào để tạo một danh sách có các phần tử được nhân đôi từ List gốc?
Trả lời:
List<Integer> doubled = list.stream().map(e -> e * 2).collect(Collectors.toList());