Tại sao java.util.Set không có (chỉ mục int)?


237

Tôi chắc chắn có một lý do chính đáng, nhưng ai đó có thể vui lòng giải thích tại sao java.util.Setgiao diện thiếu get(int Index), hoặc bất kỳ get()phương pháp tương tự nào không?

Có vẻ như các bộ rất tuyệt để đặt mọi thứ vào, nhưng tôi không thể tìm thấy một cách thanh lịch để lấy một vật phẩm từ nó.

Nếu tôi biết tôi muốn mục đầu tiên, tôi có thể sử dụng set.iterator().next(), nhưng nếu không thì có vẻ như tôi phải chuyển sang Mảng để lấy một mục ở một chỉ mục cụ thể?

Các cách thích hợp để lấy dữ liệu từ một bộ là gì? (ngoài việc sử dụng một trình vòng lặp)

Tôi chắc chắn rằng thực tế là nó bị loại khỏi API có nghĩa là có lý do chính đáng để không làm điều này - ai đó có thể vui lòng khai sáng cho tôi không?

EDIT: Một số câu trả lời cực kỳ tuyệt vời ở đây, và một số ít nói "bối cảnh nhiều hơn". Kịch bản cụ thể là một thử nghiệm dbUnit, trong đó tôi có thể khẳng định một cách hợp lý rằng tập trả về từ một truy vấn chỉ có 1 mục và tôi đang cố gắng truy cập vào mục đó.

Tuy nhiên, câu hỏi có giá trị hơn nếu không có kịch bản, vì nó vẫn tập trung hơn:

Sự khác biệt giữa bộ và danh sách .

Cảm ơn tất cả các câu trả lời tuyệt vời dưới đây.


1
Tại sao bạn sẽ nhận được một phần tử từ một tập hợp theo chỉ mục? Bạn đang cố gắng sử dụng một tập hợp như là một mảng được sắp xếp?
MSN

Ví dụ cụ thể ở đây là một thử nghiệm dbUnit đối với một Set được trả về từ một cuộc gọi ngủ đông. Trong thử nghiệm của tôi, thật hợp lý khi giả định (vì tôi khẳng định) rằng đối tượng được trả về theo một thứ tự cụ thể, vì IDataSet của tôi, tôi đã sử dụng để thiết lập nó. Đó là một trường hợp không điển hình, nhưng dẫn đến sự tò mò của tôi về API.
Marty Pitt

1
Thêm mọi thứ theo một thứ tự cụ thể không có nghĩa là chúng sẽ giữ nguyên như vậy, trừ khi bạn đang sử dụng triển khai Cài đặt tùy chỉnh.
Michael Myers

1
"Nếu tôi biết tôi muốn mục đầu tiên, tôi có thể sử dụng set.iterator (). Next ()" - Dòng này không thực sự có ý nghĩa. Bạn đang thực sự nói "Nếu tôi biết tôi muốn mục đầu tiên, theo định nghĩa của việc thực hiện mục đầu tiên, thì tôi có thể ...". Đặt chính nó là không có thứ tự, vì vậy truy cập được lập chỉ mục không có ý nghĩa. Bây giờ nếu có một ArrayListset, điều đó sẽ có ý nghĩa hơn (chỉ cần chuyển sang "Danh sách" và hạnh phúc). Có lẽ bạn có thể đưa ra nhiều bối cảnh cho câu hỏi?
jsight

Đặt không có thứ tự! Một số triển khai nhất định của nó là, nhưng một số triển khai được sắp xếp rõ ràng theo một cách cụ thể.
Revierpost

Câu trả lời:


176

Bởi vì bộ không có thứ tự. Một số triển khai thực hiện (đặc biệt là các triển khai thực hiện java.util.SortedSetgiao diện), nhưng đó không phải là thuộc tính chung của các bộ.

Nếu bạn đang cố gắng sử dụng các bộ theo cách này, bạn nên xem xét sử dụng danh sách thay thế.


