代码之家  ›  专栏  ›  技术社区  ›  technomalogical

确定List<Foo>包含元素的最简洁方法Foo.getBar文件()=“Baz”?

  •  2
  • technomalogical  · 技术社区  · 15 年前

    给一个开始 List<Foo> ,确定 Foo 具有属性的元素 bar getBar() )值为“ Baz "? 我能想到的最好答案是线性搜索:

    List<Foo> listFoo;
    for(Foo f:listFoo) {
        if(f.getBar().equals("Baz")) {
            // contains value
        }
    }
    

    我查看了HashSet,但似乎没有使用 contains() 不首先实例化 通过(在我的情况下, 创建成本很高)。我还查看了HashMap,但似乎没有一种方法可以在列表中循环并添加每一个 一次一个元素。这个列表很小,所以我不担心性能,因为我很清楚代码。

    // C#
    List<Foo> listFoo;
    bool contains = listFoo.Count(f => f.getBar=="Baz")>0;
    

    # Python
    # list_foo = [Foo(), ...]
    contains = "Baz" in (f.bar for f in list_foo)
    

    Java有办法做到这一点吗?

    4 回复  |  直到 15 年前
        1
  •  3
  •   Péter Török    15 年前

    interface Predicate<T> {
      boolean isTrueFor(T item);
    }
    
    Foo getFirst(List<Foo> listFoo, Predicate<Foo> pred) {
      for(Foo f:listFoo) {
        if(pred.isTrueFor(f)) {
          return f;
        }
      }
    }
    
    class FooPredicateBar implements Predicate<Foo> {
      private final String expected;
      FooPredicateBar(String expected) {
        this.expected = expected;
      }
      public boolean isTrueFor(Foo item) {
        return item != null && expected.equals(item.getBar());
      }
    }
    ...
    List<Foo> listFoo;
    Foo theItem = getFirst(listFoo, new FooPredicateBar("Baz"));
    
        2
  •  4
  •   Bozho    15 年前

    Java还不支持闭包,所以您的解决方案是最短的解决方案之一。另一种方法是, google-collections Iterable 像这样的结束 Predicate

    boolean contains = Iterables.any(iterableCollection, new Predicate<Foo>() {
        @Override
        public boolean apply(Foo foo) {
           return foo != null && foo.getBar().equals("Baz");
        }
    }
    
        3
  •  4
  •   Chris Aldrich    15 年前

    另外(仅供参考)f.getBar==“Baz”不适用于字符串比较,因为字符串是对象。然后使用==运算符实际比较对象(这些对象不相等,因为它们不在同一内存位置,并且是单独的对象)。equals方法是进行对象比较的最佳方法。具体来说,最好使用“Baz.equals”(f.getBar()),因为这样也可以避免令人讨厌的NullPointerExceptions。

    现在来回答你的问题。我可以想办法做到这一点,但这可能取决于父对象Foo与子对象Bar的关系。会不会一直是一对一?换句话说,“Baz”的Bar值是否可以与多个Foo对象相关联?

        4
  •  2
  •   dogbane    15 年前

    您还可以使用apachecommons CollectionUtils :

     boolean contains = CollectionUtils.exists(listFoo, new Predicate() {
         public boolean evaluate(Object input) {
             return "Baz".equals(((Foo)input).getBar());
         }
     });
    
    推荐文章