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));
            }
        };
    }
}

メインメソッドでこの構成メソッドを呼び出す方法と、このコードが実際にどのようにコンパイルされるかはよくわかりません! つまり、これが機能するためにここで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>変換するです。AB

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);
    }
}

その Strig のバイナリ表現を表すFunc<A,B>Integer ( A) を String ( ) に変換する別の実装B

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 に答える