10
@matt b: Không, tôi nghĩ anh ấy nên xem xét nó. Suy nghĩ là tốt. ;)
Michael Myers

10
Hãy xem xét nó, sau đó làm điều đó.
Joe Phillips

21
"Xem xét" là cụm từ chính xác. Có hai vấn đề có thể xảy ra (a) Anh ấy đang sử dụng một bộ khi anh ấy nên sử dụng một thứ khác, hoặc (b) Anh ấy đang cố gắng làm mọi thứ với Bộ mà họ không hỗ trợ nhưng anh ấy có thể làm một cách khác. Nó là tốt để xem xét đó là trường hợp nào.
kenj0418

6
Có thể câu trả lời đơn giản hơn là sử dụng một bộ được sắp xếp. (Tôi cho rằng tính duy nhất đã đóng một phần trong khi chọn bộ). Nhưng tôi có một câu hỏi tho, vì Sắp xếp thứ tự được đặt hàng, tại sao không có phương thức get trong api.
unsaught_exceptions

5
@HDave: Không, thực tế là việc triển khai nhiều cấu trúc dữ liệu chia sẻ một thuộc tính không làm cho nó trở thành một thuộc tính của chính cấu trúc dữ liệu. Hai trong số ba triển khai Danh sách (ArrayList và Vector) thường được sử dụng là truy cập ngẫu nhiên, nhưng điều đó không làm cho truy cập ngẫu nhiên trở thành một thuộc tính của Danh sách.
Michael Myers

74

Trên thực tế đây là một câu hỏi định kỳ khi viết các ứng dụng JavaEE sử dụng Ánh xạ quan hệ đối tượng (ví dụ với Hibernate); và từ tất cả những người trả lời ở đây, Andreas Petersson là người duy nhất hiểu được vấn đề thực sự và đưa ra câu trả lời chính xác cho nó: Java đang thiếu một Danh sách duy nhất! (hoặc bạn cũng có thể gọi nó là Orderedset hoặc Indexedset).

Maxwing đã đề cập đến trường hợp sử dụng này (trong đó bạn cần dữ liệu có thứ tự VÀ duy nhất) và anh ấy đã đề xuất Sắp xếp, nhưng đây không phải là điều Marty Pitt thực sự cần.

"Bộ chỉ mục" này KHÔNG giống như Bộ sắp xếp - trong Bộ sắp xếp, các phần tử được sắp xếp bằng cách sử dụng Bộ so sánh (hoặc sử dụng thứ tự "tự nhiên" của chúng).

Nhưng thay vào đó, nó gần với LinkedHashset hơn (mà những người khác cũng đề xuất), hoặc thậm chí còn hơn cả một "ArrayListet" (cũng không tồn tại), bởi vì nó đảm bảo rằng các phần tử được trả về theo đúng thứ tự khi chúng được chèn.

Nhưng LinkedHashSet là một triển khai, không phải là một giao diện! Những gì cần thiết là một giao diện Indexedset (hoặc Listset, hoặc Orderedset hoặc UniqueList)! Điều này sẽ cho phép lập trình viên xác định rằng anh ta cần một tập hợp các phần tử có thứ tự cụ thể và không trùng lặp, sau đó khởi tạo nó với bất kỳ triển khai nào (ví dụ: một triển khai do Hibernate cung cấp).

Vì JDK là mã nguồn mở, có thể giao diện này cuối cùng sẽ được đưa vào Java 7 ...


3
Câu trả lời tuyệt vời như nó đi, nhưng chúng ta làm gì trong lúc này?
HDave

chắc chắn rồi tôi đã sử dụng danh sách như nhiều ORM và onetomany ORM trong chế độ ngủ đông trước đây. tôi đã gặp một sự cố (hoặc khiếm khuyết) khi một truy vấn tham gia bên trái liên quan đến hơn 3 thực thể liên quan, một ngoại lệ đã được đưa ra. nhìn vào đây để biết thêm chi tiết ( joder.com/eyallupu/entry/ mài ). để giải quyết vấn đề này, sử dụng bộ làm bộ sưu tập ánh xạ ORM là cần thiết. nhưng thành thật mà nói, thiết lập không thuận tiện cho việc truy cập trong lập trình và cả khi bạn cần một bộ sưu tập đặt hàng. những gì chúng ta thực sự cần là "lập chỉ mục" như những gì Sorin Postelnicu đã nói, SORT và
UNIITE

2
Bộ sưu tập Apache Commons có ListOrderedSetnhững gì OP cần 7 năm trước (và tôi cần ngày hôm nay).
Paul

@Paul: Đó thực sự là một cái gì đó trông thực sự tốt. Thật không may, nó vẫn có 3 nhược điểm: 1) Nó là một lớp, không phải là một giao diện. 2) Nó không có trong JDK. 3) Đó không phải là những gì truy vấn Hibernate đang trả lại.
Sorin Postelnicu

Vâng, nhưng ngoài 3 nhược điểm chính thì nó hoàn hảo! :) Nhìn lại, tôi nên đăng bình luận của mình cho câu hỏi chứ không phải câu trả lời của bạn - Tôi đã khóa What is needed is an IndexedSet (or ListSet, or OrderedSet, or UniqueList)...và bỏ qua ...interface. Xin lỗi vì điều đó!
Paul

29

Chỉ cần thêm một điểm không được đề cập trong câu trả lời của mmyer .

Nếu tôi biết tôi muốn mục đầu tiên, tôi có thể sử dụng set.iterator (). Next (), nhưng nếu không thì có vẻ như tôi phải truyền vào một Array để lấy một mục tại một chỉ mục cụ thể?

Các cách thích hợp để lấy dữ liệu từ một bộ là gì? (ngoài việc sử dụng một trình vòng lặp)

Bạn cũng nên làm quen với SortedSetgiao diện (có triển khai phổ biến nhất TreeSet).

Một Sắp xếp là một Tập hợp (tức là các phần tử là duy nhất) được sắp xếp theo thứ tự tự nhiên của các phần tử hoặc sử dụng một số phần tử Comparator. Bạn có thể dễ dàng truy cập các mục đầu tiên và cuối cùng bằng cách sử dụng first()last()phương pháp. Một SortedSetcó ích mỗi một lần trong một thời gian, khi bạn cần để giữ cho bộ sưu tập của bạn cả hai trùng lặp miễn phí và sắp xếp theo một cách nào đó.

Chỉnh sửa : Nếu bạn cần một Tập hợp có các thành phần được giữ theo thứ tự chèn (giống như Danh sách), hãy xem LinkedHashSet.


Bản thân tôi thích LinkedHashset. Nhưng có, điều này là tốt để đề cập. +1
Michael Myers

Cảm ơn, tôi đã điều chỉnh câu trả lời một chút. (Có vẻ như tôi đã có một số khía cạnh của TreeSet bị nhầm lẫn với những khía cạnh của LinkedHashset.)
Jonik

25

Loại này dẫn đến câu hỏi khi nào bạn nên sử dụng một bộ và khi nào bạn nên sử dụng một danh sách. Thông thường, lời khuyên đi:

  1. Nếu bạn cần dữ liệu theo thứ tự, hãy sử dụng Danh sách
  2. Nếu bạn cần dữ liệu duy nhất, hãy sử dụng Bộ
  3. Nếu bạn cần cả hai, hãy sử dụng một trong hai: Sắp xếp thứ tự (đối với dữ liệu được sắp xếp theo bộ so sánh) hoặc Orderedset / UniqueList (đối với dữ liệu được sắp xếp theo cách chèn). Thật không may, API Java chưa có Orderedset / UniqueList.

Một trường hợp thứ tư xuất hiện thường xuyên là bạn không cần. Trong trường hợp này, bạn thấy một số lập trình viên đi với danh sách và một số với bộ. Cá nhân tôi thấy rất có hại khi xem thiết lập như một danh sách mà không đặt hàng - bởi vì nó thực sự là một con thú khác. Trừ khi bạn cần những thứ như thiết lập tính duy nhất hoặc thiết lập sự bình đẳng, luôn luôn ưu tiên danh sách.


2
nếu bạn không đặc biệt, hãy chấp nhận Bộ sưu tập <T> hoặc thậm chí có thể lặp lại <T> và khởi tạo dưới dạng Danh sách.
Andreas Petersson

Đây sẽ là một túi hoặc nhiều. Nhưng Java không hỗ trợ những thứ đó; họ nói rằng bạn chỉ nên sử dụng Bộ sưu tập <T> trực tiếp.
Ốc cơ khí

4. bạn cần dữ liệu không phải là duy nhất và không quan tâm đến thứ tự. Bạn KHÔNG THỂ sử dụng một bộ. Danh sách, túi hoặc nhiều trang sẽ hoạt động.
Andrew Gallasch

17

Tôi không chắc có ai đã đánh vần chính xác theo cách này không, nhưng bạn cần hiểu những điều sau:

Không có yếu tố "đầu tiên" trong một bộ.

Bởi vì, như những người khác đã nói, bộ không có thứ tự. Một tập hợp là một khái niệm toán học đặc biệt không bao gồm đặt hàng.

Tất nhiên, máy tính của bạn thực sự không thể giữ một danh sách những thứ không được sắp xếp trong bộ nhớ. Nó phải có một số thứ tự. Bên trong nó là một mảng hoặc một danh sách liên kết hoặc một cái gì đó. Nhưng bạn không thực sự biết nó là gì và nó không thực sự có yếu tố đầu tiên; yếu tố xuất hiện "lần đầu tiên" xuất hiện theo cách đó một cách tình cờ, và có thể không phải là lần đầu tiên. Ngay cả khi bạn đã thực hiện các bước để "đảm bảo" một yếu tố đầu tiên cụ thể, nó vẫn xuất hiện một cách tình cờ, bởi vì bạn chỉ tình cờ làm cho nó phù hợp với một triển khai cụ thể của Tập hợp; một cách thực hiện khác có thể không hoạt động theo cách đó với những gì bạn đã làm. Và trên thực tế, bạn có thể không biết việc triển khai bạn đang sử dụng cũng như bạn nghĩ bạn làm.

Mọi người chạy vào TẤT CẢ này. CÁC. THỜI GIAN. với các hệ thống RDBMS và không hiểu. Một truy vấn RDBMS trả về một tập hợp các bản ghi. Đây là cùng một loại tập hợp từ toán học: một bộ sưu tập các mục không có thứ tự, chỉ trong trường hợp này các mục là các bản ghi. Kết quả truy vấn RDBMS hoàn toàn không có thứ tự được đảm bảo trừ khi bạn sử dụng mệnh đề ORDER BY, nhưng mọi lúc mọi người đều cho rằng nó sẽ tự tắt và một ngày nào đó khi hình dạng của dữ liệu hoặc mã của họ thay đổi một chút và kích hoạt trình tối ưu hóa truy vấn hoạt động một cách khác và đột nhiên kết quả không xuất hiện theo thứ tự họ mong đợi. Đây thường là những người không chú ý trong lớp cơ sở dữ liệu (hoặc khi đọc tài liệu hoặc hướng dẫn) khi được giải thích cho họ, trước mắt, kết quả truy vấn đó không có thứ tự được đảm bảo.


Heh, và tất nhiên, thứ tự thường thay đổi ngay sau khi mã đi vào sản xuất, khi nó quá chậm, vì vậy họ thêm một chỉ mục để tăng tốc truy vấn. Bây giờ mã chạy nhanh, nhưng đưa ra câu trả lời sai. Và không ai thông báo trong ba hoặc bốn ngày ... nếu bạn may mắn. Nếu bạn không may mắn, không ai thông báo trong một tháng ...
TMN

