我有一张地图如下
Map<String, String> myMap = new HashMap<>();
myMap.put("a", "Something");
myMap.put("b", null);
myMap.put("c", "more");
还有一个清单,
List<String> myList = Arrays.asList("a","b");
我想检查 myMap 中带有 myList 中键的所有值是否都为 null
我创建了一个方法,如下所示,效果很好。我想检查我们是否可以使用流在一行代码中实现相同的目标
myMap.values().removeIf(Objects::isNull);
Map<String, String> resultMap = myList.stream().filter(myMap::containsKey).collect(Collectors.toMap(Function.identity(), myMap::get));
if(!resultMap.isEmpty()){
// Atleast one not null value is present in myMap with key in myList
}
当然,只需检查列表中的所有元素是否与映射中的非空值匹配即可:
myList.stream().allMatch(x -> myMap.containsKey(x) && myMap.get(x) == null);
// or (more overhead, but you might prefer its expressivness):
myList.stream()
.filter(myMap::containsKey)
.map(myMap::get)
.allMatch(Objects::isNull);
或者,如果您认为“缺少键”相当于“具有 null”:
myList.stream().map(myMap::get).allMatch(Objects:isNull);
Map.get
指定不存在的键返回 null。因此,您只需进行一次空检查即可过滤掉映射到空或根本未映射的键。
Map<String, String> resultMap = myList.stream()
.filter(key -> myMap.get(key) != null)
.collect(Collectors.toMap(Function.identity(), myMap::get));
如果您不需要
resultMap
,则使用 anyMatch
会更短
myList.stream().allMatch(key -> myMap.get(key) != null)
与
myMap.values().removeIf(Objects::isNull)
不同,这不会修改原始地图。
因此,您已经使用此行删除了具有
null
values 的条目:
myMap.values().removeIf(Objects::isNull);
很好,因为在集合中保留空引用是一种反模式,因为这些元素无法提供任何有用的信息。因此,我认为您的意图与检查
myList
中的所有字符串是否与 null
相关(或不存在)无关。
现在要检查
myMap
是否包含 myList
中的任何元素(这将自动暗示映射到此类元素的 value 为 non-null),您可以在 myList
的内容上创建一个流并根据 myMap
的 key-set检查每个元素:
boolean hasNonNullValue = myList.stream().anyMatch(myMap.keySet()::contains);
我怀疑您可能会使用此类键(如果有)执行某些操作。如果是这样,那么生成这些 keys 的列表是有意义的,而不是执行上面提供的检查:
List<String> keysToExamine = myList.stream()
.filter(myMap.keySet()::contains)
.toList(); // for JDK versions earlier then 16 use .collect(Collectors.toList()) instead of toList()
注意:根据key-set检查list的元素,不相反,否则可能会导致性能下降。
Stream#findAny
和 Optional#ifPresent
如果
myMap
中至少存在一个非空值且 myList
中存在相应的键,那么您似乎想要执行某些操作。如果是的话,这个组合就完美满足你的要求了。
myMap.keySet()
.stream()
.filter(k -> myMap.get(k) != null && myList.contains(k))
.findAny()
.ifPresent(
// Atleast one not null value is present in myMap with key in myList
System.out::println // A sample action
);
import javax.xml.bind.*;
import java.io.StringReader;
import java.util.List;
@XmlRootElement(name = "audit-record")
public class AuditRecord {
private List<AuditEntry> auditEntries;
@XmlElement(name = "audit-entry")
public List<AuditEntry> getAuditEntries() {
return auditEntries;
}
public void setAuditEntries(List<AuditEntry> auditEntries) {
this.auditEntries = auditEntries;
}
}
class AuditEntry {
private String name;
private String value;
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
ublic class XMLParserUsingJAXB {
public static void main(String[] args) {
String xmlString = "<audit-record>\n" +
" <audit-entry>\n" +
" <name>descrption</name>\n" +
" <value>some value which contains strange characters</value>\n" +
" </audit-entry>\n" +
" <audit-entry>\n" +
" <name>resister number</name>\n" +
" <value>123456</value>\n" +
" </audit-entry>\n" +
"</audit-record>";
try {
JAXBContext jaxbContext = JAXBContext.newInstance(AuditRecord.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
AuditRecord auditRecord = (AuditRecord) unmarshaller.unmarshal(new StringReader(xmlString));
List<AuditEntry> auditEntries = auditRecord.getAuditEntries();
for (AuditEntry entry : auditEntries) {
if ("descrption".equals(entry.getName())) {
System.out.println("Value under description: " + entry.getValue());
break; // Assuming you only need the value once
}
}
} catch (JAXBException e) {
e.printStackTrace();
}
}
}