java-为什么需要在此处添加类型,还有更好的方法吗?

以下代码无法编译,

  Validation<String, AdRequest> validateTrackingRequest(final AdRequest request) {
    return request.getTracking().stream()
        .filter(tracker -> tracker.url().length() > URL_CHAR_LIMIT).findAny()
        .map(tracker ->
            Validation.invalid("Tracking URL for event " + tracker.type() + " exceeds "
                               + URL_CHAR_LIMIT + " character limit: " + tracker.url()))
        .orElse(Validation.valid(request));
  }

与错误消息,

Incompatible types. Required: Validation<String, AdRequest>. Found Validation<String, Object>.

进行一些试验,我发现在调用map之前添加以下奇怪的语法可以解决此问题:

        .<Validation<String, AdRequest>>map(tracker ->

(我以前见过其他人这样做.)

这是什么样的语法?

我知道发生这种情况是因为Validation.invalid的基础机制必须基于通用对象,因此必须进行某种类型的强制转换.因此,也许这种语法就是“ cast”.

但是,还有一种更好的方式来写我在做什么吗?

(这是javaslang a.k.a. vavr的验证库.)

解决方法:

这称为带有显式类型参数的方法调用.您可以使用不太“奇怪”的语法:

Validation.<String, AdRequest>invalid(...)

问题在于Validation.invalid方法的定义方式以及将在其中调用什么上下文.

static <E, T> Validation<E, T> invalid(E error)

由于map不在乎结果的类型,因此无法隐式确定第二个通用参数T.

// no context
Validation<String, Object> v1 = Validation.invalid("error");

// the context set explicitly 
Validation<String, AdRequest> v2 = Validation.<String, AdRequest>invalid("error");

// the type is determined by the context implicitly
Validation<String, AdRequest> v3 = Validation.invalid("error");

要弄清楚类型,应显示上下文. Optional.map不会为您提供此上下文.它与您传递的任何结果类型R完美配合:

// v1 = Validation<String, Object>
Optional<Validation<String, Object>> o1 = ofNullable(null).map(i -> v1);

// v2 = Validation<String, AdRequest>
Optional<Validation<String, AdRequest>> o2 = ofNullable(null).map(i -> v2);

它将根据您提供的类型返回通用实例.您正在提供Validation< String,Object>对象,因此您将获得map(Function< ...,Validation< String,Object>>),这会使orElse混乱并与返回类型相矛盾.

这只是一个品味问题,但是我将一些内容放入变量中:

Validation<String, AdRequest> validateTrackingRequest(AdRequest request) {
    Validation<String, AdRequest> valid = Validation.valid(request);
    Function<Tracker, Validation<String, AdRequest>> mapper = tracker -> Validation.invalid(...);
    Predicate<Tracker> predicate = tracker -> ...;

    return request.getTracking().stream().filter(predicate).findAny().map(mapper).orElse(valid);
}
上一篇:JavaScript中的Boolean对象和Boolean数据类型有什么区别?


下一篇:是否有标头提供与uint64_t类似的类型用于Linux或gcc中的浮点和双精度?