0

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

                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 中看到它。

我是不是过滤错了?

在此处输入图像描述

4

2 回答 2

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;
}

还要考虑摆脱nulls。设置unlockExpirationDatenew 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在。

于 2014-09-07T05:19:50.607 回答
2

最有可能的是,当您进行过滤时谓词为真,然后谓词稍后变为假 - 当您使用System.currentTimeMillis().

于 2014-09-06T23:14:39.873 回答