簡體   English   中英

為什么java.util.Set無法返回任何值?

[英]why java.util.Set can't return any value?

java.util.Set僅指定返回所有記錄(通過Iterator或數組)的方法。

為什么沒有選項可以從Set返回任何值?

在現實生活中有很多意義。 例如,我有一碗草莓,我只想拿一個。 我完全不在乎哪個。

為什么我不能在Java中做同樣的事情?

這是不負責任的。 您必須詢問Java Collections框架的原始設計者。

一個可能的原因是具有不確定行為的方法往往會出現問題:

  • 它們使單元測試更加困難。
  • 它們使錯誤更難以追蹤。
  • 他們更容易被不費心閱讀API文檔的程序員誤解和濫用。

對於基於哈希表的集合組織,“獲取某些元素”方法的行為將是不確定的,或者至少很難確定/預測。

順便說一下,您可以像下面這樣簡單地獲取非空集的某些元素:

Object someObject = someSet.iterator().next();

獲取一個真正的(偽隨機)元素會比較棘手/昂貴,因為您無法索引集合中的元素。 (您需要將所有設置的元素提取到數組中...)


回顧這一點,我意識到還有另一個原因。 Set只是基於Set的數學概念,而數學中的集合元素沒有順序。 談論數學集合的第一個元素根本沒有意義。

java.util.Set是無序集合; 您可以將其視為裝有物品的袋子,但沒有任何特定的順序。 擁有get(int index)方法是沒有意義的,因為集合中的元素沒有索引。

標准Java庫的設計人員沒有提供從Set獲取隨機元素的方法。 如果您想知道為什么,那是您只能推測的事情。 也許他們認為沒有必要,或者甚至沒有考慮。

自己編寫一個從Set中獲取隨機元素的方法很容易。

如果您不關心元素的索引,請嘗試使用Queue而不是Set。

    Queue q = new ArrayDeque();
    q.element(); // retrieves the first object but doesn't remove
    q.poll(); // retrieves and removes first object

雖然沒有特別要求,但SortedSet和NavigableSet提供了保證順序和支持此順序的方法。 您可以使用first()last()

SortedSet<E> set = ...
E e1 = set.first(); // a value
E e2 = set.last(); // also a value.

實際上,迭代器比使用get(position)好得多(您可以在java.util.List )。 它允許在迭代過程中修改一件東西。 您沒有將它們放在集合中的原因可能是因為它們中的大多數不能保證插入順序。 您總是可以做類似new ArrayList<?>(mySet).get(position)

如果您不關心性能,則可以創建一個新類型並將其備份到arraylist中。

(請注意在放棄之前,這只是該想法的幼稚實現,而不是提議的最終解決方案)

import ...

public class PickableSet<E> extends AbstractSet<E>{

    private final List<E> arrayList = new ArrayList<E>();
    private final Set<E>  hashSet   = new HashSet<E>();
    private final Random  random    = new Random();

    public boolean add( E e ) {
        return hashSet.add( e ) && arrayList.add( e );
    }
    public int size() {
        return arrayList.size();
    }
    public Iterator<E> iterator() {
        return hashSet.iterator();
    }

    public E pickOne() {
        return arrayList.get( random.nextInt( arrayList.size() ) );
    }
}

當然,由於您使用的是其他接口,因此必須強制轉換以調用該方法:

Set<String> set = new PickableSet<String>();
set.add("one");
set.add("other");
String oneOfThem = ((PickableSet)set).pickOne();

https://gist.github.com/1986763

好吧,您可以像這樣進行一些工作

    Set<String> s = new HashSet<String>();
    Random r = new Random();
    String res = s.toArray(new String[0])[r.nextInt(s.toArray().length)];

這將從集合中隨機選擇一個對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM