2017-06-06 18 views
5

Để giảm mức tiêu thụ bộ nhớ, tôi đang viết lại một lớp có SortedSet<Integer>. Trong 80% trường hợp, bộ sưu tập này chỉ chứa một phần tử duy nhất. Vì vậy, tôi nghĩ rằng tôi có thể sử dụng một số SingeltonSet trong các trường hợp này và một số TreeSet bình thường trong các trường hợp khác. Bây giờ tôi nhận thấy rằng SingletonSet, như được trả về bởi Collections.singleton(), không triển khai SortedSet. Có lý do nào cho thiếu sót này không? Một yếu tố duy nhất luôn có thể được coi là sắp xếp tôi muốn nói. Tôi có phải viết bản thực hiện SingletonSet của riêng mình không?Tại sao SingletonSet không triển khai SortedSet

+1

Bạn có thể, tất nhiên, chỉ cần viết 'Cây mới mới (Collections.singleton (phần tử))'. – VGR

+0

@VGR Xin lỗi, tôi đoán tôi quên đề cập đến việc đó là tất cả về mức tiêu thụ bộ nhớ. – steffen

+4

Tôi chắc chắn bạn đang tham gia vào tối ưu hóa sớm. 'TreeSet mới' sẽ không ảnh hưởng đến hiệu suất của bạn trừ khi bạn đang tạo hàng triệu trong số đó, và có thể thậm chí là không. – VGR

Trả lời

4

Đây là một điểm thú vị, có vẻ như minh họa một lỗ nhỏ trong API bộ sưu tập.

Thực tế là Collections.singleton() được chỉ định để trả lại Set, không phải là SortedSet và trên thực tế việc triển khai không hỗ trợ giao diện đó. Tôi không nghĩ rằng nó sẽ hữu ích cho Collections.singleton() để thay đổi hành vi của nó và trả lại phiên bản của SortedSet. Điều này sẽ khuyến khích việc triển khai thực hiện kiểm tra và thanh toán xuống instanceof. (Và tương tự cho các phương thức và giao diện Bản đồ tương ứng.)

Đó là một sự an ủi nhỏ cho trường hợp sử dụng này, nhưng trong Java SE 8 phương pháp mới Collections.emptyNavigableMapemptyNavigableSet đã được giới thiệu. Điều này rất hữu ích cho các trường hợp sử dụng muốn có các bộ sưu tập có thể điều hướng trống, nhưng nếu bạn thực sự muốn điều hướng với một phần tử hoặc ánh xạ đơn lẻ, bạn sẽ không may mắn. Có một yêu cầu nâng cao JDK-6201174 bao gồm một khu vực tương tự; Tôi đã cập nhật và tập trung lại nó xung quanh việc cung cấp các API cho một tập hợp và bản đồ điều hướng đơn.

Nhưng hãy đợi! Khi bạn pointed out, có một chút trạng thái bổ sung đi cùng với các bộ sưu tập được sắp xếp/điều hướng, là bộ so sánh. (Hoặc trong trường hợp không có một bộ so sánh, ngầm là một cung cấp thứ tự tự nhiên.) Bất kỳ API singleton mới nào cũng sẽ cung cấp cho nó. Và điều này chỉ ra thực tế rằng các phương pháp * trống mà tôi đã đề cập ở trên không nói về Comparator. Điều đó có vẻ như một lỗi khác: JDK-8181754.

Thật không may là tôi không có cách giải quyết thực sự tốt cho bạn ngoài việc khóa xuống và triển khai một phân đoạn có thể thay đổi một phần hoặc có thể là NavigableSet. Bạn có thể bắt đầu với Collections.UnmodifiableNavigableSet. Điều này giúp một chút, nhưng không nhiều. Trong thực tế, bộ điều hướng rỗng là một trong số các gói này được bao quanh một khoảng trống TreeSet! Điều này là khá vô ích, vì bạn muốn tránh TreeSet trường hợp.

Tôi có thể bắt đầu từ AbstractSet và sau đó thêm tập hợp phương thức tối thiểu từ SortedSet. Có khá ít phương pháp hơn trong NavigableSet, vì vậy nếu bạn không cần tất cả các chuông và còi của nó, nó sẽ là một nhiệm vụ nhỏ hơn để dính vào SortedSet.

+1

Cảm ơn rất nhiều câu trả lời và động lực toàn diện của bạn để phân tích chủ đề này! Tôi không thể +2, vì vậy +1 + ✓. Tôi nghĩ rằng tôi sẽ kiểm tra fastutil hoặc viết của riêng tôi 'Sorted-' hoặc 'NavigableSingleton'. Một điều tôi không nhận được: Tại sao một kiểu trả về chuyên biệt hơn lại khuyến khích kiểm tra 'instanceof'? – steffen

+0

Bạn được chào đón! Vấn đề với giá trị trả về từ 'Collections.singleton' là kiểu trả về tĩnh không thể thay đổi vì lý do tương thích. Tuy nhiên, việc thực thi có thể được thay đổi để trả về một thể hiện của 'SortedSet' mặc dù kiểu trả về tĩnh là' Set'. Nhưng để sử dụng nó như là một lập trình viên 'SortedSet' sẽ phải kiểm tra' instanceof' và downcast. Bạn nên thêm một API mới với loại trả về tĩnh cụ thể hơn. –

+1

Điều chắc chắn. Và trả về một loại chuyên biệt hơn sẽ phá vỡ khả năng tương thích nhị phân. Hiểu rồi. – steffen

2

Giao diện SortedSet xác định các phương thức yêu cầu Comparator cho các phần tử đã đặt. Vì vậy, các yếu tố được duy trì bởi SortedSet phải được so sánh. Nếu singleton được trả lại bởi Collections.singleton() sẽ triển khai SortedSet, thì Collections.singleton() chỉ có thể chấp nhận Comparables (đó không phải là những gì chúng tôi muốn).

+1

+1 để chỉ ra rằng các giao diện Sắp xếp và Điều hướng ngụ ý một trạng thái ẩn, đó là Trình so sánh. –

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