Почему java.util.Set не имеет get (int index)? - PullRequest
227 голосов
/ 20 апреля 2009

Я уверен, что есть веская причина, но кто-то может объяснить, почему в интерфейсе java.util.Set отсутствует get(int Index) или какой-либо подобный метод get()?

Кажется, что наборы отлично подходят для размещения вещей, но я не могу найти элегантный способ извлечь из него один предмет.

Если я знаю, что хочу первый элемент, я могу использовать set.iterator().next(), но в противном случае мне кажется, что я должен привести к массиву, чтобы получить элемент по определенному индексу?

Каковы подходящие способы извлечения данных из набора? (кроме использования итератора)

Я уверен, что тот факт, что он исключен из API, означает, что есть веская причина не делать этого - может кто-нибудь, пожалуйста, просветите меня?

EDIT: Некоторые очень хорошие ответы здесь, а некоторые говорят «больше контекста». Конкретным сценарием был тест dbUnit, в котором я мог разумно утверждать, что возвращенный набор из запроса имел только 1 элемент, и я пытался получить доступ к этому элементу.

Однако вопрос более актуален без сценария, поскольку он остается более сфокусированным:

В чем разница между множеством и списком .

Спасибо всем за фантастические ответы ниже.

Ответы [ 18 ]

3 голосов
/ 18 августа 2010

Я столкнулся с ситуациями, когда я действительно хотел установить Sorted с доступом по индексу (я согласен с другими авторами, что доступ к несортированному Set с индексом не имеет смысла). Примером может служить дерево, где я хотел, чтобы дети сортировались, а дублировать детей не разрешалось.

Мне нужен был доступ через индекс для их отображения, и установленные атрибуты пригодились для эффективного устранения дубликатов.

Не найдя подходящей коллекции в коллекциях java.util или google, я понял, что реализовать ее самому просто. Основная идея заключается в том, чтобы обернуть SortedSet и создать список, когда требуется доступ через индекс (и забыть список при изменении SortedSet). Это, конечно, эффективно работает только тогда, когда изменение упакованного SortedSet и доступ к списку разделены во время существования Коллекции. В противном случае он ведет себя как список, который часто сортируется, т. Е. Слишком медленно.

С большим количеством детей это значительно улучшило производительность по сравнению со списком, который я сортировал через Collections.sort.

2 голосов
/ 01 апреля 2015

Обратите внимание, что через индекс можно получить доступ только к двум основным структурам данных.

  • Массив Структура данных может быть доступна через индекс с O(1) сложностью по времени для выполнения операции get(int index).
  • LinkedList Структура данных также может быть доступна через индекс, но с O(n) сложностью по времени для достижения операции get(int index).

В Java ArrayList реализован с использованием Array структура данных.

Хотя Задать структуру данных обычно можно реализовать с помощью HashTable / HashMap или BalancedTree структура данных, для быстрого определения того, существует ли элемент и добавление несуществующего Элемент, обычно хорошо реализованный Set может достигать O(1) сложность времени contains операция. В Java HashSet является наиболее распространенной используемой реализацией Set , она реализуется путем вызова HashMap API, а HashMap реализуется с использованием отдельного сцепления со связанными списками ( комбинация Array и LinkedList ).

Поскольку Set может быть реализован через другую структуру данных, для него нет метода get(int index).

1 голос
/ 21 мая 2012

Причина, по которой интерфейс Set не имеет вызова типа get index или даже чего-то еще более простого, такого как first () или last (), заключается в том, что это неоднозначная операция, и, следовательно, потенциально опасная операция. Если метод возвращает Set, и вы вызываете, скажем, метод first () для него, каков ожидаемый результат, учитывая, что универсальный Set не дает никаких гарантий относительно порядка? Результирующий объект может очень хорошо варьироваться между каждым вызовом метода, или он может не вызывать у вас ложного чувства безопасности, пока используемая вами библиотека не изменит реализацию, а теперь вы обнаружите, что весь ваш код прерывается для без особых причин.

Предложения по поводу обходных путей, перечисленные здесь, хороши. Если вам нужен индексированный доступ, используйте список. Будьте осторожны с использованием итераторов или toArray с универсальным множеством, потому что a) нет никакой гарантии на порядок и b) нет никакой гарантии, что порядок не изменится с последующими вызовами или с другими базовыми реализациями. Если вам нужно что-то промежуточное, вам нужен SortedSet или LinkedHashSet.

// Хотелось бы, чтобы в интерфейсе Set был элемент get-random-random.

1 голос
/ 29 августа 2018

Попробуйте этот код как альтернативный вариант для доступа через индексы

import java.io.*;
import java.util.*;
class GFG {
public static void main (String[] args) {
    HashSet <Integer> mySet=new HashSet<Integer>();
    mySet.add(100);
    mySet.add(100);
    int n = mySet.size();
    Integer arr[] = new Integer[n];
    arr = mySet.toArray(arr);
    System.out.println(arr[0]);
    }
}

Это напечатает 100.

1 голос
/ 10 июня 2016

java.util.Set - это коллекция неупорядоченных предметов. Это не имеет никакого смысла, если Set имеет get (int index), потому что Set не имеет индекса, а также вы можете только угадать значение.

Если вы действительно этого хотите, закодируйте метод для получения случайного элемента из Set.

0 голосов
/ 20 июня 2010

Чтобы получить элемент в наборе, я использую следующий:

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;
}
0 голосов
/ 03 февраля 2012

Вы можете сделать new ArrayList<T>(set).get(index)

0 голосов
/ 27 января 2014

Если вы не возражаете против сортировки набора, вам может быть интересно взглянуть на проект indexed-tree-map .

Усовершенствованный TreeSet / TreeMap предоставляет доступ к элементам по индексу или получению индекса элемента. И реализация основана на обновлении весов узлов в дереве RB. Поэтому здесь нет итерации или резервного копирования по списку.

...