Iterators.filter vs for-each

时间:2014-07-22 05:38:19

标签: java guava

也许是明显或愚蠢的问题,所以我很抱歉。

让我们假设我有两种方法可以在简单条件下迭代集合:

1

Predicate<SomeObject> pred1 = new Predicate<SomeObject> () {... some condition_1 ...};
Predicate<SomeObject> pred2 = new Predicate<SomeObject> () {... some condition_2 ...};
Iterator<SomeObject> newIterator = Iterators.filter(iterator, pred1);
... do something like Sets.newHashSet(newIterator) ...
newIterator = Iterators.filter(iterator, pred2);
... do something like Sets.newHashSet(newIterator) ...

2

while(iterator.hasNext()) {
 SomeObject someObject = iterator.next();
   if (condition_1) {
    ...do something like set.add(someObject)...
   } else if (condition_2) {
    ...do something like set.add(someObject)...
   }
}

我是对的,#2比#1更快?

感谢您的回答!

2 个答案:

答案 0 :(得分:1)

如果我错了,请纠正我,但我认为#2可能更快。

示例#1过滤集合两次。每次过滤都算作迭代。因此,您最有可能通过过滤它们来花费更多时间。我可能在这方面非常错误,因为我已经看到了一个问题,为什么迭代排序的集合比未排序的集合更快,但希望有人会详细说明。

然而,

示例#2迭代了一次。

不要相信我的话,但我很确定我在这里的右页。

答案 1 :(得分:1)

命令式版本会更快,但确定多少是非常困难的。在我的测试中,一旦发热,两个版本都在1.1微秒内返回。命令式版本方法在95%的情况下运行速度超过5.15微秒(1,000,000个随机执行的运行),而FluentIterable版本在95%的情况下运行速度超过6.6微米。

Guava可以非常快速,特别是如果可以静态定义谓词和函数。

在下面的示例中,请注意谓词组合和FluentIterable的使用。

FluentIterable特别有吸引力,因为用户可以用最少的修改来替换Java 8流。

public static class SomeObject {

    private final String someString;

    public SomeObject(final String someString) {
        this.someString = someString;
    }

    public String getSomeString() {
        return this.someString;
    }

    @Override
    public String toString() {
        return this.someString;
    }
}

public static final Predicate<SomeObject> CONTAINS_A_FILTER = new Predicate<GuavaExample.SomeObject>() {

    @Override
    public boolean apply(final SomeObject someObject) {

        return someObject.getSomeString()
            .contains("A");
    }
};

public static final Predicate<SomeObject> CONTAINS_B_FILTER = new Predicate<GuavaExample.SomeObject>() {

    @Override
    public boolean apply(final SomeObject someObject) {

        return someObject.getSomeString()
            .contains("B");
    }
};

public static final Predicate<SomeObject> CONTAINS_A_AND_B_FILTER = Predicates.and(CONTAINS_A_FILTER,
        CONTAINS_B_FILTER);

public static final Predicate<SomeObject> CONTAINS_A_OR_B_FILTER = Predicates.or(CONTAINS_A_FILTER,
        CONTAINS_B_FILTER);

public static void main(final String... args) {

   final List<SomeObject> someObjects = ImmutableList.of(new SomeObject("A"), new SomeObject("AB"),
            new SomeObject("B"), new SomeObject("C"));

    final Set<SomeObject> containsAandB = FluentIterable.from(someObjects)
            .filter(CONTAINS_A_AND_B_FILTER)
            .toSet();

    // prints [AB]
    System.out.println(containsAandB);

    final Set<SomeObject> containsAOrB = FluentIterable.from(someObjects)
            .filter(CONTAINS_A_OR_B_FILTER)
            .toSet();

    // prints [A, AB, B]
    System.out.println(containsAOrB);
}