3

所以我们有一个名为 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

4 回答 4

3

以下是调用 compose 的方法:

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,那么是的,在这种情况下您需要使用泛型。

于 2013-02-26T17:56:16.593 回答
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 ));
   }
}
于 2013-02-26T17:48:12.817 回答
1

一个例子:

Func<A,B>将 String ( A) 转换为 Integer ( B)的A。

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>实现,将 Integer ( A) 转换为 String ( 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()语句并运行代码。

于 2013-02-26T17:54:31.380 回答
0

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

于 2013-02-26T17:58:39.827 回答