2009-03-11 24 views
6

Tôi có hai loại đối tượng trong ứng dụng của tôi, nơi mọi đối tượng của một loại có chính xác một đối tượng tương ứng của loại khác.Bất kỳ bất lợi nào khi sử dụng các đối tượng tùy ý như các phím Bản đồ trong Java?

Lựa chọn hiển nhiên để theo dõi mối quan hệ này là Map<type1, type2>, như HashMap. Nhưng bằng cách nào đó, tôi nghi ngờ. Tôi có thể sử dụng một đối tượng làm chìa khóa trong Bản đồ, chuyển nó đi, có nó ngồi trong một bộ sưu tập khác, và lấy đối tác của nó từ Bản đồ bất cứ lúc nào không?

Sau khi một đối tượng được tạo, tất cả những gì tôi chuyển qua là một số nhận dạng, đúng không? Vì vậy, có lẽ không có vấn đề ở đó. Nếu tôi serialize và deserialize khóa thì sao?

Bất kỳ cảnh báo nào khác? Tôi có nên sử dụng cái gì khác để tương quan các cặp đối tượng, giống như một số tôi tạo ra bản thân mình?

Trả lời

22
  1. Nhu cầu quan trọng để thực hiện .equals().hashCode() đúng
  2. Chìa khóa phải không được thay đổi trong bất kỳ cách nào mà thay đổi nó .hashCode() giá trị khi nó được sử dụng như là chìa khóa
  3. Lý tưởng nhất là bất kỳ đối tượng sử dụng như một chìa khóa trong một số HashMap nên không thay đổi. Điều này sẽ tự động đảm bảo rằng 2. luôn luôn đúng.
  4. Các đối tượng khác có thể được GC có thể được giữ xung quanh khi chúng được sử dụng làm khóa và/hoặc giá trị.
0

Bất kỳ đối tượng nào cũng có thể là khóa bản đồ. Điều quan trọng ở đây là đảm bảo rằng bạn ghi đè .equals() và .hashCode() cho bất kỳ đối tượng nào sẽ được sử dụng làm khóa bản đồ.

Lý do bạn làm điều này là nếu bạn không làm như vậy, bằng sẽ được hiểu là bình đẳng đối tượng và cách duy nhất bạn có thể tìm thấy khóa bản đồ "bằng" là có quyền xử lý đối tượng gốc chinh no.

Bạn ghi đè mã băm vì mã này cần nhất quán với bằng. Điều này là để các đối tượng mà bạn đã định nghĩa bằng hash giống hệt nhau.

0

Điểm lỗi là hàm băm mã và bằng. Nếu chúng không tạo ra các giá trị trả về phù hợp và phù hợp, Bản đồ sẽ hoạt động lạ lùng. Effective Java có một phần toàn bộ trên chúng và được đánh giá cao, rất khuyến khích.

7

Tôi có hai loại đối tượng trong ứng dụng của tôi, nơi tất cả các đối tượng của một loại có chính xác một tương ứng đối tượng của loại khác.

Điều này thực sự giống như mối quan hệ có và do đó có thể được triển khai bằng thuộc tính đơn giản.

+0

Tôi đồng ý. Tuy nhiên, phần còn lại của câu hỏi vẫn có thể hữu ích cho người khác. (hoặc thậm chí cho @OP nếu đó không phải là một thay thế cho một số lý do) –

+0

@saua Tôi đồng ý với bạn. Tôi chỉ mặc dù tôi chỉ ra khả năng áp dụng các thuộc tính trong bối cảnh cụ thể này. –

1

Bạn có thể sử dụng Bản đồ chuẩn, nhưng làm như vậy bạn sẽ giữ tham chiếu mạnh mẽ cho các đối tượng của mình trong Bản đồ. Nếu đối tượng của bạn được tham chiếu trong cấu trúc khác và bạn cần Bản đồ chỉ để liên kết chúng lại với nhau, hãy xem xét sử dụng WeakHashMap.

Và BTW bạn không phải ghi đè bằng và hashCode trừ khi bạn phải xem xét một số trường hợp của một đối tượng bằng nhau ...

1

Tôi có thể sử dụng một đối tượng làm chìa khóa trong Bản đồ, chuyển nó vào, cũng có thể ngồi trong bộ sưu tập khác và truy xuất đối tác của nó từ Bản đồ bất kỳ lúc nào không?

Vâng, không sao cả.

Sau khi đối tượng được tạo, tất cả những gì tôi chuyển qua là một số nhận dạng, đúng không? Vì vậy, có lẽ không có vấn đề ở đó. Nếu tôi serialize và deserialize khóa thì sao?

Đúng vậy, bạn chỉ chuyển một tham chiếu xung quanh - tất cả chúng sẽ trỏ đến cùng một đối tượng thực tế. Nếu bạn serialize hoặc deserialize đối tượng, điều đó sẽ tạo một đối tượng mới. Tuy nhiên, nếu đối tượng của bạn thực hiện equals và hashCode đúng cách, bạn vẫn có thể sử dụng đối tượng deserialized mới để lấy các mục từ bản đồ.

Bất kỳ cảnh báo nào khác? Tôi có nên sử dụng cái gì khác để tương quan các cặp đối tượng, giống như một số tôi tạo ra bản thân mình?

Đối với Caveats, có, bạn không thể thay đổi bất cứ điều gì có thể làm cho hashCode của đối tượng thay đổi khi đối tượng nằm trong Bản đồ.

3

Nó phụ thuộc vào việc thực hiện bản đồ bạn chọn:

  • HashMap sử dụng equals()hashCode(). Theo mặc định (trong Object) đây là dựa trên danh tính đối tượng, mà sẽ làm việc OK trừ khi bạn serialize/deserialize. Với việc thực hiện đúng equals() và hashCode() dựa trên nội dung của đối tượng, bạn sẽ không có vấn đề gì, miễn là bạn không sửa đổi nó trong khi nó là một khóa trong bản đồ băm.

  • Bản đồ cây sử dụng compareTo(). Không có triển khai mặc định, vì vậy bạn cần phải cung cấp. Các giới hạn tương tự cũng áp dụng như khi triển khai hashCode() và equals() ở trên.

0

Bạn có thể xem xét Bộ sưu tập của Google là BiMap.

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