简体   繁体   中英

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

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.

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

[
    {'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.

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

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

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 segments is actually a 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.

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

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:

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 filter worked! THanks guys!

public static void main(String[] args) {

    List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
    Map<String, Object> mp = new HashMap<String, Object>();
    mp.put("1", "One");
    mp.put("2", "N");
    Map<String, Object> mp1 = new HashMap<String, Object>();
    mp1.put("1", "Two");
    mp1.put("2", "Y");
    ls.add(mp);
    ls.add(mp1);
    
    List<Map<String, Object>> ls2 = new ArrayList<Map<String, Object>>();
    Map<String, Object> mp2 = new HashMap<String, Object>();
    mp2.put("1", "One");
    mp2.put("2", "N");
    Map<String, Object> mp21 = new HashMap<String, Object>();
    mp21.put("1", "Two");
    mp21.put("2", "N");
    ls2.add(mp2);
    ls2.add(mp21);
    
    List<Map<String, Object>> segmentsWithMoreVersions = ls.stream()
            .filter(( s) -> {
                 return (boolean) ((String) s.get("2")).equalsIgnoreCase("Y");
            })
            .collect(Collectors.toList()); 
    
    System.out.println(segmentsWithMoreVersions);
    
    /*ls2.forEach(map -> {
        
        
        
    });*/
    
    
    
    
    
    
    
    
}

Output - [{1=Two, 2=Y}]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM