我尝试根据谓词过滤集合:
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中看到它。
我做错了过滤器吗?
答案 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()
时,这似乎是完全可能的。