Sự khác nhau giữa set và map

Java Map

Java Map là một phần của collections framework. Đối tượng Java Map được sử dụng để chứa các cặp khóa-giá trị. Java Map không thể chứa các khóa giống hệt nhau tuy nhiên các giá trị giống nhau thì được phép.
Một số đặc điểm về Map trong Java đó là:

  1. Map cung cấp 3 collection views – set of keys, set of key-value mappings và collection of values
  2. Map không đảm bảo về thứ tự khớp, tuy nhiên nó lại phụ thuộc vào cách thực hiện. Ví dụ, HashMap không đảm bảo thứ tự khớp nhưng TreeMap thì có.
  3. Map dùng hashCode và các phương thức tương đương trên Khóa cho các phép toán get và put. Do vậy, các class có thể biến đổi sẽ không phù hợp với các khóa của Map.Nếu các giá trị của hashCode hoặc tương đương thay đổi sau put, bạn sẽ không lấy được giá trị đúng trong phép toán get.
  4. Các implementation class phổ biến của Map trong Java là HashMap, Hashtable, TreeMap, ConcurrentHashMap và LinkedHashMap.
  5. AbstractMap class cung cấp skeletal implementation của Map interface, phần lớn các concrete class của Map mở rộng AbstractMap class và các phương thức cần thiết phải implement.

Các phương thức của Java Map

Chúng ta hãy cùng tìm hiểu một số phương thức quan trọng của Map.

  1. int size(): trả về số ;ượng cặp khóa-giá trị trong Map.
  2. boolean isEmpty(): trả về là nếu không có cặp nào, nếu không thì false.
  3. boolean containsValue(Object value): trả về là true nếu có ít nhất một khóa được khớp với một giá trị cụ thể, nếu không thì false.
  4. V get(Object key): trả về giá trị được khớp với khóa đã đâ ra, nếu không có cặp nào thì sẽ trả về null.
  5. V put(K key, V value): thêm các cặp khóa-giá trị vào map. Nếu đã có một giá trị được khớp với khóa này thì thay giá trị. Phương thức này trả về giá trị trước đó tương ứng với khóa, hoặc null nếu khóa không có gì khớp với khóa.
  6. V remove(Object key): loại bỏ giá trị được khớp với khóa khỏi map này nếu nó tồn tại. Trả về giá trị trước đó mà map khớp với khóa, hoặc null nếu map không chứa giá trị nào để khớp với khóa.
  7. void putAll(Map m): Sao chép tất cả các cặp từ một map sang map này.
  8. void clear(): loại bỏ tất cá các cặp khỏi Map.
  9. Set keySet(): trả về Set view của tất cả các khóa trong Map. Key set này được hậu thuẫn bởi Map, vì vậy bất kỳ chỉnh sửa nào trong Map sẽ phản xạ lại key set và ngược lại.
  10. Collection values(): trá về collection view của tất cả các giá trị trong Map. Tập hợp này được hậu thuẫn bởi Map, vì vậy bất kì thay đổi nào trong Map sẽ phản xạ lại tập hợp giá trị và ngược lại.
  11. Set> entrySet(): trả về Set view của các cặp trong Map. Set này được hậu thuẫn bởi Map, vì vậy bất kỳ chỉnh sửa nào trong Map sẽ phản xạ lại trong entry set và ngược lại.

