2012-11-23 42 views
5

Tôi có một lớp học với một số danh sách khóa-giá trị. Mỗi khóa (trong một danh sách) phải là duy nhất, vì vậy tôi sử dụng HashMap. Khi một nơi nào đó trong mã tôi thêm một mục mới vào một danh sách, tôi đang sử dụng put(K, V) của HashMap. Tôi muốn mã của tôi để ném một ngoại lệ nếu một nỗ lực được thực hiện để thêm một mục với khóa đã tồn tại. Và, bởi vì việc bổ sung như vậy được thực hiện ở nhiều nơi trong chương trình, tôi muốn tránh việc thêm kiểm tra trong mỗi người trong số họ. Vì vậy, nó phải là chính lớp danh sách mà sẽ không cho phép thay thế cặp khóa-giá trị hiện tại.HashMap với kiểm tra tính duy nhất

Tôi đã nghĩ đến việc mở rộng lớp HashMap bằng lớp của riêng mình, lớp này sẽ thực hiện kiểm tra và ném một ngoại lệ. Tuy nhiên, put của HashMap không ném ngoại lệ, vì vậy tôi cũng không thể làm được.

Cách tiếp cận tốt để đạt được hành vi như vậy là gì? Tôi đã sẵn sàng để thay thế HashMap với một cái gì đó tốt hơn, nhưng tôi cần nó để được nhanh chóng trong cả hai thêm và lấy các mục.

Cập nhật: Cảm ơn tất cả vì nhiều đề xuất thú vị. Vì tôi là một newbie hoàn toàn trong Java, bây giờ tôi cần phải học hỏi rất nhiều để có thể chọn một trong những tốt nhất :) Dù sao, tôi biết ơn vì nhận được rất nhiều lựa chọn trong một bữa ăn trưa-break!

+0

Commons Bộ sưu tập không nhận được độ phơi sáng xứng đáng ... – Isaac

Trả lời

0

Bạn có thể ném ngoại lệ mở rộng RuntimeException.

+2

Xin chào bạn, câu trả lời của tôi là hợp lệ. Đưa ra lý do tại sao bạn downvote – AlexWien

+1

Tôi không phải là downvoter, nhưng tôi tin rằng lý do downvoting là bạn đã đề xuất một giải pháp mà sẽ yêu cầu OP mã một cách rõ ràng kiểm tra bản thân, trong khi OP nói rõ rằng họ đang tìm kiếm cho một cơ chế sẽ tự động thực hiện điều đó. – Isaac

+1

@AlexWien Tôi đã không downvote nhưng bạn sẽ vi phạm Nguyên tắc thay thế Liskov. – Mik378

2

Một số ý tưởng:
A. Ném ngoại lệ mở rộng RuntimeException trong lớp của bạn mở rộng HashMap.
B. Cung cấp một số loại MapWrapper sẽ nhận được Bản đồ dưới dạng tham số, sẽ có được, đặt và một số phương pháp khác, với chữ ký phù hợp với bạn nhiều hơn.

+0

'B' đã tồn tại. Xem câu trả lời của tôi dưới đây. – Isaac

+0

@zaske Liskov vi phạm ở đây cũng có. – Mik378

+0

@ Mik378, 'A' ở đây vi phạm LSP; 'B' thì không. Nhưng 'B' đã có sẵn trong Bộ sưu tập của Commons (xem câu trả lời của tôi), không cần phải phát minh lại bánh xe. – Isaac

7

Bạn có thể sử dụng Commons Collections cho điều này, một cái gì đó như:

Map map = MapUtils.predicatedMap(new HashMap(), PredicateUtils.uniquePredicate(), 
      null); 

này sẽ tạo ra một trường hợp Map rằng sẽ ném một ngoại lệ bất cứ khi nào bạn thử chèn một cặp khóa-giá trị khi cùng khóa đã tồn tại.

Tất nhiên, bạn có thể tùy chỉnh hành vi này bằng cách xây dựng cá thể Predicate của riêng bạn và sử dụng nó thay vì PredicateUtils.uniquePredicate(). Của riêng bạn Predicate có thể làm bất cứ điều gì bạn cần nó để làm, vì vậy ví dụ, nó có thể ném một loại khác nhau của ngoại lệ hơn một ném bởi mặc định uniquePredicate().

6

tôi sẽ không mở rộng HashMap lớp, vì trong trường hợp này, nó sẽ dẫn đến một sự vi phạm của Liskov Substitution Nguyên tắc vì bạn thay đổi hành vi của một phương pháp lớp cơ sở.

Thay vào đó tôi sẽ sử dụng thành phần:

Tạo lớp học của bạn CustomHashMap thực hiện giao diện Map và HAVING một trường HashMap. Và redeclare mọi phương thức có trong lớp HashMap, thêm một phái đoàn vào HashMap ban đầu cho mỗi ngoại trừ phương thức put() => ném ngoại lệ nếu entry đã tồn tại.

+0

1 để đề cập đến LSP, và cảm ơn cho giải pháp. – texnic

0

Bạn có thể mở rộng HashMap và ném ngoại lệ là phân lớp của RuntimeException hoặc một trong các ngoại lệ đã được ném bởi phương thức đặt.

1

Các javadoc for Map#put states:

ném IllegalArgumentException nếu một số tài sản của khóa hoặc giá trị quy định ngăn không cho nó được lưu trữ trong bản đồ này

Tôi nghĩ trường hợp sử dụng của bạn rơi vào trường hợp đó và Do đó tôi sẽ sử dụng khả năng đó. Vì đây là một ngoại lệ không được kiểm soát, bạn có thể sử dụng bố cục, quấn HashMap và ném một số IllegalArgumentException vào các bản sao trong phương thức put.

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