一流的功能

时间:2013-02-26 17:37:18

标签: java generics first-class-functions

所以我们有一个名为Func.java的接口,如下所示:

public interface Func<A,B> {
    public B apply(A x);
}

然后我们有一个名为mainClass.java的主类,它看起来像这样:

public class mainClass{
    public static void main(String[] args) {
    }

    public static <A,B,C> Func<A,C> compose(final Func<A,B> f, final Func<B,C> g){
        return new Func<A,C>(){
            public C apply(A x){
                return g.apply(f.apply(x));
            }
        };
    }
}

我不确定如何在main方法中调用这个compose方法,以及这段代码实际编译的方式!我的意思是,这里需要java泛型吗?

4 个答案:

答案 0 :(得分:3)

您可以通过以下方式致电撰写:

public class mainClass {
    public static <A, B, C> Func<A, C> compose(final Func<A, B> f, final Func<B, C> g) {
        return new Func<A, C>() {
            public C apply(final A x) {
                return g.apply(f.apply(x));
            }
        };
    }

    public static void main(final String[] args) {
        Func<String, Double> toDouble = new Func<String, Double>() {
            public Double apply(final String x) {
                return Double.parseDouble(x);
            }
        };
        Func<Double, Integer> toInt = new Func<Double, Integer>() {
            public Integer apply(final Double x) {
                return (int) x.doubleValue();
            }
        };
        Func<String, Integer> composed = compose(toDouble, toInt);
        System.out.println("Composed: " + composed.apply("1.23"));
    }
}

我不太确定你要求仿制药是什么。从字面意义上说,不,它们不是。 Java泛型只是为您提供类型安全性。您当然可以完全废弃它们,并将A,B和C更改为仅作为对象。但是,如果要显式定义正在使用的类型,比如在我的示例中使用String,Integer和Double,那么是的,在这种情况下需要使用泛型。

答案 1 :(得分:1)

public class FirstClassFunction {
   interface Func< A, B > {
      public B apply( A x );
   }

   static <A, B, C>
   Func< A, C > compose( final Func< A, B > f, final Func< B, C > g ) {
      return new Func< A, C >() {
         @Override public C apply( A x ) {
            return g.apply( f.apply( x ) );
         }};
   }

   public static void main( String[] args ) {
      Func< Double, Character > f =
         new Func< Double, Character >(){
            @Override public Character apply( Double x ) {
               return 'a';
            }};
      Func< Character, String > g =
         new Func< Character, String >(){
            @Override public String apply( Character x ) {
               return "Hello";
            }};
      Func< Double, String > c = compose( f, g );
      System.out.println( c.apply( 3.14 ));
   }
}

答案 2 :(得分:1)

一个例子:

Func<A,B>将字符串(A)转换为整数(B)。

class Converter implements Func<String, Integer> {
    @Override
    public Integer apply(String x) {
         // System.out.println("Converter converting String \"" + x + "\" to an Integer");
        return Integer.valueOf(x);
    }
}

另一个Func<A,B>实现,它将整数(A)转换为字符串(B),表示该Strig的二进制表示

class Binary implements Func<Integer, String> {
    @Override
    public String apply(Integer x) {
        // System.out.println("Binary converting Integer " + x + " to binary String");
        return Integer.toBinaryString(x);
    }
}

一种展示它的main方法。

public static void main(String[] args) {
    // compose those to functions and you can convert strings representing
    // numbers (base 10) to Strings that represent the same number (base 2)
    Func<String, String> binaryStringConverter = compose(new Converter(), new Binary());
    System.out.println(binaryStringConverter.apply("123"));
}

为了更好地了解发生了什么,您可以取消注释System.out.println()语句并运行代码。

答案 3 :(得分:0)

如果您在仅包含实数操作的问题域中工作,则不一定需要泛型 - Func的接口可能只是public double apply(double x)。但是使用泛型可以让您灵活地将函数从一种类型转换为另一种类型。 compose方法只是为你提供了一种链接函数的方法,就像普通的数学函数组合一样。