如何在Java中过滤嵌套的Map<String,Object>?



我有包含

Map<String, Object> currencyRate
"license": "https:/etc",
"timestamp": 1654,
"base": "USD",
"rates": {
"AED": 3.6,
"AFN": 88.9,
"ALL": 112,
etc
}

例如,我想要得到"AED"的值,即3.6

我试过了:

Map<String, Object> filtered = currencyRate.entrySet()
.stream()
.filter(map->map.getValue().toString().contains("AED"))
.collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));

但是它返回了这个:

"rates": {
"AED": 3.6,
"AFN": 88.9,
"ALL": 112,
etc
}

所以"rates",它有,也有

如何在中获得"rates"?

您不需要为此使用流。相反,您需要通过"rates"获取嵌套映射,并将其类型强制转换为适当的类型(注意,此强制转换是不安全的):

double aedRate = ((Map<String, Double>) map.get("rates")).get("AED");

如果你想不惜一切代价利用流,那么首先你需要提取嵌套映射并将其从Object类型转换为Map。然后在其条目上创建一个流,并使用目标键"AED":

过滤出条目
Map.Entry<String, Double> result =
((Map<String, Double>) map.get("rates")).entrySet().stream()
.filter(entry -> entry.getKey("AED"))
.findFirst()
.orElseThrow();

注意使用Object作为泛型类型并通过类型强制转换进行操作并不是一个好的实践。Map<String, Object>的总体方法容易出错且不可维护。如果应用程序中的数据结构适当,就不会出现这个问题。

因为你正在使用一个映射,其中每个值可以是任何对象Map<String, Object>(没有声明,所以我只是假设这里),我猜你可以使用findFirst终端操作,然后将返回值转换为Map<String, Object>(我在这里也使用了对象,因为数据类型在问题中没有指定)。

当然,只有当你特别想要使用流并且严格假设只有一个值包含"AED"(同样,如果任何其他值可以包含&;aed &;,则不指定问题中的值)。或者,您可以简单地执行map.get("rates")来检索您的嵌套映射。

public static void main(String[] args) {
Map<String, Object> map = new HashMap<>(Map.of(
"license", "http:/etc",
"timestamp", 1654,
"base", "USD",
"rates", Map.of(
"AED", 3.6,
"AFN", 88.9,
"ALL", 112
// ...
)
));
Map<String, Object> mapRes = (Map<String, Object>) map.entrySet()
.stream()
.filter(entry -> entry.getValue().toString().contains("AED"))
.map(entry -> entry.getValue())
.findFirst()
.orElse(null);
System.out.println(mapRes);
}

{ALL=112, AED=3.6, AFN=88.9}

我猜你应该使用flatMap()将嵌套映射转换为新的流

Map<String, Object> filtered = currencyRate.entrySet()
.stream()
.filter(map->map.getValue().toString().contains("AED"))
.flatMap(map->map.stream())
.filter(...)
.collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));

相关内容

最新更新