【问题标题】:Google guva filter from list of arraylist来自arraylist列表的Google guva过滤器
【发布时间】:2019-11-19 19:23:10
【问题描述】:

我正在尝试使用 Google 的 Guava 过滤器从 arraylist 列表中过滤元素,它仅支持 Collection E。我必须过滤来自List of ArrayLists 的元素。

请找到我下面的代码。

有没有办法过滤List of Arraylists中的元素?

ArrayList<ArrayList<String>> lists=new ArrayList<ArrayList<String>>();

    ArrayList<String> list1 = new ArrayList<String>();
    ArrayList<String> list2 = new ArrayList<String>();
    ArrayList<String> list3 = new ArrayList<String>();

    list1.add("Hello");
    list1.add("hi");
    list1.add("howdy");

    list2.add("are you good");
    list2.add("you doing");
    list2.add("was the day");

    list3.add("who");
    list3.add("how");
    list3.add("where");

    lists.add(list2);
    lists.add(list1);
    lists.add(list3);

    Collection<String> filtered=Collections2.filter(lists, Predicates.containsPattern("dy")); // not able to filter from List of ArrayLists.
    System.out.println("Filtered -->"+filtered);

更新 1

请在下面找到我的实现:

 Collection<Menu> menus = menuRepository.getMenus();

 Collection<ArrayList<Menu>> enabledMenus = FluentIterable.from(menus)
        .transformAndConcat(Functions.identity())
        .filter(byDisabled())
        .toList();

我收到以下错误

The method transformAndConcat(Function<? super Menu,? extends Iterable<? extends T>>) in the type FluentIterable<Menu> is not applicable for the arguments (Function<Object,Object>)

请在下面找到我的byDisabled() 方法实现。

  private Predicate<ArrayList<ArrayList<Menu>>> byDisabled() {
    return new Predicate<ArrayList<ArrayList<Menu>>>() {
      @Override
      public boolean apply(ArrayList<ArrayList<Menu>> menu) {
        return isMenuEnabled(menu);
      }
    };
  }

【问题讨论】:

    标签: java filter collections guava


    【解决方案1】:

    (假设您不使用 Java 8,否则其他答案已经显示了可能的解决方案。)

    您需要在 Guava 中使用 .flatMap 等效项,它们是:

    后者可以流畅使用(呵呵),类似于 Java 8 的方法:

    ImmutableList<String> filtered = FluentIterable.from(lists)
            .transformAndConcat(Functions.identity())
            .filter(Predicates.containsPattern("dy"))
            .toList();
    

    请注意,此复制结果迭代的内容,所以如果懒惰Iterable 就足够了,最后一步可以省略:

    Iterable<String> filtered = FluentIterable.from(lists)
            .transformAndConcat(Functions.identity())
            .filter(Predicates.containsPattern("dy"));
    

    在 Gauva wiki 上阅读有关 IterablesFluentIterable 的更多信息。

    【讨论】:

    • 我在实际的实现中一直遵循它。在实施过程中遇到一些错误。我已经在我的问题中更新了这一点。
    【解决方案2】:

    您可以为此使用 Java 8 的本机流 API

    List<String> filtered = lists.stream()
        .flatMap(Collection::stream)
        .filter(Predicates.containsPattern("dy"))
        .collect(Collectors.toList());
    

    【讨论】:

      【解决方案3】:

      不确定guava 是否是您的唯一选择,如果不是,Java 8 stream 可能工作:

      如果你只想找出匹配的元素,试试:

          ArrayList<ArrayList<String>> lists = new ArrayList<>();
      
          ArrayList<String> list1 = new ArrayList<>();
          ArrayList<String> list2 = new ArrayList<>();
          ArrayList<String> list3 = new ArrayList<>();
      
          list1.add("Hello");
          list1.add("hi");
          list1.add("howdy");
      
          list2.add("are you good");
          list2.add("you doing");
          list2.add("was the day");
      
          list3.add("who");
          list3.add("how");
          list3.add("where");
      
          lists.add(list2);
          lists.add(list1);
          lists.add(list3);
      
          List<String> matchedItems =
                  lists.stream().flatMap(Collection::stream).filter(str -> str.contains("dy")).collect(Collectors.toList());
      
          for (String item : matchedItems) {
              System.out.println("Matched item: " + item);
          }
      

      注意,在这个解决方案中元素和子列表之间的关系丢失了。

      【讨论】:

        猜你喜欢
        • 2013-12-13
        • 1970-01-01
        • 2020-04-16
        • 1970-01-01
        • 1970-01-01
        • 2014-09-14
        • 2012-11-07
        • 1970-01-01
        • 2021-11-18
        相关资源
        最近更新 更多