I have some situation where I have page List containing collection of Map name page and in page map I have another List calling Groups, which is look like:
List<Map<String,Object>> group = new ArrayList<>();
Map<String,Object> groupMap = new HashMap<>();
groupMap.put("G1F1", null); //<-- null value need to remove from groupMap
groupMap.put("G1F2", "F2value");
groupMap.put("G1F3", "F3value");
groupMap.put("G1F4", null);//<-- null value need to remove from groupMap
group.add(groupMap);
Map<String,Object> groupMap2 = new HashMap<>();
groupMap2.put("G2F1", null);//<-- null value need to remove from groupMap2
groupMap2.put("G2F2", "F2value");
groupMap2.put("G2F3", "F3value");
groupMap2.put("G2F4", null);//<-- null value need to remove from groupMap2
group.add(groupMap2);
Map<String,Object> page1 = new HashMap<>();
page1.put("PageID", "PID1001");
page1.put("Groups", group);
Map<String,Object> page2 = new HashMap<>();//<-- page2 do not have Groups need to remove from pages
page2.put("PageID", "PID1208");
Map<String,Object> page3 = new HashMap<>();//<-- page3 do not have Groups need to remove from pages
page3.put("PageID", "PID1212");
Map<String,Object> page4 = new HashMap<>();//<-- page4 do not have Groups need to remove from pages
page4.put("PageID", "PID1214");
Map<String,Object> page5 = new HashMap<>();
page5.put("PageID", "PID15555");
page5.put("Groups", group);
pages.add(page1);
pages.add(page2);
pages.add(page3);
pages.add(page4);
pages.add(page5);
In the above pages object I need to remove those pages that do not have any Groups and in the Groups I need to remove those items that has null value.
I tried with the following code using java8 lamda but the output is unexpected which is like [true, true, false, false]
.
Object object = pages.stream().filter(page -> page.containsKey("Groups"))
.map(page -> (List) page.get("Groups"))
.flatMap(x -> x.stream()).map(group -> ((Map<String,Object>)group).entrySet().removeIf(g -> g.getValue() == null)).collect(Collectors.toList());
I'm able to remove all the items in the Groups which contains null value by the following code:
pages.stream().filter(page -> page.containsKey("Groups"))
.map(page -> (List) page.get("Groups")).flatMap(x -> x.stream()).forEach(group -> ((Map<String,Object>)group).entrySet().removeIf(entry -> null == entry.getValue()));
But not able to filter out the Pages means if the page donot contains any Groups then I need to remove that page user single statement lambda, I can do it using conventional Java iteration process, which is look like :
private static void sanitizePages() {
Iterator<Map<String,Object>> listIt = pages.iterator();
while(listIt.hasNext()) {
Map<String,Object> item = listIt.next();
if(!item.containsKey(("Groups"))){
listIt.remove();
continue;
}
List<Map<String,Object>> groups = (List<Map<String,Object>>)item.get("Groups");
Iterator<Map<String,Object>> groupsIt = groups.iterator();
while(groupsIt.hasNext()) {
Map<String,Object> map = groupsIt.next();
Iterator<Entry<String, Object>> groupIt = map.entrySet().iterator();
while(groupIt.hasNext()) {
Entry<String,Object> group = groupIt.next();
if(null == group.getValue()) groupIt.remove();
}
}
}
}
But I need lambda solution.
First of all, Streams are not the right tool when you want to modify collections, but note that there a several useful methods on the Collections itself.
If you want to win a prize for maximizing the lambda usage, you can use:
pages.removeIf(item -> {
List<Map<String,Object>> groups = (List<Map<String,Object>>)item.get("Groups");
if(groups==null) return true;
groups.forEach(map -> map.values().removeIf(Objects::isNull));
return false;
});
But note that there are good old methods like removeAll
which still work and aren't more complicated than the lambda based use:
Set<Object> nulls=Collections.singleton(null);
pages.removeIf(item -> {
List<Map<String,Object>> groups = (List<Map<String,Object>>)item.get("Groups");
if(groups==null) return true;
groups.forEach(map -> map.values().removeAll(nulls));
return false;
});
Of course, the code was simpler if the collections weren't type with Object
, requiring an unchecked type cast…
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.