2014-09-06 3 views
0

나는 술어에 따라 컬렉션을 필터링하려고 :collections.filter가 잘못 될 수 있습니까?

   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에서 볼 수 있습니다.

필터를 잘못하고 있습니까? 당신이 System.currentTimeMillis()을 사용할 때 완벽하게 가능 보인다 - 가장 가능성이 보인다 무엇

enter image description here

+0

(기본적으로, 'Collection2.filter'는 잘못 될 수 없습니다.) 구현은 매우 간단하며'Collection'을 반복 할 때'predicate.apply'가'true를 반환하는 요소 만 반환합니다 ') – ColinD

답변

2

는 필터링을했을 때 술어는 사실, 다음 술어가 나중에 거짓이 된 것입니다. 이 같은

+0

그건 그렇지 않아. 현재 시간은 9 월 7 일이었습니다. unlockExpirationDate는 8 월 30 일이었습니다. 필터링과 디버깅 사이의 문제가 아닙니다. 그 밖의 무엇을 할 수 있는가? –

3
당신은 정말하지 말아야 할

일 :

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

System.currentTimeMillis()를 캡처하고 그것을 사용하는 대신 클래스 인스턴스를 만듭니다. 이렇게하면 필터가 시간이 지나도 안정적으로 유지됩니다.

또한 null의 치우는 고려이

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

같은 것을 생각해 보자. 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에 있습니다.

+0

그렇지 않습니다. 현재 시간은 9 월 7 일이었습니다. unlockExpirationDate는 8 월 30 일이었습니다. 필터링과 디버깅 사이의 문제가 아닙니다. 그 밖의 무엇을 할 수 있는가? –

+0

'long millis'는 특정 날짜의 '날짜'보다 어떤면에서 좋습니까? 아무래도 내 술어가 사실로 돌아 오는 이유는 무엇입니까? –

+0

(비록 내가 디버깅하는 동안 그것을 잡을 수 없었지만) –

관련 문제