2010-03-25 39 views
5

Trong mã java của tôi, tôi thường kết thúc với một số Map<String,Map<String,foo>> hoặc Map<String,List<String>> và sau đó tôi gặp khó khăn khi nhớ Chuỗi nào là khóa nào. Tôi nhận xét tuyên bố với //Map<capabiltyId,Map<groupId,foo>> hoặc //Map<groupId,List<capabilityId>, nhưng đó không phải là giải pháp tốt nhất. Nếu Chuỗi không phải là cuối cùng, tôi sẽ tạo các lớp mới CapabilityId extends StringGroupId extends String, nhưng tôi không thể. Có cách nào tốt hơn để theo dõi điều nào là chìa khóa và có thể có trình biên dịch thực thi nó?An toàn loại tốt hơn trong bộ sưu tập Java

+0

Bạn có thể sử dụng enum thay vì Chuỗi không? Điều đó có thể hữu ích khi bạn có các khóa được xác định rõ. – Carl

Trả lời

7

Thay vì có CapabilityId, hãy mở rộng String, CapabilityId có thể bao gồm trường String được gọi là "id"; sau đó, Map của bạn có thể được định nghĩa là Map<CapabilityId, Map<GroupId, Foo>> và bạn có thể nhận được tại các trường ID riêng lẻ thông qua một số getId() trên các lớp chính của bạn.

Tôi không chắc chắn tôi sẽ làm được điều này bản thân mình, nhưng nếu tôi đã làm, điều này có lẽ những gì tôi muốn làm.

Bạn có thể giới hạn sự lộn xộn bằng cách có lớp abstract GenericId với trường id và phương pháp getId() và có CapabilityIdGroupId kế thừa từ đó.

+0

Đó là một nhận xét rất hợp với Lincoln. –

+0

Tôi thừa nhận tôi đã đi cho Jerry Pournelle "Nếu bạn cần điều này, bạn cần nó xấu", nhưng ngược lại. –

+0

Đây chính xác là những gì tôi đã làm hôm qua để theo dõi rò rỉ bộ nhớ; thay vì 150m đối tượng String tôi có thể ngay lập tức phát hiện ra bản đồ nào không bị xóa bằng cách xem có bao nhiêu đối tượng nnnnKey đang được tạo. – rhu

9

chuỗi Bọc trong wrapper-lớp học nếu bạn muốn:

class GroupId implements Comparable { 
    private String groupId; 

    public GroupId (String groupId) { 
     this.groupId = groupId; 
    } 
    ... 
} 

Map<GroupId, List<CapabilityId>> m = ... 
+0

Tại sao thực hiện So sánh? –

3

Tạo một lớp ID mà bạn có thể phân lớp, và trong đó bao gồm một lĩnh vực String và triển khai của equals()hashCode() mà sử dụng lĩnh vực đó.

0

Thêm vào câu trả lời khác:

Wrap nó.

Đó không chỉ là giải pháp cho vấn đề của bạn mà là một ý tưởng hay nói chung, tức là tránh các thông số đơn giản . Mã của bạn sẽ đạt được khả năng đọc, sự tỉnh táo và bảo trì. Bạn có thể thêm tất cả các loại thuộc tính đẹp cho nó, ví dụ: khai báo nó @Immutable. Khi bạn phát hiện ra nó theo cách này là tốt hơn để nhớ và kiểm soát. Bạn sở hữu lớp và có thể làm bất cứ điều gì bạn thích với nó.

2

Tôi sẽ đặt tất cả trong một lớp và sử dụng tên trường/phương pháp/đối số hợp lý.

public class GroupCapabilities { 
    private Map<String, Map<String, Group>> groupCapabilities; 

    public void addGroup(String capabilityId, Group group) { 
     Map<String, Group> groups = groupCapabilities.get(capabilityId); 
     if (groups = null) { 
      groups = new HashMap<String, Group>(); 
      groupCapabilities.put(capabilityId, group); 
     } 
     groups.put(group.getId(), group); 
    } 

    public Map<String, Group> getGroups(String capabilityId) { 
     return groupCapabilities.get(capabilityId); 
    } 

    public Group getGroup(String capabilityId, String groupId) { 
     Map<String, Group> groups = groupCapabilities.get(capabilityId); 
     return (groups != null) ? groups.get(groupId) : null; 
    } 

    // Etc.. 
} 

Bằng cách này, bạn có thể xem tại phương thức/đối số có tên/kỳ vọng.

1

Có một số cách để đi trên một này (một số đã được đề cập):

  • Như @Roman, quấn các loại mục đích chung trong một loại cụ thể hơn, mang đến cho gõ mạnh. Mạnh gõ tốt, IMO.
  • Là @nanda, hãy sử dụng loại bộ sưu tập cụ thể hơn. Thư viện Java có một chút nghèo nàn trong lĩnh vực này. Nó phụ thuộc vào cách bạn cảm nhận về sự phụ thuộc.
  • Là @BalusC, di chuyển tất cả nội dung icky vào một lớp học khốc liệt. Không thực sự loại bỏ vấn đề, nhưng nó có chứa nó (như trong Ghostbusters).
  • Map<String,Map<String,foo>> trông rất giống bạn có khóa tổng hợp, tức là khóa bao gồm hai phần. Vì vậy, giới thiệu một lớp khóa tổng hợp bất biến, đó là một đối tượng giá trị đại diện cho hai đối tượng giá trị thành phần.
Các vấn đề liên quan