我有一个地图对象列表。这些地图对象具有id,condition_1,condition_2等属性/键。示例地图如下所示,
List<Map<String, Object>> allItems = Lists.newArrayList();
Map<String, Object> paramsMap = Maps.newHashMap();
paramsMap.put("id", "a");
paramsMap.put("condition_1", false);
paramsMap.put("condition_2", true);
paramsMap.put("condition_3", false);
allItems.add(paramsMap);
所以,我需要过滤allItems
对象,使其只有那些具有condition_1 = true
&amp;的映射对象。 condition_2 = false
,&amp;等等&amp;等等。
我考虑过使用apache commons CollectionUtils.filter,但这似乎无法解决我的问题,因为我无法将地图条目指定为过滤条件。
我也不反对使用Google Guava,但我无法找到一个好的解决方案。
基本上我试图模仿优秀的JavaScript库underscore.js中的_.where
功能。
答案 0 :(得分:5)
一种番石榴解决方案:
Iterables.filter(allItems, new Predicate<Map<String, Object>>() {
@Override public boolean apply(Map<String, Object> map) {
return Boolean.TRUE.equals(map.get("condition_1"))
&& Boolean.FALSE.equals(map.get("condition_2"));
}
});
答案 1 :(得分:0)
我认为你必须做很长的事情。遗憾的是,Java Maps不是Iterable类型,这意味着大多数常见的库都不具备过滤功能。尝试这样的事情(我相信如果你担心你的第一个键值对,字符串在java中是隐含的):
```
boolean result = true;
boolean test = true;
List<Map<String, Object> resultList;
for(Map<String, Object> map : allitems) {
for(String key : map.keySet()) {
result = result && test && map.get(key);
test = !test;
}
if(result) {
resultList.add(map);
}
}
return resultList;
```
另一种可能性是将Map转换为KeyValue
s列表并使用apache映射和列表函数。最有可能的是,当你使用java 7时,你不会那么漂亮。希望这有帮助。
答案 2 :(得分:0)
我认为最好的解决方案是实际上与Kotlin在方法Map<K, V>.filter
中所做的相同。
让我们创建谓词:
public interface Predicate<T> {
boolean apply(T t);
}
谓词是对类似函数的编程有用的接口。满足条件时,方法apply将返回true。
然后,创建类似CollectionUtils
的类,并在其中放置一个静态方法:
public static <K, V> Map<K, V> filter(
@NonNull Map<K, V> collection,
@NonNull Predicate<Map.Entry<K, V>> predicate
) {
Map<K, V> result = new HashMap<>();
for (Map.Entry<K, V> entry : collection.entrySet()) {
if (predicate.apply(entry) {
result.put(entry.getKey(), entry.getValue();
}
}
return result;
}
这样,我们可以通过以下方式使用此方法:
Map<String, Object> map = ...;
Map<String, Object> filtered = CollectionUtils.filter(map, new Predicate<Map.Entry<String, Object>>() {
@Override
public boolean apply(Map.Entry<String, Object> entry) {
return isEntryOK(entry);
}
};
如果您实际上可以使用Java 8,但是由于某些原因您不能使用Java的流(例如,支持与Java 8不兼容的较旧版本的Android的Android开发),则可以删除语法的建议并以更好的形式编写: / p>
Map<String, Object> map = ...;
Map<String, Object> filtered = CollectionUtils.filter(
map,
entry -> isEntryOK(entry)
);
或者,我认为最好的解决方案-> 切换到Kotlin,即可为您提供所有这些功能! :D
答案 3 :(得分:-4)
allItems.stream()
.filter(map->
(map.get("condition_1")==true)&&(map.get("condition_2")==false))
.forEach(System.out::println); //Example output