Chuyển đến nội dung chính

Cách HashMap (Dictionary) hoạt động trong Java

Cách HashMap (Dictionary) hoạt động trong Java

HashMap (hay Dictionary) là một key-value data structure quan trọng. Các dev nhà ta chắc hẳn ai cũng đã từng dùng HashMap để giải quyết các bài toán hằng ngày rồi. Vậy liệu các bạn có đặt câu hỏi HashMap hoạt động như thế nào? Làm sao làm việc với HashMap lại nhanh? Đây cũng là câu hỏi thường xuyên được hỏi trong các buổi phỏng vấn Software Engineering
  • HashMap hoạt động như thế nào? Bạn có thể tự xây dựng một HashMap cho riêng mình không?
  • Hash Collision là gì? Làm sao để giải quyết Hash Collision?
  • Những gì cần lưu ý khi sử dụng HashMap?

HashMap

HashMap là key-value data structure cho phép chúng ta lưu trữ data và chi phí cho các thao tác cơ bản (put, get, delete) chỉ là O(1).

HashMap hoạt động như thế nào?

HashMap hoạt động dựa trên nguyên lý hashing (Hashing principle). Khi chúng ta gọi hàm put(key, value) hay get(key) thì về cơ bản HashMap sẽ làm 2 bước sau

Tìm bucket

Bucket là nơi lưu trữ các key có hash gần như nhau, bucket được lưu trong một array nên chi phí truy xuất chỉ là O(1), Từ key, làm sao ta có thể tìm được index của bucket? Câu trả lời đơn giản là dùng giá trị hash của key và một công thức ánh xạ giá trị hash này với index trong array (index = hash % n chẳng hạn), thao tác này cũng tốn O(1) luôn.

Thao tác trên bucket:

Tìm xem key có thực sự tồn tại trong bucket hay không bằng hàm Equals(). Trong trường hợp có nhiều key có giá trị hash như nhau, thì một bucket có thể có nhiều item(key-value), việc của ta khi đó là duyệt qua bucket và kiểm tra xem có giá trị key trong bucket không.
Có thể thấy, tốc độ của HashMap không thực sự là O(1), trong trường hợp hàm hash tệ, dẫn đến tất cả các key-value đều nằm trong cùng 1 bucket. Tùy thuộc vào cấu trúc dữ liệu của bucket mà kết quả có thể khác nhau. Java 7 dùng Singlely Linked-List (O(n)), còn Java 8 sử dụng Red-Black Tree O(logn) để implement bucket.

Làm sao để xây dựng một HashMap?

hashmap
Xây dựng một HashMap không quá phức tạp, bạn có thể đọc thêm source code của ngôn ngữ bạn đang sử dụng để hiểu thêm. Nhưng về cơ bản sẽ có những vẫn đề cơ bản sau.
  • Bucket table: internal array chứa các bucket, array này có size xác định và sẽ được mở rộng khi số lượng phần tử trong HashMap đạt ngưỡng.
  • Bucket: nơi lưu trữ các key-value có giá trị gần như nhau, bucket có thể là Linked-List hoặc Tree.
  • put(key, value) và get(key): dùng dùng giá trị hash của key để tìm ra index của bucket, sau đó dùng equal để kiểm tra key có tồn tại trong bucket hay không.
  • rehashing: Size của bucket table sẽ được mở rộng, các phần tử sẽ được rearrange lại khi số lượng phần tử của Hashmap đến một ngưỡng nào đó (load factor, trong Java, giá trị này bằng 0.75 * size).

Hash Collision là gì?

Hash Collision là trường hợp hàm hash implement tệ, dẫn đến nhiều key-value nằm trong cùng một bucket. Tùy thuộc vào implement của bucket mà chi phí có thế khác nhau.
Ngoài ra, khi số lượng item tăng lên, khả năng xảy ra hash collision cao hơn thì ta có thể tăng size của bucket table lên, rehashing lại toàn HashMap. Trong Java, default load factor = 0.75, điều này có nghĩa số lượng bucket luôn lớn hơn số lượng item, Developer của Java hy vọng rằng mỗi bucket chỉ có một item.

Những gì cần lưu ý khi sử dụng HashMap

HashCode và Equals: Khi implement Equals thì phải implement HashCode, 2 object bằng nhau thì hashcode cũng phải bằng nhau!
Ngoài ra, hàm hash cũng cần phải implement sao cho có thể phân tán key-value đều cho các bucket (Best practive các bạn có thể tham khảo cuốn Effective Java, Item 9)
Init capacity và rehashing: rehashing có chi phí lớn, hãy tính toán và khởi tạo HashMap với kích thước hợp lý.

