2013-02-22 41 views
5

Tôi cần một lớp thu thập có cả hai: chỉ mục nhanh và truy cập băm. Bây giờ tôi có ArrayList. Đô thị này có acces chỉ số tốt, nhưng phương pháp contains của mình là không thực hiện. HashSet có thực hiện tốt contains nhưng không có acces được lập chỉ mục. Bộ sưu tập nào có cả hai? Có lẽ một cái gì đó từ Apache? Hoặc tôi có nên tạo lớp bộ sưu tập của riêng mình có cả hai: ArrayList cho các chỉ mục acces và HashSet cho kiểm tra contains?Bộ sưu tập có chỉ mục và truy cập băm

Chỉ cần làm rõ: tôi cần cả hai get(int index)contains(Object o)

+2

Bạn sở hữu cấu trúc dữ liệu chứa cả hai (hoặc một số biến thể trên đó) có lẽ là cách để đi. – Dukeling

+0

Bạn có thể giải thích _why_ bạn muốn điều này không? –

+0

Có, tôi có thể. Tôi có mã kế thừa, sử dụng gần như tất cả các phương thức của đối tượng List (ArrayList). Tôi không có cơ hội để viết lại nó, nhưng tôi muốn tăng hiệu suất của nó.Vấn đề chính ở đây là chứa các phương thức indexOf và vì chúng có hiệu suất tuyến tính. –

Trả lời

0

Nếu bạn đang đi qua chỉ số từ đầu đến cuối, tôi nghĩ rằng điều này có thể đáp ứng nhu cầu của bạn: LinkedHashSet

Nếu bạn cần truy cập ngẫu nhiên thông qua chỉ mục, cũng như truy cập băm, nếu không ai khác có đề xuất tốt hơn, tôi đoán bạn có thể tạo bộ sưu tập của riêng bạn làm cả hai.

+2

Theo như tôi có thể thấy, truy cập được lập chỉ mục sẽ là 'O (n)', không đặc biệt hiệu quả. – Dukeling

+0

LinkedHashSet không có phương thức 'get (int index)' –

+0

@SergiyMedvynskyy Có, nhưng bạn có thể sử dụng trình lặp để mô phỏng nó. – Dukeling

1

Nếu hiệu suất truy cập được lập chỉ mục không phải là một vấn đề các trận đấu gần nhất là LinkedHashSet mà API nói rằng nó là

bảng Hash và liên kết thực hiện danh sách các giao diện Set, với trật tự lặp dự đoán được.

ít nhất tôi không nghĩ rằng hiệu suất sẽ kém hơn hiệu suất của LinkedListPerformance. Nếu không, tôi không thể thấy không thay thế nhưng giải pháp ArrayList + HashTable của bạn

+0

Tôi không chắc chắn rằng nó thực sự tốt hơn –

0

Làm như thế này; sử dụng sự kết hợp của Hash kỹ thuật cũng như danh sách để có được tốt nhất của cả hai thế giới :)

class DataStructure<Integer>{ 
    Hash<Integer,Integer> hash = new HashMap<Integer, Integer>(); 
    List<Integer> list = new ArrayList<Integer>(); 

    public void add(Integer i){ 
     hash.add(i,i); 
     list.add(i); 
    } 
    public Integer get(int index){ 
     return list.get(index); 
    } 
    ... 
} //used Integers to make it simpler 

Vì vậy, đối tượng; bạn giữ trong HashMap/HashSet cũng như ArrayList.

Vì vậy, nếu bạn muốn sử dụng

contains method : call hashed contains method. 

get an object with index: use array to return the value 

Chỉ cần chắc chắn rằng bạn có cả những bộ sưu tập đồng bộ. Và chăm sóc cập nhật/xóa trong cả hai cấu trúc dữ liệu.

+0

Đó là lỗ hổng cuối cùng, mà tôi sẽ sử dụng, nếu tôi không thể tìm thấy cái gì tốt hơn –

0

Tôi không biết thời gian tra cứu chính xác, nhưng có thể bạn có thể sử dụng một số triển khai của Map interface. Bạn có thể lưu trữ các đối tượng của mình với map.put(objectHash, obj).

Sau đó, bạn có thể xác minh rằng bạn có một đối tượng nhất định với:

boolean contained = map.containsValue(obj); 

Và bạn có thể sử dụng băm để tra cứu một đối tượng trong bản đồ:

MyObject object = map.get(objectHash); 

Mặc dù, sự sụp đổ chỉ là rằng bạn sẽ cần phải biết băm của bạn về cuộc gọi tra cứu này có thể không có khả năng trong quá trình triển khai của bạn.

+0

containsValue cho HashMap có hiệu suất giống như chứa một danh sách - tuyến tính. Tôi muốn logarithmical (nếu có thể của khóa học). –

+0

@SergiyMedvynskyy Ahh, tôi không biết điều đó. Bạn có một tham chiếu về nơi bạn phát hiện ra điều đó không? –

+0

Chỉ cần xem triển khai HashMap. Phương thức containsValue lặp qua tất cả các mục và kiểm tra cho sự bình đẳng như phương thức chứa của ArrayList. –

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