忽略Java流中的null
我正在使用Java流对一些数据执行一些转换。我希望忽略映射中包含空值的任何值 例如:忽略Java流中的null,java,java-stream,Java,Java Stream,我正在使用Java流对一些数据执行一些转换。我希望忽略映射中包含空值的任何值 例如: HashMap vals=newhashmap(); VAL.put(“空”,空); VAL.put(“第1条”、“第1条”); 我尝试过使用过滤器: Map nullMap=vals.entrySet().stream() .filter(e->e.getValue()!=null) .collect(collector.toMap)( e->e.getKey().trim(), e->(e.getValu
HashMap vals=newhashmap();
VAL.put(“空”,空);
VAL.put(“第1条”、“第1条”);
我尝试过使用过滤器:
Map nullMap=vals.entrySet().stream()
.filter(e->e.getValue()!=null)
.collect(collector.toMap)(
e->e.getKey().trim(),
e->(e.getValue()字符串实例?((字符串)e.getValue()).trim():e.getValue()))
但是,返回的对象完全删除了null键/值对(在我的示例中为“null”->null)。在Java流中的.filter
步骤之后的任何后续处理中,如何保留键“null”并忽略它
在上面的示例中,我希望得到一个返回的映射,其中键和值对被修剪,空值在修剪步骤中被“忽略”。toMap收集器不允许
null
值,因此不能使用它生成包含null
值的映射
如果您的输入映射是可变的,并且更改它是一个选项,那么您可以简单地修剪这些值
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 vals=newhashmap();
VAL.put(“空”,空);
VAL.put(“第1条”、“第1条”);
vals.replaceAll((键,val)->字符串的val实例?((字符串)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);
HashMap result=vals.entrySet().stream()
.collect(HashMap::new,(m,e)->m.put(e.getKey().trim(),
e、 字符串的getValue()实例((字符串)e.getValue()).trim():e.getValue()),
地图:putAll);
为了更好的可读性,即避免重复相同的表达式,我们可以使用块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);
HashMap result=vals.entrySet().stream()
.收集(
HashMap::新建,
(m,e)->{
对象值=e.getValue();
m、 put(例如getKey().trim(),字符串的值实例?((字符串)值)。trim():值);
},地图::putAll);
请注意,对关键点应用trim()
时,即使关键点在原始地图中是唯一的,也可能会发生碰撞,例如,当具有“key1”
和“key1”
时。toMap
收集器会在这种情况下抛出,而上面创建的临时收集器只会在没有警告的情况下覆盖其中一个冲突的映射。此代码不会编译<代码>过滤器
不返回映射
。您应该澄清您想要执行的“后续处理”,特别是当您假设其结果是一个与源映射具有相同内容的映射时。生成该地图看起来像是一个过时的操作。感谢@Holger的建议,我为问题添加了更多的细节。所以只需删除过滤器
步骤<对于null
,code>e.getValue()instanceof String将计算为false
,因此它不会调用trim()
…啊,因为toMap
收集器通常不允许null
值。这不是流问题,而是收集器的问题。是否需要对钥匙应用trim()
?在您的示例中似乎不是这样,但更改键可能会导致歧义。@user7它在Java8中使用。但是自Java9以来,没有merge函数的toMap
收集器在内部不使用Map.merge
。但是它仍然保留了抛出null
值的行为,这非常有效。谢谢你这么详细的回答,真的很有帮助!