在 Java 7 或更低版本中,HOWTO 使用在地图中找到的键/值过滤地图对象列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27989224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:45:47  来源:igfitidea点击:

In Java 7 or below, HOWTO filter a list of map objects using key/value found in the map

javacollectionsunderscore.jsguavalambda

提问by Chantz

I have a list of map objects. These map objects have properties/keys like id, condition_1, condition_2 etc. A sample map looks like so,

我有一个地图对象列表。这些地图对象具有 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);

So, I need to filter the allItemsobject such that it has only those map objects which have condition_1 = true& condition_2 = false, & so on & so forth.

所以,我需要过滤allItems对象,使其只有那些具有condition_1 = true& condition_2 = false,等等等等的地图对象。

I thought about using apache commons CollectionUtils.filterbut that doesn't seem to solve my problem because I have no way of specifying map entries as filter conditions.

我想过使用 apache commons CollectionUtils.filter但这似乎并没有解决我的问题,因为我无法将地图条目指定为过滤条件。

I am not averse to using Google Guava as well, but I was unable to find a good solution.

我也不反对使用 Google Guava,但我找不到好的解决方案。

Basically I am trying to mimic the _.wherefunctionality found in the excellent JavaScript library underscore.js.

基本上,我试图模仿_.where优秀的 JavaScript 库 underscore.js 中的功能。

回答by Louis Wasserman

One Guava solution:

一种番石榴解决方案:

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"));
   }
});

回答by laazer

I think you will have to do this the long way. Unfortunately Java Maps are not of type Iterable which means most common libraries don't have filter functions for them. Try something like this (I believe strings are implicitly true in java in case you are worried about your first key-value pair):

我认为你将不得不长期这样做。不幸的是,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;

```

``

Another possibility is to turn your Map into a List of KeyValuesand using apache mapping and list functions. Most likely, while you are using java 7, you are not going to get that pretty one liner. Hope this helped.

另一种可能性是将您的 Map 转换为KeyValues的列表并使用 apache 映射和列表功能。最有可能的是,当您使用 java 7 时,您不会得到那么漂亮的衬里。希望这有帮助。

回答by Cililing

I think the best solution is to actually do the same what Kotlin does in method Map<K, V>.filter.

我认为最好的解决方案是实际执行 Kotlin 在 method 中所做的相同操作Map<K, V>.filter

Let's create predicate:

让我们创建谓词:

public interface Predicate<T> {
    boolean apply(T t);
}

Predicate is an interface useful for functional-like programming. Method apply returns true when a condition is fulfilled.

Predicate 是一个对类函数式编程有用的接口。当满足条件时,方法apply 返回true。

Then, create class like CollectionUtilsand put a static method there:

然后,创建类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;
}

This way we can use this method in following way:

这样,我们可以通过以下方式使用此方法:

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);
    }
};

If you in fact can use Java 8, but because of some reasons you cannot use Java's streams (like Android Development supporting older version of Android not compatible with Java 8) you can remove syntax's sugger and write it in better form:

如果您实际上可以使用 Java 8,但由于某些原因您不能使用 Java 的流(例如 Android 开发支持与 Java 8 不兼容的旧版本的 Android),您可以删除语法的建议并以更好的形式编写它:

Map<String, Object> map = ...;
Map<String, Object> filtered = CollectionUtils.filter(
    map,
    entry -> isEntryOK(entry)
);

Or, the best solution in my opinion -> Switch to Kotlin which gives you all those features out of the box! :D

或者,我认为最好的解决方案 ->切换到 Kotlin,它为您提供所有这些开箱即用的功能!:D

回答by tly

in Java 8 you could use streams:

在 Java 8 中你可以使用流:

allItems.stream()
        .filter(map->
        (map.get("condition_1")==true)&&(map.get("condition_2")==false))
        .forEach(System.out::println); //Example output