javaandroidguavaandroid-guava

How to filter Array of Map with multiple value using Guava


I have an Array containing Map. And I want to filter my array using some (multiple) key and value inside of the map object. For example, WHERE ID > 1 AND Name <> "cc" (key > 1, Name<>"cc").

How can i do that in Java? I have imported the Guava libraries that has Collections2 to filter the array. But, I didn't found any example that is filtering Map object inside the array.

here is some of my example codes:

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

            Map<String, Object> map1 = new HashMap<>();
            map1.put("ID", 1);
            map1.put("Name", "aa");
            baseList.add(map1);

            Map<String, Object> map2 = new HashMap<>();
            map2.put("ID", 2);
            map2.put("Name", "bb");
            baseList.add(map2);

            Map<String, Object> map3 = new HashMap<>();
            map3.put("ID", 3);
            map3.put("Name", "cc");
            baseList.add(map3);

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

            filteredList = Collections2.filter() ???

I want to filter with a kind of ID >= 1 AND NAME<>"cc" Which will resulting Array containing Map object like this: [{ID=1,Name="aa"}, {ID=2,Name="bb"}]

Anyone can help?


Solution

  • Do you use Java 8? You can do:

    List<Map<String, Object>> filteredList = maps.stream()
        .filter(map -> (Integer) map.get("ID") >= 1 && !"cc".equals(map.get("Name")))
        .collect(Collectors.toList());
    

    to have new list with filtered maps.

    If you want collection view using Guava goodies (or no Java 8), you should use Collections2.filter:

    Collection<Map<String, Object>> filteredList = Collections2.filter(
        maps, new Predicate<Map<String, Object>>() {
          @Override
          public boolean apply(@Nullable Map<String, Object> map) {
            return (Integer) map.get("ID") >= 1 && !"cc".equals(map.get("Name"));
          }
        });
    

    there's no Lists.filter, see IdeaGraveyard for explanation, hence only Collection interface is provided.

    Do you really need list of maps instead of Map<Integer, String> (or maybe Map<Integer, YourDomainObject>)? Then you could do:

    final Map<Integer, String> map = ImmutableMap.of(
        1, "aa",
        2, "bb",
        3, "cc");
    final Map<Integer, String> filteredMap = Maps.filterEntries(map,
        e -> e.getKey() >= 1 && !"cc".equals(e.getValue()));