2010-09-27 14 views
7

Đây là một câu hỏi lập trình tầm thường. Tôi không phải là một chuyên gia về Java. Nói rằng tôi sử dụng các đối tượng của Công ty lớp tùy chỉnh và nhân viên, một cách tương tự với những gì nhiều RDBMS ví dụ làm:Người ta có thể kiểm soát danh tính của các đối tượng trong Java hay không và nếu có thì làm cách nào?

class Employee 
{ 
    Company company; 
} 

class Company 
{ 
    String name; 
} 

tôi cần phải đảm bảo rằng khác nhau Company đối tượng có tên duy nhất - tức là không có hai đối tượng đó có thể có cùng một tên, bởi vì từ quan điểm của tôi nó không có ý nghĩa, và cũng chỉ đơn giản là ăn bộ nhớ - nếu hai nhân viên làm việc tại IBM, sau đó có một đối tượng Company duy nhất với name, khoảng thời gian đó.

Suy nghĩ của tôi bây giờ đi cùng với việc tạo một đối tượng riêng tư - để cho công việc phân bổ đối tượng Công ty với tên tùy ý được ủy nhiệm cho một phương thức đáng tin cậy - giả sử sẽ từ chối mọi nỗ lực tạo đối tượng đã tồn tại hoặc trả lại một đối tượng hiện có hoặc mới (tạo một đối tượng nếu cần).

Vấn đề là, tôi không chắc chắn cách thực hiện điều này một cách trang nhã. Một điều mà sẽ tốt đẹp là không phải thực hiện tra cứu O(n) mỗi khi một đối tượng Company có tên được yêu cầu - vì vậy có thể bản đồ băm hoặc cây nhị phân có tiện lợi cho tôi không? Tôi cũng muốn ghi đè cách thức các đối tượng Company được xác định - dẫn tôi đến điều này: tôi sẽ ghi đè các phương pháp Object.equals và/hoặc Object.hashCode?

+0

Bạn có chắc chắn rằng bạn nên quan tâm đến việc sử dụng bộ nhớ thừa? Bạn sẽ phải trả tiền để theo dõi tất cả các công ty bằng cách nào đó, và nó sẽ chi phí bạn (có lẽ trong CPU). Đảm bảo rằng tối ưu hóa của bạn không sớm. – nojo

+0

Điều này không nhất thiết phải là quá nhiều cho việc tối ưu hóa, vì nó là vì tầm quan trọng của ràng buộc mà nên tránh hai đối tượng 'Công ty' có cùng tên. Bằng cách đó, nếu, nói rằng công ty tham chiếu bởi N nhân viên thay đổi tên, tôi chỉ phải thực sự làm điều đó cho một đối tượng 'Company'. Những thứ như thế. – amn

Trả lời

4

Bạn có thể ghi đè equalshashCode và lưu trữ chúng trong HashMap hoặc HashSet.

+0

bạn sẽ tìm kiếm chúng bằng cách nào? –

+0

@Michael: xem mẫu cân nhắc được đề cập bên dưới. – aperkins

+0

@Michael Ý tưởng cơ bản của tôi là nó sẽ cho phép tất cả các loại tập quán có thể là tự nhiên, như 'map.get (company)' hoặc 'set.contains (company)'. –

8

Hãy xem mô hình cân bằng.

gì tôi sẽ làm là một cái gì đó như:

// incomplete, but you get the idea hopefully 
CompanyFactory 
{ 
    private Map<String, Company> companies; 

    public getCompany(final String name) 
    { 
     Company company; 

     company = compaines.get(name); 

     if(company == null) 
     { 
      company = new Company(name); 
      companies.put(name, company); 
     } 

     return (company); 
    } 
} 
+0

+1 - Đây là vấn đề chính xác mà mô hình cân được thiết kế để giải quyết. :) – aperkins

+0

Vâng, đó là những gì tôi bắt đầu làm. Tuy nhiên, tôi quan tâm đến các tham chiếu đến các đối tượng của Công ty - có vẻ như bản đồ này, mặc dù hữu ích ở đây, sẽ giữ lại các tham chiếu đến tất cả các đối tượng Công ty đã từng tạo, mặc dù có thể không còn các tham chiếu "tốt" nữa. Tôi nghĩ về một WeakHashMap, nhưng yếu đề cập đến các phím, không phải là giá trị: '- ( – amn

+0

Tôi tin rằng khi khóa được lấy ra từ WeakHashMap giá trị cũng được loại bỏ, và do đó đủ điều kiện để thu gom rác thải. – TofuBeer

1

Một điều mà sẽ được tốt đẹp không phải là phải làm một O (n) tra cứu mỗi khi một đối tượng công ty với một tên là yêu cầu - vì vậy có thể một bản đồ băm hoặc một cây nhị phân có sẵn cho tiện ích của tôi?

Điều đó nghe có vẻ đúng, có.

Tôi cũng muốn ghi đè lên cách các đối tượng công ty được xác định - dẫn tôi như thế này: Tôi sẽ trọng Object.equals và/hoặc phương pháp Object.hashCode?

Nếu bạn đảm bảo rằng không bao giờ có hai trường hợp có cùng giá trị khóa, bạn thực sự không phải làm điều đó.

1

Khi tôi muốn tạo bộ sưu tập các đối tượng có thể được xem theo tên duy nhất, tôi lưu trữ Map của chuỗi (tên) vào đối tượng. Sau đó tôi có thể tra cứu đối tượng liên quan đến tên.

Nói đúng, bạn không cần phải chạm vào equals()hashCode() để làm điều đó, vì bạn không lưu trữ các đối tượng của mình làm khóa.Việc thực hiện equals() và hashCode() một cách chính xác có thể khó khăn để có được quyền, và các phím trong một bản đồ thực hiện như HashMap (có thể cung cấp cho bạn tra cứu hiệu quả) là nhạy cảm với các phương pháp này. Sử dụng lớp hiện có (và không thay đổi quan trọng) lớp String làm khóa giúp bạn có được chức năng tra cứu này ngay.


Cập nhật: Nếu bạn làm cho nhà xây dựng của mình riêng tư, như bạn đã đề cập, bạn có thể ngăn việc tạo trường hợp Công ty mới. Cung cấp một số phương pháp tạo trường hợp Công ty khác (Factory pattern) cho phép bạn đảm bảo rằng các phiên bản Công ty mới chỉ thực sự mới nếu chúng chưa được lưu trữ theo tên, nếu không thì phiên bản hiện tại của tên đã cho sẽ được trả về (ví dụ: Singleton)

+0

Thực ra, việc lưu trữ một String là khóa không đủ toán học. Đó là toán học có thể cho 2 chuỗi khác nhau để băm với cùng một giá trị. –

+5

... đặt chúng trong cùng một nhóm, và phương thức String equals() tiếp quản để đảm bảo tính duy nhất ...? – Brabster

+0

@ John Thực tế là đủ. – EJP

0

Nếu tên của đối tượng có thể thay đổi theo thời gian, hãy xem xét bao gồm ID duy nhất được tạo cho mỗi đối tượng. Ánh xạ của bạn sẽ từ tên thành ID duy nhất, sau đó từ ID duy nhất đến đối tượng thực tế.

Nhân tiện, nếu tất cả các đối tượng đã biết trong thời gian biên dịch, bạn có thể sử dụng Enum.