可以collections.filter错了吗?

时间:2014-09-06 22:16:22

标签: java android collections guava android-guava

我尝试根据谓词过滤集合:

                private void filterExpiredOffers() {
                    mOffersList = Lists.newArrayList(Collections2.filter(
                            mOffersList, new Predicate<Offer>() {
                                @Override
                                public boolean apply(Offer offer) {
                                    return mUnlockExpirationCalculator
                                            .isUnlockValid(offer);
                                }
                            }));
                }

public boolean isUnlockValid(Offer offer) {
    return ((offer.unlockExpirationDate == null) || (System
            .currentTimeMillis() < offer.unlockExpirationDate.getTime()));
}

我看到一个报价因此而变得“假”

但是,我稍后会在arrayList中看到它。

我做错了过滤器吗?

enter image description here

2 个答案:

答案 0 :(得分:3)

你真的不应该这样做:

public boolean isUnlockValid(Offer offer) {
    return ((offer.unlockExpirationDate == null) || (System
            .currentTimeMillis() < offer.unlockExpirationDate.getTime()));
}

创建一个类实例,它捕获System.currentTimeMillis()并使用它。这样,您的过滤器将随着时间的推移保持稳定。

考虑这样的事情

class UnlockValidPredicate implements Predicate<Offer> {
    public UnlockValidPredicate() {
        this(System.currentTimeMillis());
    }

    public UnlockValidPredicate(long millis) {
        this.millis = millis;
    }

    @Overrride public boolean apply(Offer offer) {
        return offer.unlockExpirationDate == null
                || millis < offer.unlockExpirationDate.getTime();
    }

    private final long millis;
}

还要考虑摆脱null。将unlockExpirationDate设置为new Date(Long.MAX_VALUE)对于“永不过期”已经足够了,不是吗?

  

那不是它。当前时间是9月7日。 unlockExpirationDate是8月30日。过滤和调试之间的关系不是几天。还有什么呢?


摆脱Date,它是愚蠢的可变类。 最有可能的是,你以某种方式改变了它。

这样的事情
 MyClass(Date date) {
     this.date = date;
 }

 Date getDate() {
     return date;
 }

是灾难的秘诀。最好的解决方案是使用不可变类(在Java 8或JodaTime中可用)。第二好的是使用long millis。最后一个是clone Date无处不在。

答案 1 :(得分:2)

最有可能的是,当你进行过滤时,谓词是正确的,然后谓词在以后变为假 - 当你使用System.currentTimeMillis()时,这似乎是完全可能的。