我在寻找一个谷歌集合方法返回不返回null供应商序列的第一个结果。

我看用Iterables.find(),但在我谓我会打电话给我的供应商,结果对空比较,然后再次调用一次find方法返回的供应商。

有帮助吗?

解决方案

由于您的评论平息风暴的回答(欲望不叫Supplier.get()两次),然后怎么样:

private static final Function<Supplier<X>, X> SUPPLY = new Function<....>() {
    public X apply(Supplier<X> in) {
        // If you will never have a null Supplier, you can skip the test;
        // otherwise, null Supplier will be treated same as one that returns null
        // from get(), i.e. skipped
        return (in == null) ? null : in.get();
    }
}

然后

Iterable<Supplier<X>> suppliers = ... wherever this comes from ...

Iterable<X> supplied = Iterables.transform(suppliers, SUPPLY);

X first = Iterables.find(supplied, Predicates.notNull());

请注意自带Iterables.transform()出了Iterable是惰性计算,因此作为Iterables.find()循环过它,你只能尽可能评价作为第一个非null返流一个,而且只有一次。

其他提示

您问如何做到这一点使用谷歌集合,但这里是你会怎么做,而不使用谷歌集合。它比较考恩的回答(这是一个很好的答案) - 这是比较容易理解。

private static Thing findThing(List<Supplier<Thing>> thingSuppliers) {
  for (Supplier<Thing> supplier : thingSuppliers) {
    Thing thing = supplier.get();
    if (thing != null) {
      return thing;
    }
  }
  // throw exception or return null
}

在注释中的 - 如果这是你的类的调用者的过错,抛出IllegalArgumentException或IllegalStateException异常适当的;如果这不应该发生过,使用的AssertionError;如果这是一个正常现象您的代码调用此预期将不得不检查,你可能会返回null。

什么是错的呢?

List<Supplier> supplierList = //somehow get the list
Supplier s = Iterables.find(supplierList, new Predicate<Supplier>(){
     boolean apply(Supplier supplier) {
         return supplier.isSomeMethodCall() == null;
     }
     boolean equals(Object o) {
         return false;
     }
});

您想节省一些线?我能想到的唯一的优化是静态导入查找这样你就可以摆脱“Iterables”的。另外,谓语是一个匿名内部类,如果你需要它在一个以上的地方,你可以创建一个类,它会为你看,

List<Supplier> supplierList = //somehow get the list
Supplier s = find(supplierList, new SupplierPredicateFinder());

其中SupplierPredicateFinder是另一个类。

更新:在这种情况下发现是错误的方法。实际上,你需要这样的自定义功能,可以返回两个值。如果使用的是公共的集合则可以使用一个DefaultMapEntry或者可以简单地返回一个Object [2]或一个Map.Entry。

public static DefaultMapEntry getSupplier(List<Supplier> list) {
    for(Supplier s : list) {
        Object heavyObject = s.invokeCostlyMethod();
        if(heavyObject != null) {
             return new DefaultMapEntry(s, heavyObject);
        }
    }
}

大小为2的列表或尺寸1的散列映射或长度为2的数组替换DefaultMapEntry:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top