Java Сортировка карты с помощью Steams VS TreeMap

Нравится это:

const input = [
  [ 'foo', 3.672698 ],
  [ 'bar', 71.999747 ],
  [ 'baz', 107.400002 ],
];

const output = input.reduce((acc, item) => {
  acc.push({
    name: item[0],
    money: item[1]
  });
  return acc;
}, [])

console.log(output);

3
задан 孙兴斌 19 January 2019 в 05:06
поделиться

2 ответа

Как отмечали другие, сброс отсортированного потока записей в обычный HashMap ничего не сделает ... LinkedHashMap - логичный выбор.

Однако альтернативой вышеупомянутым подходам является полное использование API Stream Collectors.

Collectors имеет метод toMap, который позволяет предоставить альтернативную реализацию для Map. Таким образом, вместо HashMap вы можете запросить LinkedHashMap, например, так:

unsortedMap.entrySet()
    .stream()
    .sorted(Map.Entry.comparingByKey())
    .collect(Collectors.toMap(
       Map.Entry::getKey,
       Map.Entry::getValue,
       (v1, v2) -> v1, // you will never merge though ask keys are unique.
       LinkedHashMap::new
    ));

Между использованием TreeMap и LinkedHashMap ... Сложность построения, вероятно, будет такой же, как O ( n log n) ... Очевидно, что решение TreeMap является лучшим подходом, если вы планируете продолжать добавлять к нему больше элементов ... Я думаю, вам следовало начать с TreeMap в этом случае. Опция LinkedHashMap имеет преимущество в том, что поиск будет O (1) на Связанной или исходной несортированной карте, тогда как TreeMap похож на O(log n), так что если вам потребуется сохранить несортированную карту для эффективного поиска, тогда как если вы создадите LinkedHashMap, вы можете сбросить исходную несортированную карту (тем самым сэкономив немного памяти).

Чтобы сделать вещи немного более эффективными с LinkedHashMap, вы должны предоставить хорошую оценку требуемого размера при построении, чтобы не было необходимости динамического изменения размера, поэтому вместо LinkedHashMap::new вы говорите () -> new LinkedHashMap<>(unsortedMap.size()).

Я считаю, что использование TreeMap более изящно ... так как код меньше, так что если нет фактической проблемы с производительностью, которую можно было бы решить с помощью подхода несортированной и отсортированной связанной карты, я бы используйте Tree.

0
ответ дан Valentin Ruano 19 January 2019 в 05:06
поделиться

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

Map<String, Integer> sortedMap = new LinkedHashMap<>();
unsortMap.entrySet()
    .stream()
    .sorted(Map.Entry.comparingByKey())
    .forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue()));

Но теперь ваши два примера даже не имеют одинаковую структуру данных. TreeMap поддерживается деревом (красно-черным, если я правильно помню). Вы бы использовали TreeMap, если хотите иметь возможность выполнять итерацию в отсортированном виде или быстро искать ключ. LinkedHashMap - это hashmap со связанным списком, проходящим через него. Вы можете использовать это, если вам нужно поддерживать порядок вставки, например, при реализации очереди.

0
ответ дан Tim Biegeleisen 19 January 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: