Java: лучший способ сохранить произвольный индекс ArrayList - PullRequest
5 голосов
/ 10 февраля 2012

Я знаю, что не могу сохранить значение в индексе ArrayList, который еще не использовался, то есть меньше размера. Другими словами, если myArrayList.size () равен 5, тогда, если я пытаюсь сделать

myArrayList.set(10, "Hello World") 

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

Это выглядит как:

  • Такое же поведение в векторе
  • Если мне нужно иметь возможность произвольного доступа (то есть элемента в позиции X), тогда я могу выбрать Vector и ArrayList.
  • Я мог бы использовать HashMap и использовать индекс в качестве ключа, но это действительно неэффективно.

Итак, каково элегантное решение того, что выглядит как обычный случай? Должно быть, я что-то упустил ...

Ответы [ 7 ]

4 голосов
/ 10 февраля 2012

Я мог бы использовать HashMap и использовать индекс в качестве ключа, но это действительно неэффективно.

Зависит.Если индексы, которые вы используете, очень скудны, возможно, было бы намного лучше использовать карту.Если индексы имеют тенденцию быть близко друг к другу, я думаю, что нет лучшего способа, чем заполнить его нулями.Просто напишите для него служебную функцию, которую вы можете использовать снова и снова, вместо того, чтобы повторять цикл везде, где вам это нужно, что-то вроде этого:

private void padTo(List<?> list, int size) {
    for (int i=list.size(); i<size; i++)
        list.add(null);
}
3 голосов
/ 10 февраля 2012

Вы можете использовать TreeMap<key, value>, который отсортирован в естественном порядке по value.

Здесь вы можете сохранить значение в качестве индекса. Вы можете вставить любое значение, оно не должно быть в порядке. Это кажется самым простым решением.

3 голосов
/ 10 февраля 2012

Вы можете использовать вместо Map<Integer, MyClass>. В частности, если вы используете HashMap, это также будет O(1) - хотя это будет медленнее, чем ArrayList.

1 голос
/ 10 февраля 2012

HashMap, вероятно, гораздо менее неэффективен, чем вы думаете, попробуйте.В противном случае, я не могу придумать способа сделать это более элегантно, чем зацикливание и заполнение нулем.Если вы хотите, по крайней мере, элегантность изложения, вы всегда можете создать подкласс ArrayList и добавить метод expandingSet (position, value), чтобы скрыть все циклы и тому подобное, или что-то еще.Возможно, это не вариант, хотя?Если бы не просто использовать метод утилиты где-то еще для него, но это не так хорошо, imho, хотя он будет работать и с другими типами списков, я думаю ...

Возможно, класс-обертка будет лучшимиз обоих миров, или, возможно, это просто повлечет за собой ненужные накладные расходы ...

1 голос
/ 10 февраля 2012

Если вам определенно нужно использовать список, а не карту, то лучше переопределить методы add и set массива, чтобы сначала поставить нулевые значения в индексах раньше. Нет другого лучшего способа ИМО

1 голос
/ 10 февраля 2012

Звучит так, как будто вы хотите обычный массив:

  • Вы хотите произвольный доступ
  • Вы хотите указать большой размер
0 голосов
/ 10 февраля 2012

Если вы ищете разреженный массив (где большинство индексов будут пустыми), то лучшим выбором будет карта какого-то типа (вероятно, HashMap). Любое решение для работы с массивами будет вынуждено зарезервировать пространство для всех пустых индексов, что не очень эффективно для пространства, и HashMap достаточно быстр для большинства обычных целей.

Если вы в конечном итоге заполните массив до некоторого n, вам нужно будет добавить нули в цикле, чтобы получить нужный индекс. Вы можете сделать это несколько более эффективным, задав начальную емкость из числа элементов, которые вы в конечном итоге захотите сохранить (это предотвращает необходимость изменения размера ArrayList). new ArrayList(n) будет работать нормально. К сожалению, не существует простого способа сделать его определенного размера для начала, кроме добавления элементов в цикл при его создании.

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