java – Guava为什么toStringFunction不是泛型函数?

前端之家收集整理的这篇文章主要介绍了java – Guava为什么toStringFunction不是泛型函数?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Guava toStringFunction()具有以下声明:
public static Function<Object,String> toStringFunction() { ... }

Object的所有非原始根,因此该函数运行良好.

但是当我尝试用另一个函数组合它时,例如:

Function<Integer,Double> f1 = Functions.compose(Functions.forMap(someMap),Functions.toStringFunction());

someMap变量是map< String,Double>,所以我希望toStringFunction将Integer转换为String,然后forMap将String转换为Double.
但是我收到编译错误

Function<Integer,^
  required: Function<Integer,Double>
  found:    Function<Object,Double>
2 errors

我的两个问题是:

1.具体告诉编译器toStringFunction应该是Function<整数,字符串>?一个简单的演员不会起作用,我正在寻找这两个函数的真实组合.

Function< Integer,String> g1 = (Function< Integer,String>)Functions.toStringFunction(); 

// cause error

2.将toStringFunction写成如下:

@SuppressWarnings("unchecked") 
  public static <E> Function<E,String> toStringFunction(){
    return (Function<E,String>) ToStringFunction.INSTANCE;
  }

  // enum singleton pattern
  private enum ToStringFunction implements Function<Object,String>{
    INSTANCE;


    // @Override public String toString(){
    //   return "Functions.toStringFunction()";
    // }

    @Override public String apply(Object o){
      return o.toString();
    }
  }

我可以指定类型:

Function<Integer,Functions.<Integer>toStringFunction());

这很好用.但番石榴团队现在拥有的版本的动机是什么?

解决方法

经过评论讨论后:

要修复编译错误

Function<Object,Double> f1 = 
    Functions.compose(Functions.forMap(someMap),Functions.toStringFunction());

你的问题意味着你需要一个函数< Integer,Double>而不是函数< Object,Double>.根据评论中的讨论,并试图考虑其他方案,您想要这个的唯一原因是验证. toStringFunction中的代码不受您的控制,因此该函数中的验证是不可能的.至于forMap函数中的验证,该代码也是您无法控制的.如果要防止IllegalArgumentException,则无论您提供的输入是Object还是Integer,都必须执行此验证.因此,验证也超出了forMap,toStringFunction和compose的范围,因为这些函数都没有提供这种验证,你必须编写自己的代码来执行此操作(捕获异常并处理它或预先验证在调用这个组合函数之前以某种方式).

对于特定的组合,通过将Function的输入参数从Object更改为Integer,你什么也得不到,因为Function只需要Object中的方法,所以这是一个很好的决定,因为它简化了这种情况下的事情并使其更广泛可用.假设您能够将参数类型强制为Integer,您仍然无法获得任何好处,无论是IllegalArgumentException的验证还是您正在尝试的其他内容.

在设计API时,您希望尽可能多的消费者使用它,而不必偏离您的方式,即您应该使用满足您要求的最高级别的类.通过在toStringFunction中使用Object,Guava函数满足了这个原则.这使得该功能更通用并且可以更广泛地使用.这就是选择Object而不是参数化此函数的原因.

如果函数接受了一个参数,它就不会像现在这样做,所以为什么在不需要时使用参数.这种方法大大简化了设计,而不是添加不需要的东西.

原始答案:

每个类都是Object的子类,Function只调用Object类中存在的输入上的toString.因此,在这种情况下,声明一个Function等同于声明Function.通过将Function的输入参数从Object更改为Integer,您将无法获得任何结果,因为它简化了这种情况下的事情.

您应尽可能使用满足您要求的最高级别的课程.这使得该功能更通用并且可以更广泛地使用.这就是选择Object而不是参数化此函数的原因.

修复编译错误函数f1 = Functions.compose(Functions.forMap(someMap),Functions.toStringFunction());

猜你在找的Java相关文章