Tôi không nghĩ anh ấy đã bỏ lỡ điều đó (có lẽ anh ấy đã cẩu thả với ký hiệu). Anh ta không muốn yếu tố đầu tiên từ tập hợp, anh ta muốn một yếu tố tùy ý từ tập hợp. Bạn có thể cho anh ta một yếu tố tùy ý kể từ khi SetIterable.
Elazar Leibovich

Bạn đang nói về get (index) theo chỉ mục. Điều gì về một get (Object) bằng đẳng thức?
Kumar Manish

10

một số cấu trúc dữ liệu bị thiếu trong các bộ sưu tập java tiêu chuẩn.

Túi (như bộ nhưng có thể chứa các yếu tố nhiều lần)

UniqueList (danh sách được sắp xếp, chỉ có thể chứa mỗi phần tử một lần)

có vẻ như bạn sẽ cần một người duy nhất trong trường hợp này

nếu bạn cần cấu trúc dữ liệu linh hoạt, bạn có thể quan tâm đến Bộ sưu tập của Google


1
Guva có cung cấp "Danh sách duy nhất" không?
Mike Rylander

không, nhưng bạn có thể có java.util.LinkedHashset có các thuộc tính tương tự.
Andreas Petersson

7

Đó là sự thật, phần tử trong Set không được sắp xếp theo định nghĩa của Bộ sưu tập Set. Vì vậy, họ không thể được truy cập bởi một chỉ mục.

Nhưng tại sao chúng ta không có phương thức get (object), không phải bằng cách cung cấp chỉ mục làm tham số, mà là một đối tượng bằng với đối tượng chúng ta đang tìm kiếm? Bằng cách này, chúng ta có thể truy cập dữ liệu của phần tử bên trong Tập hợp, chỉ bằng cách biết các thuộc tính của nó được sử dụng bởi phương thức bằng nhau.


7

Nếu bạn định thực hiện nhiều truy cập ngẫu nhiên theo chỉ mục trong một bộ, bạn có thể có được chế độ xem mảng của các thành phần của nó:

Object[] arrayView = mySet.toArray();
//do whatever you need with arrayView[i]

Có hai nhược điểm chính:

  1. Nó không hiệu quả về bộ nhớ, vì một mảng cho toàn bộ cần phải được tạo.
  2. Nếu bộ được sửa đổi, chế độ xem sẽ trở nên lỗi thời.

5

Đó là bởi vì Set chỉ đảm bảo tính duy nhất, nhưng không nói gì về các kiểu truy cập hoặc sử dụng tối ưu. Tức là, Tập hợp có thể là Danh sách hoặc Bản đồ, mỗi Bản đồ có các đặc điểm truy xuất rất khác nhau.


5

Lý do duy nhất tôi có thể nghĩ đến khi sử dụng một chỉ số bằng số trong một tập hợp là để lặp lại. Cho rằng, sử dụng

for(A a : set) { 
   visit(a); 
}

Không đúng, những gì về việc truy cập một yếu tố ngẫu nhiên?
Jeremy Salwen

Ha, ha. điểm tốt :) nhưng điều đó sẽ rất dễ bị lạm dụng, tôi chắc chắn.
Hugo

3

Tôi gặp phải tình huống tôi thực sự muốn một Bộ sắp xếp có quyền truy cập thông qua chỉ mục (Tôi đồng tình với các áp phích khác rằng việc truy cập Bộ chưa được sắp xếp với chỉ mục không có ý nghĩa). Một ví dụ sẽ là một cái cây nơi tôi muốn các em được sắp xếp và các bản sao trẻ em không được phép.

Tôi cần quyền truy cập thông qua chỉ mục để hiển thị chúng và các thuộc tính được thiết lập có ích để loại bỏ hiệu quả các bản sao.

Tìm thấy không có bộ sưu tập phù hợp trong các bộ sưu tập java.util hoặc google, tôi thấy nó đơn giản để tự thực hiện nó. Ý tưởng cơ bản là bọc một Sắp xếp Sắp xếp và tạo Danh sách khi cần truy cập qua chỉ mục (và quên danh sách khi Sắp xếp Sắp xếp thay đổi). Điều này tất nhiên chỉ hoạt động hiệu quả khi thay đổi Sắp xếp được bao bọc và việc truy cập danh sách được tách ra trong vòng đời của Bộ sưu tập. Mặt khác, nó hoạt động như một danh sách được sắp xếp thường xuyên, tức là quá chậm.

Với số lượng lớn trẻ em, hiệu suất này được cải thiện rất nhiều so với danh sách tôi đã sắp xếp qua Collections.sort.


2

Xin lưu ý chỉ có 2 cấu trúc dữ liệu cơ bản có thể được truy cập thông qua chỉ mục.

  • Cấu trúc dữ liệu mảng có thể được truy cập thông qua chỉ mục với O(1)độ phức tạp thời gian để đạt được get(int index)hoạt động.
  • Cấu trúc dữ liệu LinkedList cũng có thể được truy cập thông qua chỉ mục, nhưng với O(n)độ phức tạp về thời gian để đạt được get(int index)hoạt động.

Trong Java, ArrayListđược triển khai bằng cấu trúc dữ liệu Array .

Mặc dù cấu trúc dữ liệu Set thường có thể được triển khai thông qua cấu trúc dữ liệu HashTable / HashMap hoặc Bal cân bằng , để phát hiện nhanh xem một phần tử có tồn tại và thêm phần tử không tồn tại hay không, thông thường, Set được triển khai tốt có thể đạt được thao tác O(1)phức tạp thời gian contains. Trong Java, HashSetlà cách triển khai Set được sử dụng phổ biến nhất , nó được triển khai bằng cách gọi HashMapAPI và HashMapđược triển khai bằng cách sử dụng chuỗi riêng với các danh sách được liên kết (kết hợp giữa ArrayLinkedList ).

Set có thể được thực hiện thông qua cấu trúc dữ liệu khác nhau, nên không có get(int index)phương pháp nào cho nó.


Cây ngón tay (Xem Data.Sequence.lookupchức năng của Haskell ) cũng cho phép truy cập thông qua chỉ mục ( O(1)gần cuối O(log n)gần giữa, chính xác hơn O(min(log(k), log(n-k)))), cũng như cây nhị phân (Xem Data.Set.lookupIndexchức năng của Haskell ). Vì vậy, khẳng định ban đầu của bạn rằng "Xin lưu ý chỉ có thể truy cập 2 cấu trúc dữ liệu cơ bản qua chỉ mục" là không chính xác.
dấu chấm phẩy

1

Lý do tại sao giao diện Set không có cuộc gọi loại chỉ mục hoặc thậm chí một cái gì đó thậm chí còn cơ bản hơn, chẳng hạn như đầu tiên () hoặc cuối cùng (), là vì đây là một hoạt động mơ hồ và do đó là một hoạt động nguy hiểm tiềm tàng. Nếu một phương thức trả về một Tập hợp và bạn gọi, hãy nói phương thức đầu tiên () trên đó, kết quả mong đợi là gì, với điều kiện là Tập chung không đảm bảo cho việc đặt hàng? Đối tượng kết quả có thể rất khác nhau giữa mỗi lệnh gọi của phương thức, hoặc nó có thể không và đưa bạn vào một cảm giác an toàn sai lầm, cho đến khi thư viện bạn đang sử dụng thay đổi thay đổi việc triển khai bên dưới và bây giờ bạn thấy rằng tất cả mã của bạn bị phá vỡ Không có lý do đặc biệt.

Các đề xuất về cách giải quyết được liệt kê ở đây là tốt. Nếu bạn cần truy cập được lập chỉ mục, sử dụng một danh sách. Hãy cẩn thận với việc sử dụng các trình lặp hoặc toArray với một Set chung, bởi vì a) không có gì đảm bảo cho việc đặt hàng và b) không có gì đảm bảo rằng thứ tự sẽ không thay đổi với các lần gọi tiếp theo hoặc với các triển khai cơ bản khác nhau. Nếu bạn cần một cái gì đó ở giữa, một Sắp xếp Sắp xếp hoặc LinkedHashset là những gì bạn muốn.

