如何将这段代码简化为单个lambda表达式?想法是有一个地图列表,我想使用键上的过滤器来创建一个新的地图列表。在此示例中,我想重新映射它,以便仅保留键“ x”和“ z”。
Map<String, String> m0 = new LinkedHashMap<>();
m0.put("x", "123");
m0.put("y", "456");
m0.put("z", "789");
Map<String, String> m1 = new LinkedHashMap<>();
m1.put("x", "000");
m1.put("y", "111");
m1.put("z", "222");
List<Map> l = new ArrayList<>(Arrays.asList(m0, m1));
List<Map> tx = new ArrayList<>();
for(Map<String, String> m : l) {
Map<String, String> filtered = m.entrySet()
.stream()
.filter(map -> map.getKey().equals("x") || map.getKey().equals("z"))
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
tx.add(filtered);
}
System.err.println("l: " + l);
System.err.println("tx: " + tx);
输出:
l: [{x=123, y=456, z=789}, {x=000, y=111, z=222}]
tx: [{x=123, z=789}, {x=000, z=222}]
当然,您可以将整个操作转换为一个Stream操作。
// no need to copy a List (result of Array.asList) to an ArrayList, by the way
List<Map<String, String>> l = Arrays.asList(m0, m1);
List<Map<String, String>> tx = l.stream().map(m -> m.entrySet().stream()
.filter(map -> map.getKey().equals("x") || map.getKey().equals("z"))
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue())))
.collect(Collectors.toList());
但请注意,通过a进行流式传输Map
和过滤是一项具有线性时间复杂度的操作,因为它会根据过滤器检查每个映射的每个键,而您只需要保留很少的实际键。因此,这里使用起来更简单,更有效(对于较大的地图)
List<Map<String, String>> tx = l.stream()
.map(m -> Stream.of("x", "y")
.filter(m::containsKey).collect(Collectors.toMap(key->key, m::get)))
.collect(Collectors.toList());
每个地图只会执行四个查询。如果麻烦您,您甚至可以将其减少为两次查找,但是,常数因数与总体时间复杂度无关,如果地图具有恒定的时间查找,则总时间复杂度将是恒定的时间,例如HashMap
。即使对于具有O(log(n))
查找时间复杂度TreeMap
的映射(例如),如果映射大于示例代码的三个映射,这也将比线性扫描更有效。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句