Нравится это:
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);
Как отмечали другие, сброс отсортированного потока записей в обычный 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
.
Ваш потоковый код не будет даже сортировать карту, потому что он выполняет операцию с 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 со связанным списком, проходящим через него. Вы можете использовать это, если вам нужно поддерживать порядок вставки, например, при реализации очереди.