| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java: Общие вопросы > Исследование роли accessOrder в жизни |
| Автор: Royan 22.4.2008, 11:18 | ||||||||
| Есть у данной исплементации Map конструктор со следующей сигнатурой: LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) Я решил поэкспериментировать, вот мои результаты:
Output:
Если к-то не заметил, то в случае когда параметр accessOrder выставлен в true, то всякий раз когда мы пользуемся итератором, последний элемент к которому произошло обращение при помощи LinkedHashMap#get(), LinkedHashMap#put() и LinkedHashMap#putAll() переходит в конец списка (в случае putAll() для каждого добавленного элемента). Объяснил коряво ну суть такая. Если accessOrder в true, и мы внутри цикла итерируем по LinkedHashMap, то всякий раз когда мы делаем вызов вышеописанных методов внутри нашего цикла, то следующий раз когда мы будем итерировать то начнем с того элемента который дернули последним. Именно поэтому в строке 26 авыводится 9, а не 0 (как было бы если бы accessOrder был выставлен в false) break'и в циклах стоят, дабы не спровоцировать ConcurrentModificationException, поскольку опять же обращение get(), put() и putAll() модифицирует внутреннюю структуру списка. Еще одно дополнение, вызовы get() должны быть последовательным поэтому если сразу дернуть, к примеру, 2-й элемент, то все будет работать в обычных условиях:
Output:
Все это я затеял с тем, чтобы понять зачем вообще весь этот огород было городить? В каких задачах нужна подобная функциональность? |
| Автор: Andy_L20066 22.4.2008, 12:33 |
| интересный вопрос.... ну могу сказать следующее: если accessOrder у нас true и выполняется (Integer i : map.keySet()) тогда переменная 'i' будет постоянно отвечать за индекс первого елемента в мапе... то есть это может быть 9, как в первом случае... потому что этот елемент сейчас на первом месте в мапе... тоесть вернется елемент с ключем 9... или если во втором случае у нас был доступ сначала ко второму елементу(map.get(i+2)), потом map.get(i) вернуло 0... ну правильно... потому что второй елемент поместился в конец мапы.... а на первом месте сейчас елемент с ключем 0....если accessOrder у нас false - тогда (Integer i : map.keySet()) будет нулевой... и будет возвращатся елемент с ключем '0'... тоесть с тем какие елементы в даный момент возвращаются, на мой взгляд - все логично... думаю функциональность такая нужна для того чтобы можно было иметь копию мапы из точным порядком елементов... хотя черт его знает.... поправьте если может чьо не так изложил... |
| Автор: Royan 24.4.2008, 12:13 |
Окей возьмем к примеру LRU кэш. Например мне нужно вытащить из LinkedHashMap'а 5-ый элемент... это что же получается - для того, чтобы добраться до него я должен буду проитерировать по элементам с 1 по 4-ый, чтобы потом взять сверху 5-ый? Тогда теряется суть кэша. В какой-то одной стороне должны оказываться самые часто используемые элементы, в другой самые редко используемые, а тут я взял и перебрал все с 1 по 4 как будто они мне были нужны. |
| Автор: LSD 24.4.2008, 12:54 | ||
Из Map никто не вытаскивает элементы по номеру, т.к. в общем случае (например при использовании HashMap) неизвестно что там будет под пятым номером. Элементы из Map вытаскиваются по ключу. Итератор по Map используется или для полного перебора всех элементов, или для перебора их в определенном порядке (SortedMap или LRU Map) который индивидуален для каждого типа Map. |
| Автор: Royan 27.4.2008, 20:15 | ||
Проблема в том, что в LRU реализации LinkedHashMap невозможно проитерировать более одного элемента за раз, так как внутренняя структура карты меняется после каждого выхова метода get |
| Автор: LSD 27.4.2008, 22:57 | ||||
Возможно, просто надо использовать правильный итератор
|
| Автор: Royan 28.4.2008, 00:35 | ||||
Итератор заработал - эффект пропал, это я, конечно, не к тому, чтобы ты полез дебажить
Output:
|
| Автор: LSD 28.4.2008, 11:38 | ||
Клево придумано То что ты хочешь, реализуется так:
Есть такая штука ListIterator, вот он позволяет указывать с какого места начати итерацию, и позволяет итерировать как вперед, так и назад. Но существует, только для List. P.S. И не пиши new String(">" + i) это совершенно избыточный код, приводящий к созданию лишних объектов. Вполне достаточно ">" + i. |