java 收集EntrySet流到LinkedHashMap

js4nwp54  于 2023-03-28  发布在  Java
关注(0)|答案(3)|浏览(150)

我想将流收集到LinkedHashMap<String, Object>
我有一个存储在LinkedHashMap<String, Object> resources中的JSON资源。然后我通过流式传输此Map的EntrySet来过滤掉JSON元素。目前我正在将流的元素收集到常规的HashMap中。但在此之后,我将向Map添加其他元素。我希望这些元素以插入顺序排列。

final List<String> keys = Arrays.asList("status", "createdDate");

Map<String, Object> result = resources.entrySet()
        .stream()
        .filter(e -> keys.contains(e.getKey()))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

result.put("date", "someDate");
return result;

这就是为什么我想收集流到一个LinkedHashMap<String, Object> .我如何才能实现这一点?

eqzww0vc

eqzww0vc1#

你可以用Stream来实现:

Map<String, Object> result = resources.entrySet()
            .stream()
            .filter(e -> keys.contains(e.getKey()))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x, y) -> y, LinkedHashMap::new));

(x, y) -> y部分是因为mergeFunction在查找重复键时,它返回找到的第二个键的值。第四部分是mapFactory,它是供应商提供的一个新的空Map,结果将插入其中。

iszxjhcz

iszxjhcz2#

使用Map.forEach执行此操作的另一种方法是:

Map<String, Object> result = new LinkedHashMap<>();
resources.forEach((key, value) -> {
    if (keys.contains(key)) {
        result.put(key, value);
    }
});
result.put("date", "someDate");

如果你可以考虑在keySet上迭代:

Map<String, Object> result = new LinkedHashMap<>();
resources.keySet().stream()
        .filter(keys::contains)
        .forEach(key -> result.put(key,resources.get(key)));
result.put("date", "someDate");
jljoyd4f

jljoyd4f3#

接受的答案包含与默认答案不同的合并(抛出)。遗憾的是,Java Collectors类中不存在三个参数的toMap(keyFunction, valueFunction, mapFactory)重载。因为我只需要LinkedHashMap,所以我只是将它作为一个自定义的助手方法,从复制(必要时)该类的内部。行为与两个参数的toMap相同,除了结果Map是LinkedHashMap

class Helper {

    private static <K,V,M extends Map<K,V>> BinaryOperator<M> uniqKeysMapMerger() {
        return (m1, m2) -> {
            for (Map.Entry<K,V> e : m2.entrySet()) {
                K k = e.getKey();
                V v = Objects.requireNonNull(e.getValue());
                V u = m1.putIfAbsent(k, v);
                if (u != null) throw new IllegalStateException(String.format("Duplicate key %s (attempted merging values %s and %s)", k, u, v));
            }
            return m1;
        };
    }

    private static <T,K,V> BiConsumer<Map<K,V>,T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) {
        return (map, element) -> {
            K k = keyMapper.apply(element);
            V v = Objects.requireNonNull(valueMapper.apply(element));
            V u = map.putIfAbsent(k, v);
            if (u != null) throw new IllegalStateException(String.format("Duplicate key %s (attempted merging values %s and %s)", k, u, v));
        };
    }

    public static <T,K,U> Collector<T,?,Map<K,U>> toLinkedHashMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) {
        return Collector.of(LinkedHashMap::new, uniqKeysMapAccumulator(keyMapper, valueMapper), uniqKeysMapMerger());
    }

}

相关问题