泛型地狱 - 如何将 joda.DateTime 传递给 Hamcrest Matcher.greaterThan?

发布于 2024-12-13 12:20:25 字数 891 浏览 0 评论 0原文

JodaTime 有

public final class DateTime extends BaseDateTime {...}

它的工作方式到

public interface ReadableInstant extends Comparable<ReadableInstant>

Hamcrest 有

public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<? super T>
    greaterThan(T value) {...}

如果我尝试

greaterThan(new DateTime());

然后我得到一个编译错误(Eclipse 给出了大部分线索)

Matchers类型的泛型方法greaterThan(T)不适用 对于参数(日期时间)。推断的类型 DateTime 不是有效的替代品 对于有界参数>

我认为 greaterThan 的签名实际上应该是正确的吗

public static <T extends java.lang.Comparable<? super T>> org.hamcrest.Matcher<? super T>     
    greaterThan(T value)

?有没有办法将它们组合在一起,而不需要转换为原始Comparable

JodaTime has

public final class DateTime extends BaseDateTime {...}

which works its way up to

public interface ReadableInstant extends Comparable<ReadableInstant>

Hamcrest has

public static <T extends java.lang.Comparable<T>> org.hamcrest.Matcher<? super T>
    greaterThan(T value) {...}

If I try

greaterThan(new DateTime());

then I get a compile error (Eclipse gives most clue)

The generic method greaterThan(T) of type Matchers is not applicable
for the arguments (DateTime). The inferred type DateTime is not a valid substitute
for the bounded parameter >

Am I right in thinking that the signature of greaterThan should actually be

public static <T extends java.lang.Comparable<? super T>> org.hamcrest.Matcher<? super T>     
    greaterThan(T value)

? And is there a way to fit these together short of casting to the raw Comparable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三生殊途 2024-12-20 12:20:25

是的,在我看来这将是一个更好的签名。

您是否尝试过明确指定比较类型?

Matchers.<ReadableInstant>greaterThan(new DateTime());

不幸的是,我不相信您可以使用静态导入来调用它并指定类型参数 - 但这可能不会太困难。

当然,另一种方法是提出论点:

greaterThan((ReadableInstant) new DateTime());

我手头没有 Hamcrest,但在测试类型中使用您给我的签名,上面的方法对我来说效果很好。

Yes, it looks to me like that would be a better signature.

Have you tried specifying the comparison type explicitly?

Matchers.<ReadableInstant>greaterThan(new DateTime());

I don't believe you can call it using a static import and also specifying the type argument, unfortunately - but that may not be too much of hardship.

Of course an alternative is to cast the argument:

greaterThan((ReadableInstant) new DateTime());

I don't have Hamcrest handy, but the above worked fine for me using the signature you'd given me, in a test type.

眼泪也成诗 2024-12-20 12:20:25

如果您经常使用它并且对转换感到困扰,您还可以像这样实现自己的 Matcher:

public static Matcher<AbstractPartial> isAfter(final AbstractPartial partial) {
    return new BaseMatcher<AbstractPartial>(){

        @Override
        public void describeTo(final Description description) {
            description.appendText("after partial: ").appendValue(partial);
        }

        @Override
        public boolean matches(final Object object) {
            if (object instanceof AbstractPartial) {
                return ((LocalDate) object).isAfter(partial);
            }
            return false;
        }
    };
}

并像这样测试它:

    Set<LocalDate> dates = Sets.newHashSet(new LocalDate(2013, 1, 1), new LocalDate(2013, 1, 2), new LocalDate(
        2013, 1, 3));
    assertThat(
        CollectionUtils.isEqualCollection(filter(isAfter(new LocalDate(2013, 1, 1)), dates),
            Lists.newArrayList(new LocalDate(2013, 1, 2), new LocalDate(2013, 1, 3))), is(true));

如果您想使用 DateTime 而不是 LocalDate,只需在第一个清单中用 AbstractInstant 替换 AbstractPartial 即可。

If you use it often and are bothered by the conversion, you can also implement your own Matcher like this:

public static Matcher<AbstractPartial> isAfter(final AbstractPartial partial) {
    return new BaseMatcher<AbstractPartial>(){

        @Override
        public void describeTo(final Description description) {
            description.appendText("after partial: ").appendValue(partial);
        }

        @Override
        public boolean matches(final Object object) {
            if (object instanceof AbstractPartial) {
                return ((LocalDate) object).isAfter(partial);
            }
            return false;
        }
    };
}

And test it like this:

    Set<LocalDate> dates = Sets.newHashSet(new LocalDate(2013, 1, 1), new LocalDate(2013, 1, 2), new LocalDate(
        2013, 1, 3));
    assertThat(
        CollectionUtils.isEqualCollection(filter(isAfter(new LocalDate(2013, 1, 1)), dates),
            Lists.newArrayList(new LocalDate(2013, 1, 2), new LocalDate(2013, 1, 3))), is(true));

If you want to use DateTime instead of LocalDate, just substitute AbstractPartial with AbstractInstant in the first listing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文