Có một vài phương thức Java Map được giới thiệu trong Java 8.

  1. default V getOrDefault(Object key, V defaultValue): trả về giá trị được khớp với một khóa cụ thể, hoặc defaultValue nếu map không chứa giá trị nào để khớp với khóa.
  2. default void forEach(BiConsumer action): thực hiện action được đưa ra cho mỗi đầu vào của map này.
  3. default void replaceAll(BiFunction function): thay giá trị của mỗi entry với kết quả dẫn hàm được đưa ra cho entry đó.
  4. default V putIfAbsent(K key, V value): nếu một khóa cụ thể chưa được khớp với giá trị (hay được khớp với null), khớp nó với giá trị được đưa ra và trả về null, ngoài ra thì trả về giá trị hiện tại.
  5. default boolean remove(Object key, Object value): Loại bỏ entry cho một khóa cụ thể chỉ khi nó đang được khớp với một giá trị cụ thể.
  6. default boolean replace(K key, V oldValue, V newValue): Thay thế entry cho một khóa cụ thể chỉ khi nó đang được khớp với một giá trị cụ thể.
  7. default V replace(K key, V value): Thay thế entry cho một khóa cụ thể chỉ khi nó đang được khớp với một số giá trị.
  8. default V computeIfAbsent(K key, Function mappingFunction): Nếu khóa cụ thể chưa được khớp vởi một giá trị (hoặc khớp với null), tính toán giá trị của nó sử dụng hàm mapping được đưa ra và nhập nó vòa map này trừ khi null.
  9. default V computeIfPresent(K key, BiFunction remappingFunction): nếu tồn tại giá trị cho một khóa cụ thể và không phải null, tính toán để khớp một giá trị mới cho cặp khóa và giá trị hiện tại được khớp với nó. Nếu hàm trả về null, thì việc khớp giá trị mới sẽ được loại bỏ
  10. default V compute(K key, BiFunction remappingFunction): tính toán để khớp một giá trị mới cho cặp khóa và giá trị hiện tại được khớp với nó (hoặc null nếu không có giá trị nào đang được khớp).
  11. default V merge(K key, V value, BiFunction remappingFunction): nếu một khóa cụ thể chưa được khớp với một giá trị hoặc đang khớp với null, khớp nó với một giá trị không phải null. Ngoài ra, thay thế giá trị được khớp với kết quả của hàm remapping được đưa ra, hoặc loại bỏ nếu kết quả là null.

Bạn sẽ để ý thấy tất cả các phương thức mới được thêm vào Java 8 Map interface là các phương thức mặc định với implementation. Điều này là để đảm bảo không xảy ra các lỗi biên dịch khi các class implement Map interface.

Ví dụ

Dưới đây là ví dụ về một chương trình đơn giản cho Java Map. Chúng ta sẽ sử dụng Map implementation class HashMap cho ví dụ này.

packagecom.journaldev.examples;

importjava.util.Collection;

importjava.util.HashMap;

importjava.util.Map;

importjava.util.Map.Entry;

importjava.util.Set;

publicclassMapExample{

publicstaticvoidmain(String[]args){

Map<String,String>data=newHashMap<>();

data.put("A","A");//putexample

data.put("B","B");

data.put("C","C");

data.put("D",null);//nullvalue

data.put(null,"Z");//nullkey

Stringvalue=data.get("C");//getexample

System.out.println("Key=C,Value="+value);

value=data.getOrDefault("E","DefaultValue");

System.out.println("Key=E,Value="+value);

booleankeyExists=data.containsKey(null);

booleanvalueExists=data.containsValue("Z");

System.out.println("keyExists="+keyExists+",valueExists="+valueExists);

Set<Entry<String,String>>entrySet=data.entrySet();

System.out.println(entrySet);

System.out.println("datamapsize="+data.size());

Map<String,String>data1=newHashMap<>();

data1.putAll(data);

System.out.println("data1mappings="+data1);

StringnullKeyValue=data1.remove(null);

System.out.println("data1nullkeyvalue="+nullKeyValue);

System.out.println("data1afterremovingnullkey="+data1);

Set<String>keySet=data.keySet();

System.out.println("datamapkeys="+keySet);

Collection<String>values=data.values();

System.out.println("datamapvalues="+values);

data.clear();

System.out.println("datamapisempty="+data.isEmpty());

}

}


Output của chương trình trên sẽ là:

Key=C,Value=C

Key=E,Value=DefaultValue

keyExists=true,valueExists=true

