2012-01-20 26 views
9

Tôi đã thực hiện một tập hợp vector để tránh đập GC với các cấp phát lặp và giống như (bạn nhận được một/miễn phí mới cho cả tham chiếu đã đặt và bộ lặp cho mỗi lần truyền của giá trị hoặc khóa của HashSet)làm thế nào để tôi nhận được một ID duy nhất cho mỗi đối tượng trong Java?

được cho là phương thức Object.hashCode() là một id duy nhất cho mỗi đối tượng. (sẽ thất bại cho một phiên bản 64 bit?)

Nhưng trong mọi trường hợp, nó có thể ghi đè và do đó không được bảo đảm duy nhất, cũng không phải duy nhất cho mỗi cá thể đối tượng.

Nếu tôi muốn tạo một "ObjectSet" làm thế nào để tôi nhận được một ID duy nhất được đảm bảo cho từng trường hợp của một đối tượng?

Tôi chỉ tìm thấy câu trả lời này: câu trả lời.

How to get the unique ID of an object which overrides hashCode()?

+0

Câu hỏi không rõ ràng. Chính xác những gì bạn đang cố gắng để đạt được và tại sao nó cần một ID duy nhất cho mỗi đối tượng? – Paolo

+1

Mô tả về những gì bạn đang cố gắng làm là * thực sự * mơ hồ. Bạn có thể cung cấp thêm thông tin? Có thể có một cách tốt hơn để đạt được mục tiêu lớn hơn của bạn. –

+0

Tôi thấy câu trả lời/questin này trả lời những gì tôi muốn. http: // stackoverflow.com/questions/909843/java-how-to-get-the-unique-id-of-an-đối tượng-ghi đè-hashcode – peterk

Trả lời

5

java.lang.System.identityHashCode(obj); sẽ thực hiện việc này cho bạn, nếu bạn thực sự cần và hiểu hậu quả. Nó nhận được mã băm nhận dạng, ngay cả khi phương pháp cung cấp mã băm đã bị ghi đè.

+13

Thậm chí nếu điều này đã được vài tháng tuổi, cần lưu ý rằng 'System.identityHashCode (Object)' không ** không ** cần phải phân biệt đối tượng riêng biệt (như đã được nêu trong các câu trả lời và nhận xét khác)! – siegi

+1

Giải pháp được cung cấp (có một số giải thích và chi tiết): http://stackoverflow.com/questions/909843/java-how-to-get-the-unique-id-of-an-object-which-overrides-hashcode – Benj

+0

identityHashCode() trả về kết quả của phương thức hashCode() được định nghĩa trong Object. trong javadoc cho phương thức như vậy, nó nói: "Nhiều như là thực tế hợp lý, phương thức hashCode được định nghĩa bởi lớp Object 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ỉ nội bộ của đối tượng thành một số nguyên, nhưng kỹ thuật triển khai này không được yêu cầu bởi ngôn ngữ lập trình JavaTM.) " –

5

Không, đó không phải là cách hashCode() công trình. Giá trị trả về không nhất thiết phải là duy nhất. Hợp đồng chính xác được viết ra trong số documentation.

Ngoài ra,

được cho là phương pháp Object.hashCode() là một id duy nhất cho mỗi đối tượng

là không đúng sự thật. Để trích dẫn tài liệu:

Thực tế là hợp lý, phương pháp hashCode được xác định bởi lớp Object trả về các số nguyên riêng biệt cho các đối tượng riêng biệt.

+0

Tôi biết - đó là lý do tôi đặt câu hỏi. – peterk

3

Cố gắng làm tốt hơn GC GC có vẻ như tối ưu hóa sớm với tôi.

GC đã được điều chỉnh để xử lý các đối tượng sống ngắn. Nếu bạn gặp vấn đề về hiệu suất với GC, bạn phải help the GC, không triển khai lại (IMNSHO)

+1

Tôi rất thích nó nếu GC xác định thời gian thực có sẵn như là một plugin cho máy ảo Java chung nơi tôi có thể đảm bảo GC sẽ tiêu thụ nhiều hơn 2 mili giây trong mỗi khung của vòng lặp mô phỏng 60hz. Giảm phân bổ và miễn phí làm giảm số lượng gian hàng GC định kỳ không thể tránh khỏi. – peterk

32

Giải pháp đơn giản nhất là thêm trường vào đối tượng. Đây là giải pháp nhanh nhất và hiệu quả nhất và tránh bất kỳ vấn đề nào của các đối tượng không được dọn sạch.

abstract Ided { 
    static final AtomicLong NEXT_ID = new AtomicLong(0); 
    final long id = NEXT_ID.getAndIncrement(); 

    public long getId() { 
     return id; 
    } 
} 

Nếu bạn không thể sửa đổi các lớp, bạn có thể sử dụng một IdentityHashMap như @ glowcoder của giải pháp xóa.

private static final Map<Object, Long> registry = new IdentityHashMap<Object, Long>(); 
private static long nextId = 0; 

public static long idFor(Object o) { 
    Long l = registry.get(o); 
    if (l == null) 
     registry.put(o, l = nextId++); 
    return l; 
} 

public static void remove(Object o) { 
    registry.remove(o); 
} 
+0

sẽ là mã ở trên, nơi bạn thêm một trường vào đối tượng đảm bảo một id duy nhất cho mỗi thể hiện được tạo ra khi đối mặt với các đối tượng được tạo ra từ nhiều luồng cùng một lúc? – Geek

+0

@Geek Nó sẽ nếu bạn sử dụng AtomicLong. –

Các vấn đề liên quan