// Tôi thực sự muốn giao diện Set có phần tử get-ngẫu nhiên.


1

java.util.Setlà một bộ sưu tập các mặt hàng chưa đặt hàng. Sẽ không có nghĩa gì nếu Set có get (int index), vì Set không có chỉ mục và bạn cũng chỉ có thể đoán giá trị.

Nếu bạn thực sự muốn điều này, hãy mã hóa một phương thức để lấy phần tử ngẫu nhiên từ Set.


0

Bạn có thể làm new ArrayList<T>(set).get(index)


Cái này trả về một List of Set và get (index) trả về Set. Thay vào đó, tôi đã sử dụng: new ArrayList<T>(t).get(0) Tôi nghĩ rằng có sự phản đối hợp lệ đối với ý tưởng lấy một phần tử cụ thể từ Tập hợp theo chỉ mục. Nhưng thật tuyệt nếu Set có chức năng thành viên duy nhất (), đối với Bộ có kích thước 1, cung cấp quyền truy cập dễ dàng vào phần tử duy nhất trong Bộ. Điều này sẽ cứu những người đã nói ở trên new ArrayListhoặcfor (Foo foo : foos) { return foo; }
Doug Moscrop

0

Nếu bạn không quan tâm đến tập hợp được sắp xếp thì bạn có thể quan tâm đến dự án bản đồ cây được lập chỉ mục .

TreeSet / TreeMap nâng cao cung cấp quyền truy cập vào các phần tử theo chỉ mục hoặc nhận chỉ mục của một phần tử. Và việc thực hiện dựa trên việc cập nhật trọng lượng nút trong cây RB. Vì vậy, không lặp lại hoặc sao lưu bởi một danh sách ở đây.


0

Set là một giao diện và một số lớp triển khai của nó là Hashset, TreeSet và LinkedHashset. Nó sử dụng HashMap dưới mui xe để lưu trữ các giá trị. Vì HashMap không bảo toàn thứ tự, nên không thể lấy giá trị theo chỉ mục.

Bây giờ bạn phải suy nghĩ về cách Set đang sử dụng HashMap vì HashMap lưu trữ một cặp khóa, giá trị nhưng Set thì không. câu hỏi hợp lệ. khi bạn thêm một phần tử vào Set, bên trong, nó sẽ duy trì HashMap trong đó khóa là phần tử bạn muốn nhập trong Set và giá trị là hằng số giả. Dưới đây là một thực hiện nội bộ của chức năng thêm. Do đó, tất cả các khóa trong HashMap sẽ có cùng giá trị không đổi.

// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

Tất cả Setcác triển khai đang sử dụng HashMapdưới mui xe để lưu trữ các giá trị mà bạn có thể chứng minh yêu cầu đó TreeSetkhông?
greybeard

1
the keys in the HashMap will have the same constant value các chìa khóa trongHashMap bản đồ sẽ được ánh xạ tới một và giống nhau bất biếnObject
greybeard


-3

Để lấy phần tử trong Tập hợp, tôi sử dụng theo sau:

public T getElement(Set<T> set, T element) {
T result = null;
if (set instanceof TreeSet<?>) {
    T floor = ((TreeSet<T>) set).floor(element);
    if (floor != null && floor.equals(element))
    result = floor;
} else {
    boolean found = false;
    for (Iterator<T> it = set.iterator(); !found && it.hasNext();) {
    if (true) {
        T current = it.next();
        if (current.equals(element)) {
        result = current;
        found = true;
        }
    }
    }
}
return result;
}

chức năng không phải là những gì câu hỏi yêu cầu. chúng ta cần chỉ số, không phải giá trị. chức năng của bạn đang làm gì? có vẻ như nó chỉ trả về phần tử nếu nó bằng một phần tử bên trong. cái này làm gì mà chứa () không?
Janus Troelsen

Định Tnghĩa ở đâu? Tại sao if (true)?
lượng tử
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.