[null=Z,A=A,B=B,C=C,D=null]

datamapsize=5

data1mappings={null=Z,A=A,B=B,C=C,D=null}

data1nullkeyvalue=Z

data1afterremovingnullkey={A=A,B=B,C=C,D=null}

datamapkeys=[null,A,B,C,D]

datamapvalues=[Z,A,B,C,null]

datamapisempty=true

1. Framework là gì?

Khung công tác là một kiến ​​trúc được xác định trước có chứa một tập hợp một số lớp và giao diện có thể được sử dụng trực tiếp mà không cần bất kỳ sửa đổi nào.

2. Khung Bộ sưu tập là gì?

Trong Java, tập hợp là một thực thể duy nhất đại diện cho một nhóm đối tượng và khung là một kiến ​​trúc được xác định có chứa các giao diện và lớp. Do đó, khung công tác Bộ sưu tập Java là một kiến ​​trúc xác định một định giao diện, lớp và thuật toán. Khung này có sẵn từ JDK 1.2. Nó cũng có thể thực hiện các hoạt động như tìm kiếm, chèn, sắp xếp, xóa, thao tác, v.v.

3. Lớp Collections là gì?

Collections là một lớp trong Java là một phần của gói java.util và chứa nhiều phương thức tĩnh khác nhau mà chúng ta có thể sử dụng để thực hiện các thao tác trên Collections. Nó cũng chứa các phương thức cho các thuật toán khác nhau như phân loại, tìm kiếm nhị phân, v.v.

4. Sự khác biệt giữa Mảng và Bộ sưu tập là gì?

MảngBộ sưu tập
Nó có kích thước cố định và không thể thay đổi kích thước trong thời gian chạyKích thước có thể được thay đổi động và không cố định.
Nó chỉ có thể lưu trữ cùng một loại dữ liệuNó có thể lưu trữ kết hợp các giá trị kiểu dữ liệu
Nó không có các phương thức tích hợp sẵn như sắp xếp hoặc tìm kiếmNó có các phương pháp tích hợp để sắp xếp và tìm kiếm
Hiệu suất nhanhHiệu suất chậm
Hiệu quả bộ nhớ kém hơnHiệu quả bộ nhớ cao hơn
Nó không được triển khai dựa trên bất kỳ cấu trúc dữ liệu nàoMọi lớp trong Bộ sưu tập được triển khai dựa trên một số cấu trúc dữ liệu

5. Các giao diện khác nhau hiện diện trong khuôn khổ Bộ sưu tập là gì?

Giao diện bộ sưu tập: Đây là giao diện gốc của hệ thống phân cấp khuôn khổ Bộ sưu tập. Các giao diện khác có mặt trong khuôn khổ Bộ sưu tập là giao diện Bản đồ và lặp lại. Các giao diện này còn có các giao diện con vì không có triển khai trực tiếp cho giao diện Bộ sưu tập.

Giao diện Bộ sưu tập chứa Danh sách, Đặt và Giao diện hàng đợi.

Giao diện danh sách: Đây là một tập hợp các phần tử có thứ tự cho phép lưu trữ các giá trị trùng lặp.

Đặt giao diện: Đây là một tập hợp các phần tử không có thứ tự và không cho phép các giá trị trùng lặp.

Giao diện hàng đợi: Nó thực hiện hàng đợi cấu trúc dữ liệu và tuân theo khái niệm FIFO (First-In-First-Out).

Giao diện Deque: Đây là hàng đợi kết thúc kép thực hiện cả ngăn xếp và hàng đợi và do đó hỗ trợ cả FIFO và LIFO.

Giao diện bản đồ: Nó lưu trữ dữ liệu dưới dạng các cặp khóa-giá trị và chúng tôi chỉ có thể lưu trữ các khóa duy nhất.

6. Sự khác biệt giữa ArrayList và Vector là gì?

