我有包含
的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}
{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()));