HashSet вместо недостатка производительности ArrayList

В одном из своих проектов я использовал ArrayList<ArrayList<Integer>> в качестве структуры данных графа.

Итак, график:

HashSet вместо недостатка производительности ArrayList

будет эквивалентен списку ниже:

HashSet вместо недостатка производительности ArrayList

Но я изменил структуру данных с ArrayList<ArrayList<Integer>> на Map<Integer, Set<Integer>>, поэтому тот же график выше теперь будет эквивалентен карте:

HashSet вместо недостатка производительности ArrayList

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

Map был выбран из-за простоты управления структурой данных.

Проблема в том, что когда я изменил структуру данных, производительность упала почти в 2 раза.

Вот наиболее часто используемые операции в моем проекте:

В первой реализации:

int index = someIndex();
int v1 = listoflists.get(index).get(0);
int v2 = listoflists.get(index).get(1);

Во второй реализации:

int index = somIndex();
Set<Integer> sets = map.get(index);
Integer[] set =  sets.toArray(new Integer[sets.size()]);
int v1 = set[0];
int v2 = set[1];

Иногда мне нужно получить один, два или максимум три элемента.

Есть идеи улучшить производительность второй реализации?

Когда вы извлекаете элементы из Set, выполняете ли вы одно и то же действие со всеми из них?

MTCoster 06.12.2018 13:08

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

Sharon Ben Asher 06.12.2018 13:09

1. Я не уверен, зачем кому-то поощрять представление Graphs как List<List<Integer>> или даже Map<Integer, Set<Integer>>! 2. Поскольку ваши операции основаны на индексах, использование Set не имеет особого смысла, можете ли вы не использовать функцию limit и просто элементы 3 из Set и делать то, что вы делаете дальше.

Naman 06.12.2018 13:10

@SharonBenAsher нет, это был мой способ получить эти элементы.

xmen-5 06.12.2018 13:12

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

Sharon Ben Asher 06.12.2018 13:12

Я подозреваю, что toArray() создает новый массив и копирует в него все элементы (это действительно зависит от реализации), почему бы не использовать iterator()?

Sharon Ben Asher 06.12.2018 13:14

@SharonBenAsher, я это проверю.

xmen-5 06.12.2018 13:15

Я только что посмотрел на документация, и он довольно четко описывает создание нового массива, копирование и т. д.

Sharon Ben Asher 06.12.2018 13:16
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
8
61
1

Ответы 1

Integer[] set =  sets.toArray(new Integer[sets.size()]);

Приведенная выше строка кода добавляет дополнительную сложность. Оптимизируйте его с помощью Итератора,

int index = somIndex();
Set<Integer> sets = map.get(index);
Iterator iterator = sets.iterator(); 

while (iterator.hasNext()) { 
   System.out.println(iterator.next()); 
}

Иногда вам требуется всего несколько значений, поэтому выполняйте итерацию соответственно.

Другие вопросы по теме