Lập danh sáchvector
ArrayList không được đồng bộ hóaVectơ được đồng bộ hóa
Nó không phải là một lớp kế thừaNó là một lớp kế thừa
Nó có thể tăng kích thước lên 50% kích thước mảngNó có thể tăng kích thước của nó lên gấp đôi
Nó không an toàn theo luồngNó an toàn theo chủ đề
Chỉ sử dụng Iterator để duyệt quaSử dụng cả Enumeration và Iterator để duyệt qua
Hiệu suất ArrayList nhanh hơnHiệu suất vectơ tương đối chậm hơn

Xem thêm

Câu hỏi phỏng vấn BankBazaar

7. Sự khác biệt giữa ArrayList và LinkedList là gì?

Lập danh sáchLinkedList
Sử dụng mảng động để lưu trữ các phần tửSử dụng Double LinkedList để lưu trữ các phần tử
Hiệu suất chậm hơnHiệu suất nhanh hơn
Nó chỉ có thể được sử dụng để triển khai Danh sáchNó có thể được sử dụng để triển khai Danh sách và Hàng đợi
Cung cấp quyền truy cập ngẫu nhiênKhông cung cấp quyền truy cập ngẫu nhiên
Chiếm ít bộ nhớ hơn vì nó chỉ lưu trữ đối tượngChiếm nhiều bộ nhớ hơn vì nó lưu trữ cả đối tượng và tham chiếu của đối tượng
get (int index) cho hiệu suất của O (1)get (int index) cho biết hiệu suất của O (n)
Hiệu suất hoạt động loại bỏ trong trường hợp xấu nhất là O (n) và trường hợp tốt nhất là O (1)Thao tác loại bỏ cho hiệu suất của O (1)
Phương thức Add cho biết hiệu suất của O (n) trong trường hợp xấu nhấtPhương thức Add cho hiệu suất của O (1)

Tìm hiểu về Map và Set trong javascript

Bài đăng này đã không được cập nhật trong 2 năm

Trong javascript, dev thường dùng nhiều thời gian vào việc quyết định kiểu cấu trúc dữ liệu chuẩn có thể giúp thao tác sau này dễ dàng hơn, tiết kiệm thời gian và làm cho code dễ hiểu hơn. Hai cấu trúc dữ liệu phổ biến để lưu trữ data là Objects và Arrays (cũng là một loại object). Dev sử dụng Objects để lưu trữ cặp key/value và Arrays để lưu trữ danh sách chỉ mục. Tuy nhiên, để mang đến cho dev sự uyển chuyển nhiều hơn, ECMAScript 2015 giới thiệu 2 loại Object mới là Map, được sắp xếp theo bộ các cặp key/value và Set, là một bộ các cặp giá trị duy nhất. trong hướng dẫn này, bạn sẽ tìm hiểu về Map và Set, làm cho chúng giống hoặc khác với Object và Array, các thuộc tính và phương thức có sẵn của chúng và ví dụ về một số cách sử dụng trong thực tế.

Tổng quan về Collections trong Java

1. Giới thiệu Java Collection Framework

Bất kì lập trình viên nào đã từng làm việc với Java hay Android có lẽ đều biết tới ArrayList – một class cực kì dễ dùng và tiện dụng. Nhưng có lẽ không nhiều người biết rằng ArrayList chỉ là một trong số rất nhiều class thuộc bộ thư viện Java Collection Framework của Java – một bộ thư viện với rất nhiều class mạnh mẽ giúp bạn đơn giản hóa các thao tác khi làm việc với tập hợp và đồ thị. Java Collection Framework (có thể gọi là nền tảng tập hợp) được xây dựng các interface đinh nghĩa các cách thao tác với tập hợp, các class cụ thể thực thi các interface và các giải thuật thông dụng thường xuyên được sử dụng với tập hợp.

Sự khác nhau giữa set và map
Java Collection Framework cung cấp cho bạn hầu như tất cả những gì bạn cần khi muốn làm việc với các tập hợp hay là đồ thị, không chỉ vậy nó còn cho phép bạn mở rộng bằng các kế thừa từ các class hay interface có sẵn để tạo ra bộ thư viện phù hợp nhất với nhu cầu của bạn. Collection framework được thiết kế với mục đích như sau:

  • Framework phải là hiệu năng cao. Sự triển khai cho các tập hợp cơ bản (các mảng động, linked list, tree và hashtable) được sử dụng với hiệu quả cao.
  • Framework phải cho phép các kiểu tập hợp khác nhau để làm việc theo một cách tương tự như nhau với độ phân hóa ở mức cao.
  • Kế thừa và/hoặc tìm hiểu với các tập hợp phải là dễ dàng. Một collections framework là một cấu trúc thống nhất để biểu diễn và thao tác các collection. Tất cả collections framework đều chứa:
  • Interface: Đây là các kiểu dữ liệu abstract mà biểu diễn collection. Interface cho phép collection được thao tác một cách độc lập theo phép biểu diễn của chúng. Trong ngôn ngữ hướng đối tượng, các interface nói chung cấu tạo nên một hierarchy.
  • Sự triển khai: ví dụ như các Class Đây là sự triển khai cụ thể của collection interface. Về bản chất, chúng là những cấu trúc dữ liệu có thể tái sử dụng.
  • Thuật toán: Đây là các phương thức thực hiện các trình tính toán hữu ích, như tìm kiếm và xếp thứ tự phân loại, trên các đối tượng mà triển khai collection interface. Các thuật toán được xem như là đa hình: đó là, cùng một phương thức có thể được sử dụng trên nhiều sự triển khai khác nhau của collection interface thích hợp.
  • Ngoài ra, framework định nghĩa một số map interfaces và class. Map lưu giữ các cặp key/value. Mặc dù các map không là collections về khái niệm, nhưng chúng hoàn toàn tương thích với collection. Để làm rõ hơn mình sẽ đi luôn vào giới thiệu tới các bạn từng thành phần chính được của Java Collection Framework.

2. Collection Interface

Collection Interface định nghĩa những phương thức cơ bản khi làm việc với tập hợp, đây là gốc cũng là nền móng để từ đó xây dựng lên cả bộ thư viện Java Collection Framework. Collection Interface được kế thừa từ Iterable Interface nên các bạn có thể dễ dàng duyệt qua từng phần tử thông qua việc sử dụng Iterator.

3. Set Interface

Set (tập hợp) là kiểu dữ liệu mà bên trong nó mỗi phần tử chỉ xuất hiện duy nhất một lần (tương tự như tập hợp trong toán học vậy) và Set Interface cung cấp các phương thức để tương tác với set. Set Interface được kế thừa từ Collection Interface nên nó cũng có đầy đủ các phương thức của Collection Interface. Một số class thực thi Set Interface thường gặp:

  • TreeSet: là 1 class thực thi giao diện Set Interface, trong đó các phần tử trong set đã được sắp xếp.
  • HashSet: là 1 class implement Set Interface, mà các phần tử được lưu trữ dưới dạng bảng băm (hash table).
  • EnumSet: là 1 class dạng set như 2 class ở trên, tuy nhiên khác với 2 class trên là các phần tử trong set là các enum chứ không phải object.

4. List Interface

List (danh sách) là cấu trúc dữ liệu tuyến tính trong đó các phần tử được sắp xếp theo một thứ tự xác định. List Interface định nghĩa các phương thức để tương tác với list cũng như các phần tử bên trong list. Tương tự như Set Interface, List Interface cũng được kế thừa và có đầy đủ các phương thức của Collection Interface.

Một số class thực thi List Interface thường sử dụng:

  • ArrayList: là 1 class dạng list được implement dựa trên mảng có kích thước thay đổi được.
  • LinkedList: là một class dạng list hoạt động trên cơ sở của cấu trúc dữ liệu danh sách liên kết đôi (double-linked list)
  • Vector: là 1 class thực thi giao diện List Interface, có cách thực lưu trữ như mảng tuy nhiên có kích thước thay đổi được, khá là tương tự với ArrayList, tuy nhiên điểm khác biệt là Vector là synchronized, hay là đồng bộ, có thể hoạt động đa luồng mà không cần gọi synchronize một cách tường minh
  • Stack: cũng là 1 class dạng list, Stack có cách hoạt động dựa trên cơ sở của cấu trúc dữ liệu ngăn xếp (stack) với kiểu vào ra LIFO (last-in-first-out hay vào sau ra trước) nổi tiếng.

5. Queue Interface

Queue (hàng đợi) là kiểu dữ liệu nổi tiếng với kiểu vào ra FIFO (first-in-first-out hay vào trước ra trước), tuy nhiên với Queue Interface thì queue không chỉ còn dừng lại ở mức đơn giản như vậy mà nó cũng cấp cho bạn các phương thức để xây dựng các queue phức tạp hơn nhiều như priority queue (queue có ưu tiên), deque (queue 2 chiều), … Và cũng giống như 2 interface trước, Queue Interface cũng kế thừa và mang đầy đủ phương thức từ Collection Interface. Một số class về Queue thường sử dụng:

  • LinkedList: chính là LinkedList mình đã nói ở phần List
  • PriorityQueue: là 1 dạng queue mà trong đó các phần tử trong queue sẽ được sắp xếp.
  • ArrayDeque: là 1 dạng deque (queue 2 chiều) được implement dựa trên mảng

6. Map Interface

Map (đồ thị/ánh xạ) là kiểu dữ liệu cho phép ta quản lý dữ liệu theo dạng cặp key-value, trong đó key là duy nhất và tương ứng với 1 key là một giá trị value. Map Interface cung cấp cho ta các phương thức để tương tác với kiểu dữ liệu như vậy. Không giống như các interface ở trên, Map Interface không kế thừa từ Collection Interface mà đây là 1 interface độc lập với các phương thức của riêng mình. Dưới đây là một số class về Map cần chú ý:

  • TreeMap: là class thực thi giao diện Map Interface với dạng cây đỏ đen (Red-Black tree) trong đó các key đã được sắp xếp. Class này cho phép thời gian thêm, sửa, xóa và tìm kiếm 1 phần tử trong Map là tương đương nhau và đều là O(log(n))
  • HashMap: là class thực thi giao diện Map Interface với các key được lưu trữ dưới dạng bảng băm, cho phép tìm kiếm nhanh O(1).
  • EnumMap: cũng là 1 Map class nữa, tuy nhiên các key trong Map lại là các enum chứ không phải object như các dạng Map class ở trên.
  • WeakHashMap: tương tự như HashMap tuy nhiên có 1 điểm khác biệt đáng chú ý là các key trong Map chỉ là các Weak reference (hay Weak key), có nghĩa là khi phần tử sẽ bị xóa khi key được giải phóng hay không còn một biến nào tham chiếu đến key nữa.

Nguồn tham khảo:

http://vietjack.com/java/collection_trong_java.jsp https://docs.oracle.com/javase/8/docs/technotes/guides/collections/overview.html http://that2u.com/java-collection-framework-phan-1-gioi-thieu-chung/ http://o7planning.org/vi/10165/huong-dan-su-dung-nen-tang-tap-hop-trong-java#a12326


Giống nhau của HashMap và HashSet

  • Cả hai cấu trúc dữ liệu không duy trì bất kỳ thứ tự cho các phần tử truyền vào.
  • Cả hai đều sử dụng phương thức hashCode () và equals () để duy trì tính duy nhất của dữ liệu.
  • Cả hai cung cấp cho hiệu suất thời gian là hằng số cho các thao tác chèn (add/ put) và loại bỏ (remove).
  • Cả hai đều không đồng bộ (non-synchronized).