Java 8 过滤器和列表收集<Map<String, Object>>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30246433/
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 16:45:21  来源:igfitidea点击:

Java 8 Filter and Collect of List<Map<String, Object>>

javajava-8filteringjava-stream

提问by BoxMan0617

Ok, so I have a List of Maps that I want to filter then collect to another List of Maps. Every time I put that List through the process, I get a List of Objects... Help?!

好的,所以我有一个要过滤的地图列表,然后收集到另一个地图列表。每次我在整个过程中放入该列表时,我都会得到一个对象列表...帮助?!

List<Map<String, Object>> segments = (List<Map<String, Object>>) (List<?>) query.getResultList();

List<Map<String, Object>> segmentsWithMoreVersions = segments.stream()
            .filter((Object s) -> {
                Object[] ss = (Object[]) s;
                if(((Long) ss[2]) == 1)
                {
                    return false;
                }
                return true;
            })
            .collect(Collectors.toList());

As you can see... In the filter method I've had use an Object because I can't get the s variable to be a Map. When I do try, I get a ClassCastException.

如您所见...在过滤器方法中,我使用了一个对象,因为我无法将 s 变量设为 Map。当我尝试时,我得到一个 ClassCastException。

Edit: Ok, maybe more information is needed... So my segmentsvariable is like so:

编辑:好的,也许需要更多信息......所以我的segments变量是这样的:

[
    {'name': 'ABC', 'version': 1, 'ct': 1},
    {'name': 'AAA', 'version': 1, 'ct': 1},
    {'name': 'BFD', 'version': 1, 'ct': 4},
    {'name': 'SDE', 'version': 1, 'ct': 1}
]

What I want to do is to filter out all of the Maps that have the ct as 1. The filter method is looking at that Object (because I can't get it to cast to a Map) and checking if it == to 1, and if so it does NOT return it to the stream.

我想要做的是过滤掉所有 ct 为 1 的地图。过滤器方法正在查看该对象(因为我无法将其转换为地图)并检查它是否 == 为 1 ,如果是这样,它不会将其返回到流中。

Edit2: After the comments, I edited to the following:

Edit2:评论后,我编辑为以下内容:

List<Map<String, Object>> segmentsWithMoreVersions = segments.stream()
            .filter(m -> ((Long) m.get("ct")) != 1L)
            .collect(Collectors.toList());

And I got the following: Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.Map

我得到了以下信息: Caused by: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.Map

采纳答案by BoxMan0617

Ok... So the problem was NOT the filter function. Thanks to @Radiodef pointing out the unchecked conversion I found that it was that that was causing the problems. So what I did was change that to this:

好的...所以问题不在于过滤器功能。感谢@Radiodef 指出未经检查的转换,我发现正是这导致了问题。所以我所做的是将其更改为:

List<?> tmp = query.getResultList();
    List<Map<String, Object>> segments = new ArrayList<Map<String, Object>>();
    for(Object t : tmp)
    {
        Object[] tt = (Object[]) t;
        Map<String, Object> rMap = new HashMap<String, Object>();
        rMap.put("name", tt[0]);
        rMap.put("version", tt[1]);
        rMap.put("ct", tt[2]);
        segments.add(rMap);
    }

From there the filterworked! THanks guys!

从那里开始filter工作!多谢你们!

回答by Radiodef

So, based on your description, I think the filter you want is this:

所以,根据你的描述,我认为你想要的过滤器是这样的:

segments.stream()
        .filter(m -> ((Long) m.get("ct")) != 1L)
        .collect(toList());

Or being explicit about the type of the predicate:

或者明确说明谓词的类型:

        .filter((Map<String, Object> m) ->
                    ((Long) m.get("ct")) != 1L)


On your edit: you have erroneous data in the Map, or you've misunderstood the way it's represented. It appears that segmentsis actually a List<Object[]>.

在您的编辑中:您在地图中有错误的数据,或者您误解了它的表示方式。看来这segments实际上是一个List<Object[]>.

I don't really have enough information to help you fix it.

我真的没有足够的信息来帮助您修复它。

To try debugging, you could do something like:

要尝试调试,您​​可以执行以下操作:

segments.stream()
        .map(Arrays::toString)
        .forEach(System.out::println);

This will tell you what's actually in it if you don't have documentation to refer to.

如果您没有可参考的文档,这将告诉您其中的实际内容。

回答by Nik

This works for me...

这对我有用...

    List<Map<String, Object>> segments = new ArrayList<Map<String, Object>>();

    List<Map<String, Object>> segmentsWithMoreVersions = segments.stream()
            .filter((Map<String, Object> s) -> {
                 return (Long) s.get("versions") > 1;
            })
            .collect(Collectors.toList());