Поиск LinkedHashMap, более быстрый метод, чем последовательный?

Мне интересно, есть ли более эффективный метод для получения объектов из моей LinkedHashMap с отметками времени, превышающими указанное время. т.е. что-то лучше, чем следующее:

    Iterator<Foo>  it = foo_map.values().iterator();
    Foo foo;

    while(it.hasNext()){
        foo = it.next();
        if(foo.get_timestamp() < minStamp) continue;

        break;
    }

В моей реализации каждый из моих объектов имеет по существу три значения: «id», «timestamp» и «data». Объекты вставляются в порядке их временных меток, поэтому, когда я вызываю итератор для набора, я получаю упорядоченные результаты (как того требует связанный контракт хэш-карты). Карта привязана к идентификатору объекта, поэтому я могу быстро найти их по идентификатору.

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

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


person sean262 none    schedule 08.08.2013    source источник


Ответы (1)


Нет более быстрого способа... если вы просто используете LinkedHashMap.

Если вам нужен более быстрый доступ, вам нужно использовать другую структуру данных. Например, TreeSet с соответствующим компаратором может быть лучшим решением для этого аспекта вашей проблемы. Например, если ваш TreeSet упорядочен по дате, то вызов tailSet с соответствующим фиктивным значением может дать вам все элементы, большие или равные заданной дате.


Поскольку результаты уже отсортированы, есть ли какой-либо алгоритм, которому я могу передать итератор (или коллекцию), который может выполнять поиск быстрее, чем последовательный?

Не для LinkedHashMap.

Однако, если бы упорядоченный список был вместо этого ArrayList, вы могли бы использовать «бинарный поиск» в списке ... при условии, что вы можете заблокировать его, чтобы предотвратить одновременные изменения во время поиска. (На самом деле параллелизм — это потенциальная проблема, которую следует учитывать независимо от того, как вы это реализуете... включая ваш текущий линейный поиск.)


Если вы хотите сохранить возможность выполнять id поиск, вам понадобятся две структуры данных; например TreeSet и HashMap, которые совместно используют свои объекты-элементы. TreeSet, вероятно, будет более эффективным, чем попытка поддерживать ArrayList в порядке предположения о случайных вставках и/или случайных удалениях.

person Stephen C    schedule 08.08.2013
comment
Данные заблокированы, поэтому параллелизм не является проблемой. Да, бинарный поиск был бы огромным улучшением, но я не могу отказаться от сопоставления идентификаторов. - person sean262 none; 08.08.2013
comment
Я думаю, две структуры данных могут это сделать. Обычная старая хэш-карта и список массивов, которые содержали объекты, содержащие только идентификатор и отметку времени. Удаление объектов было бы немного сложнее, поскольку для удаления соответствующей метки времени также потребовался бы поиск в массиве. Но я думаю, что поиск по отметке времени будет намного быстрее. - person sean262 none; 08.08.2013