Nhận xét

Bài đăng phổ biến từ blog này

Entry Test của FPT

IQ - Kiểm tra tư duy logic (8/20) - GMAT- Kiểm tra khả năng tính toán trong thời gian ngắn (8/20) - Tiếng Anh (18-> 25/50) - Các bài thi chuyên môn - FE (8/20) IQ: lên mạng tìm "IQ test" là ra đầy. + GMAT: Những câu trắc nghiệm tính toán đơn giản kiểu như sau:  1 . Một shop thời trang sale off quần jeans 15 %, quần jeans giá 450 $, người mua đưa 500 $, hỏi cashier trả lại bao nhiêu $ tiền thừa.? 2 . 100 % là 180 , vậy 150 là bao nhiêu %? Tiếng anh: Cỡ như thi TOEIC thôi. Chuyên môn: Mobile thì trắc nghiệm Java. Qúa trình tuyển như sau :v Lần 1: Test IQ, Tiếng Anh( mình làm í ẹ khoảng 50% mà vẫn được) , Java Lân 2: được gọi điện lên :)) + Gioi thiệu bản thân + Họ chỉ hỏi các câu căn bản như: -. OOP: là gì, 4 tính chất, ví dụ, khác nhau giữa interface và abstract - CODE: hầu toàn các bài toán vòng for :)) , cẩn thận mấy câu kế thừa. SQL (distinct, view, function, cursor, store procedure, ...v.v.), nhớ có câu cộng 2 số int không dùng biến đệm hơi khoai haha + Nói ch...

Java: Java Package-Thư viện trong Java

Giới thiệu về Package Các bạn mới học lập trình Java thường không dể ý tới package vì các bạn toàn tạo file .java vào cùng 1 chỗ, không cần sắp xếp, không cần quản lý truy nhập. Nhưng để tăng kỹ năng lập trình với Java, các bạn cần phải tìm hiểu về package trong Java. Các bạn có thể tham khảo định nghĩa sau: Package được dùng để đóng gói các lớp trong chương trình lại với nhau thành một khối. Đây là cách tốt nhất để lưu trữ các lớp gần giống nhau hoặc có cùng một module thành một khối thống nhất – để đáp ứng 1 khối chức năng. Từ đây mình sẽ giới thiệu thêm với các bạn các câu lệnh nhâp khẩu,nó có định dạng như sau : Định dạng :  import javaPackageNameImport;    Nó giống như khai báo thư viện ở các ngôn ngữ lập trình khác.Như vậy,chỉ khi các bạn nhập khẩu chúng,các bạn mới có thể sử dụng thư viện mà chúng cung cấp cho ta. VD :    import java.util.Date;   import java.text.SimpleDateFormat; Lưu ý : -Các câu lệnh nhập khẩu rất nhiều và...

phỏng vấn Embedded C và C++?

Có vài điểm rất nhỏ, các bạn không để ý có thể dẫn đến bất lợi (nếu không muốn nói là rớt) ở vòng hồ sơ hoặc khi đi phỏng vấn. Mình liệt kê rất cụ thể ra những chuyện mình đã thấy qua nhiều lần (người thật, việc thật), hy vọng cho các bạn thêm kinh nghiệm. Lưu ý: Những chuyện này rất chủ quan, có thể chỉ đúng trong môi trường của mình và hoàn toàn không đúng trong môi trường khác. Gửi email CV đến không có Cover Letter, chỉ đính kèm mỗi file PDF là cái CV. CV ghi : tiếng Anh: Trung Bình, C: Trung Bình,... nhưng bên dưới lại ghi ưu điểm_:  là người ham học hỏi... CV bằng tiếng Việt và lại viết sai chính tả tiếng Việt. CV ghi quá nhiều về các hoạt động tình nguyện, hiến máu, blah blah... nhưng phần kĩ thuật lại có 3 dòng thôi. Mặc đồ thể dục của trường và đi dép lê đến PV. Đến muộn PV (em ấy bảo bị kẹt xe). Đưa yêu cầu, em ấy không hiểu đề nhưng ngại không dám hỏi lại, dẫn đến viết hoàn toàn sai. Hỏi ngay câu căn bản đầu tiên em ấy đã nói không biết và  đổ do trường kh...