我正在使用 Java 流对一些数据执行一些转换。我想忽略映射中包含空值的任何值。
例子:
HashMap<String, Object> vals = new HashMap<>();
vals.put("null", null);
vals.put("string1", "1 ");
我试过使用过滤器:
Map<String, Object> nullMap = vals.entrySet().stream()
.filter(e -> e.getValue() != null)
.collect(Collectors.toMap(
e -> e.getKey().trim(),
e -> (e.getValue() instanceof String ? ((String) e.getValue()).trim() : e.getValue())))
但是,返回的对象已完全删除空键/值对(在我的示例中为“null”-> null)。在 Java 流中 .filter
步骤之后的任何后续处理过程中,如何保留键“null”并忽略它?
在上面的示例中,我希望返回一个 Map,其中键值对被修剪,空值在修剪步骤中被“忽略”。
最佳答案
toMap
收集器不允许null
值,所以你不能用它来产生 Map
包含 null
值(value)观。
如果您的输入映射是可变的并且可以更改它,您可以像这样简单地修剪值
HashMap<String, Object> vals = new HashMap<>();
vals.put("null", null);
vals.put("string1", "1 ");
vals.replaceAll((key,val) -> val instanceof String? ((String)val).trim(): val);
如果修改源映射不是一个选项,或者你真的必须修剪键,你必须使用不同的收集器。您可以临时定义一个收集器,例如
HashMap<String, Object> result = vals.entrySet().stream()
.collect(HashMap::new, (m,e) -> m.put(e.getKey().trim(),
e.getValue() instanceof String? ((String)e.getValue()).trim(): e.getValue()),
Map::putAll);
为了更好的可读性,即避免重复相同的表达式,我们可以使用 block lambda 语法和局部变量,例如
HashMap<String, Object> result = vals.entrySet().stream()
.collect(
HashMap::new,
(m,e) -> {
Object value = e.getValue();
m.put(e.getKey().trim(), value instanceof String? ((String)value).trim(): value);
}, Map::putAll);
申请时注意trim()
对于键,键可能会发生冲突,即使它们在原始 map 中是唯一的,例如当有 " key1"
和 "key1 "
. toMap
收集器会抛出这种情况,而上面创建的临时收集器会在没有警告的情况下简单地覆盖冲突映射之一。
关于java - 忽略 Java 流中的 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63343637/