Trong Java, obj.hashCode()
trả về một số giá trị. Việc sử dụng mã băm này trong lập trình là gì?
Trong Java, obj.hashCode()
trả về một số giá trị. Việc sử dụng mã băm này trong lập trình là gì?
Câu trả lời:
hashCode()
được sử dụng cho bucketing trong Hash
triển khai thích HashMap
, HashTable
, HashSet
vv
Giá trị nhận được hashCode()
được sử dụng làm số nhóm để lưu trữ các phần tử của tập hợp / bản đồ. Số nhóm này là địa chỉ của phần tử bên trong tập hợp / bản đồ.
Khi bạn làm điều contains()
đó sẽ lấy mã băm của phần tử, sau đó tìm kiếm cái xô nơi mã băm trỏ đến. Nếu tìm thấy nhiều hơn 1 phần tử trong cùng một nhóm (nhiều đối tượng có thể có cùng mã băm), thì nó sử dụng equals()
phương thức để đánh giá xem các đối tượng có bằng nhau hay không, sau đó quyết định xem contains()
có đúng hay sai hay không, hoặc quyết định xem phần tử có thể là thêm vào trong tập hợp hay không.
equals()
để đánh giá", vậy nếu chỉ có một phần tử băm khớp với phần tử được tìm thấy, nó sẽ trả về đúng trực tiếp? nhưng vì nhiều đối tượng có thể có cùng mã băm nên nó phải chạy equals()
để đánh giá xem phần tử khớp có bằng nhau hay không, nó có thể cho bạn kết quả không mong muốn, tôi có đúng không?
hashCode()
phương thức?
Từ Javadoc :
Trả về một giá trị mã băm cho các đối tượng. Phương pháp này được hỗ trợ vì lợi ích của hashtables như được cung cấp bởi
java.util.Hashtable
.Hợp đồng chung
hashCode
là:
Bất cứ khi nào nó được gọi trên cùng một đối tượng nhiều lần trong khi thực thi ứng dụng Java,
hashCode
phương thức phải luôn trả về cùng một số nguyên , miễn là không có thông tin nào được sử dụng trong các phép so sánh trên đối tượng được sửa đổi. Số nguyên này không cần nhất quán từ một thực thi của một ứng dụng đến một thực thi khác của cùng một ứng dụng.Nếu hai đối tượng bằng nhau theo
equals(Object)
phương thức, thì việc gọihashCode
phương thức trên mỗi hai đối tượng phải tạo ra kết quả số nguyên giống nhau.Người ta không cần thiết rằng nếu hai đối tượng đều không công bằng theo
equals(java.lang.Object)
phương pháp, sau đó gọi cáchashCode
phương pháp trên mỗi của hai đối tượng phải xuất trình kết quả số nguyên khác nhau. Tuy nhiên, lập trình viên cần lưu ý rằng việc tạo ra các kết quả số nguyên riêng biệt cho các đối tượng không bằng nhau có thể cải thiện hiệu suất của hashtables.Nhiều như vậy là thực tế hợp lý, phương thức hashCode được xác định bởi lớp Object sẽ trả về các số nguyên riêng biệt cho các đối tượng riêng biệt. (Điều này thường được thực hiện bằng cách chuyển đổi địa chỉ bên trong của đối tượng thành số nguyên , nhưng kỹ thuật lập trình Java này không được yêu cầu bởi ngôn ngữ lập trình Java.)
Giá trị được trả về bởi
hashCode()
mã băm của đối tượng, là địa chỉ bộ nhớ của đối tượng ở dạng thập lục phân.Theo định nghĩa, nếu hai đối tượng bằng nhau, mã băm của chúng cũng phải bằng nhau. Nếu bạn ghi đè
equals()
phương thức, bạn thay đổi cách hai đối tượng được đánh đồng và việc triển khai đối tượnghashCode()
không còn hợp lệ. Do đó, nếu bạn ghi đè phương thức equals (), bạn cũng phải ghi đèhashCode()
phương thức.
Câu trả lời này là từ tài liệu hướng dẫn chính thức của java SE 8
hashCode()
là một hàm lấy một đối tượng và xuất ra một giá trị số. Mã băm cho một đối tượng luôn giống nhau nếu đối tượng không thay đổi.
Chức năng thích HashMap
, HashTable
, HashSet
, vv mà cần phải đối tượng cửa hàng sẽ sử dụng một hashCode
modulo kích thước của mảng nội bộ của họ để lựa chọn những gì "vị trí nhớ" (tức là mảng position) để lưu trữ các đối tượng.
Có một số trường hợp va chạm có thể xảy ra (hai đối tượng kết thúc với cùng một mã băm), và tất nhiên, điều đó cần phải được giải quyết cẩn thận.
Mặc dù hashcode không làm gì với logic kinh doanh của bạn, chúng tôi phải chăm sóc nó trong hầu hết các trường hợp. Bởi vì khi đối tượng của bạn được đưa vào một thùng chứa dựa trên hàm băm (Hashset, HashMap ...), vùng chứa sẽ đặt / lấy mã băm của phần tử.
Mã băm là một số được tạo từ bất kỳ đối tượng nào.
Đây là những gì cho phép các đối tượng được lưu trữ / truy xuất nhanh chóng trong Hashtable.
Hãy tưởng tượng ví dụ đơn giản sau :
Trên bàn trước mặt bạn. bạn có chín hộp, mỗi hộp được đánh số từ 1 đến 9. Bạn cũng có một đống đồ vật cực kỳ khác nhau để lưu trữ trong các hộp này, nhưng một khi chúng ở trong đó bạn cần có thể tìm thấy chúng càng nhanh càng tốt.
Những gì bạn cần là một cách quyết định ngay lập tức hộp nào bạn đã đặt từng đối tượng. Nó hoạt động giống như một chỉ mục. bạn quyết định tìm bắp cải để tìm hộp bắp cải nằm trong hộp nào, sau đó đi thẳng đến hộp đó để lấy nó.
Bây giờ hãy tưởng tượng rằng bạn không muốn làm phiền với chỉ mục, bạn muốn có thể tìm ra ngay lập tức từ đối tượng mà nó sống trong đó.
Trong ví dụ này, chúng ta hãy sử dụng một cách thực sự đơn giản để làm điều này - số lượng chữ cái trong tên của đối tượng. Vì vậy, bắp cải đi vào hộp 7, hạt đậu đi vào hộp 3, tên lửa ở hộp 6, banjo trong hộp 5 và cứ thế.
Thế còn tê giác thì sao? Nó có 10 ký tự, vì vậy chúng tôi sẽ thay đổi thuật toán của chúng tôi một chút và "bọc xung quanh" để các đối tượng 10 chữ cái đi vào hộp 1, 11 chữ cái trong hộp 2, v.v. Điều đó sẽ bao gồm bất kỳ đối tượng.
Đôi khi một hộp sẽ có nhiều hơn một vật thể trong đó, nhưng nếu bạn đang tìm kiếm một tên lửa, thì việc so sánh đậu phộng và tên lửa vẫn nhanh hơn nhiều so với việc kiểm tra cả đống cải bắp, đậu Hà Lan, banjos và tê giác.
Đó là mã băm. Một cách để lấy một số từ một đối tượng để nó có thể được lưu trữ trong Hashtable. Trong Java, mã băm có thể là bất kỳ số nguyên nào và mỗi loại đối tượng chịu trách nhiệm tạo mã riêng. Tra cứu phương thức "hashCode" của Object.
Nguồn - tại đây
Một trong những cách sử dụng hashCode () là xây dựng cơ chế Catching . Nhìn vào ví dụ này:
class Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
if (x != point.x) return false;
return y == point.y;
}
@Override
public int hashCode()
{
int result = x;
result = 31 * result + y;
return result;
}
class Line
{
public Point start, end;
public Line(Point start, Point end)
{
this.start = start;
this.end = end;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Line line = (Line) o;
if (!start.equals(line.start)) return false;
return end.equals(line.end);
}
@Override
public int hashCode()
{
int result = start.hashCode();
result = 31 * result + end.hashCode();
return result;
}
}
class LineToPointAdapter implements Iterable<Point>
{
private static int count = 0;
private static Map<Integer, List<Point>> cache = new HashMap<>();
private int hash;
public LineToPointAdapter(Line line)
{
hash = line.hashCode();
if (cache.get(hash) != null) return; // we already have it
System.out.println(
String.format("%d: Generating points for line [%d,%d]-[%d,%d] (no caching)",
++count, line.start.x, line.start.y, line.end.x, line.end.y));
}
hashCode()
là một mã duy nhất được tạo bởi JVM cho mỗi lần tạo đối tượng.
Chúng tôi sử dụng hashCode()
để thực hiện một số thao tác trên thuật toán băm liên quan như băm, Hashmap, v.v.
Những lợi thế của việc hashCode()
làm cho hoạt động tìm kiếm trở nên dễ dàng bởi vì khi chúng ta tìm kiếm một đối tượng có mã duy nhất, nó sẽ giúp tìm ra đối tượng đó.
Nhưng chúng ta không thể nói hashCode()
là địa chỉ của một đối tượng. Nó là một mã duy nhất được tạo bởi JVM cho mọi đối tượng.
Đó là lý do tại sao ngày nay thuật toán băm là thuật toán tìm kiếm phổ biến nhất.