Java N级嵌套泛型

时间:2014-01-02 03:44:23

标签: java generics

我想知道是否有任何允许N级嵌套泛型的东西?

假设我有

class Example< A > {
    ...
}

有什么技巧可以获得

Example<Example<Example<Example<Example<Example<...A...>>>>>>>

当程序运行时(即没有硬编码)?

我想知道这个的原因是因为我参数化了单变量多项式类的系数 - 所以我得到了多项式&lt; C>,其中C是系数的类​​型,C可以是Integer,Rational,Polynomial(这可以解决多元多项式问题),或许多其他事情。

Polynomial< Polynomial< Integer > > 

对于两个可变多项式可能没问题,但如果它到达任意数量的变量,我就会遇到麻烦。我意识到这可能是糟糕的设计。有没有办法解决这个问题(除了重启)?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

实际上有一种方法可以使用参数递归来解决这个问题。它没有给你准确的N嵌套参数化,但它解决了必须输入的问题

Example< Example < Example< ... ... > > > >

我今天偶然发现了一篇关于这个主题的文章:http://www.cs.ubbcluj.ro/~studia-i/2011-4/02-Niculescu.pdf

关于Java Generics的部分,请跳至第4部分。以下是我从文章关于参数递归和我尝试的编码实验的讨论中得到的结果。

我从没想过会尝试这样的事情:

public interface RingElem< T extends RingElem< T > > {

    public abstract RingElem< T > add( RingElem< T > e );

    public abstract RingElem< T > multiply( RingElem< T > e );
}

我没有意识到你可以通过扩展&#34;本身的东西来参数化接口。&#34;现在,如果你有一个RingElem对象,那么它将被T参数化,类型为RingElem。通过递归,你几乎拥有RingElem< RingElem < RingElem < ... > > >,但它是无限的&#34;嵌套。

现在,您可以实现RingElem接口来创建自己的多项式类:

public class Polynomial implements RingElem< Polynomial > {

    ///...
}

如果您有Polynomial个对象,则将其参数化为Polynomial< Polynomial< ... ... > >

当我在脑海中想到这一点时,我怀疑你是否可以初始化这样一个物体。但是一旦我开始编码,它似乎很简单。以下是3个课程我和#34;黑客攻击&#34;一起允许人们操纵多元单项式。我会用更好的设计重写(我应该使用public interface Monomial< T extends Polynomial< T > >,其中T是Monomial的系数类型)并在我得到时间时添加注释。

如示例所示,您可以获得使用字母表中每个字母的多元单项式,而无需键入Monomial< Monomial< Monomial< Monomial< ... ... > > > 26次。

单项式:(例如5x ^ 2,4a ^ -5)

public class Monomial implements RingElem< Monomial > {

    private Monomial m_coefficient;

    private Monomial m_base;

    private Monomial m_exponent;

    public Monomial() {

    }

    public Monomial( Monomial coefficient , Monomial base , Monomial exponent ) {
        if ( base.m_coefficient != null ) {
            this.m_coefficient = coefficient.multiply( base.m_coefficient );
            if ( base.m_base != null ) {
                this.m_coefficient = coefficient.multiply( base.m_base );
            }
        }
        else {
            this.m_coefficient = coefficient;
        }
        this.m_exponent = exponent;
        this.m_base = base;
    }

    @Override
    public Monomial add( RingElem< Monomial > e ) {
        if ( e instanceof Monomial ) {
            Monomial addend = (Monomial) e;
            if ( this.m_base.equals( addend.m_base ) && this.m_exponent.equals( addend.m_exponent ) ) {
                Monomial rtn = new Monomial( this.m_coefficient.add( addend.m_coefficient ) , this.m_base , this.m_exponent );
                return rtn;
            }
            else {
                throw new RuntimeException( "Addition would produce a polynomial, which is not implemented yet!" );
            }
        }
        else {
            throw new RuntimeException( "Operation not defined" );
        }
    }

    @Override
    public Monomial multiply( RingElem< Monomial > e ) {
        if ( e instanceof Constant ) {
            Constant c = ( Constant ) e;
            return new Monomial( this.m_coefficient.multiply( c ) , this.m_base , this.m_exponent );
        }
        else if ( e instanceof Monomial ) {
            Monomial m = ( Monomial ) e;
            return new Monomial( this.m_coefficient.multiply( m.m_coefficient ).multiply( m.m_base ) , this.m_base , this.m_exponent.add( m.m_exponent ));
        }
        else {
            throw new RuntimeException( "Operation not defined" );
        }
    }

    @Override
    public String toString() {
        if ( this.m_coefficient == null || this.m_base == null || this.m_exponent == null ) {
            return "<error>";
        }
        return this.m_coefficient.toString() + this.m_base.toString() + "^" + this.m_exponent.toString();
    }

    final public static void main( String[] args ) {
        String[] letters = { "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" , "u" , "v" , "w" , "x" , "y" , "z" };
        Variable[] v = new Variable[ letters.length ];
        for ( int i=0 ; i<letters.length ; i++ ) {
            v[ i ] = new Variable( letters[ i ] );
        }
        Monomial coefficient = new Constant( 1.2 );
        Monomial exponent = new Constant( 4.5 );
        Monomial test = new Monomial( coefficient , v[ 0 ] , exponent );
        for ( int i=1 ; i<letters.length ; i++ ) {
            test = test.multiply( new Constant( 1.2 ) );
            test = new Monomial( test , v[ i ] , new Constant( (int)(Math.random() * 25 )) );
        }
        System.out.println( test.toString() );
    }

    @Override
    public boolean equals( Object o ) {
        if ( o instanceof Monomial ) {
            Monomial m = ( Monomial ) o;
            return this.m_coefficient.equals( m.m_coefficient ) && this.m_base.equals( m.m_base ) && this.m_exponent.equals( m.m_exponent );
        }
        else {
            return false;
        }
    }
}

常数类:(例如1,2,2.115159,-10000)

public class Constant extends Monomial {

    private double m_val;

    public Constant( double val ) {
        super();

        this.m_val = val;
    }

    @Override
    public Constant add ( RingElem e ) {
        if ( e instanceof Constant ) {
            Constant c = ( Constant ) e;
            return new Constant( this.m_val + c.m_val );
        }
        else if ( e instanceof Variable ) {
            throw new RuntimeException( "Operation would create a polynomial, which is not defined yet!" );
        }
        else {
            throw new RuntimeException( "Operation not defined" );
        }
    }

    @Override
    public Monomial multiply( RingElem e ) {
        if ( e instanceof Constant ) {
            Constant c = ( Constant ) e;
            return new Constant( this.m_val * c.m_val );
        }
        else if ( e instanceof Variable ) {
            return new Monomial( this.clone() , (Variable) e , new Constant( 1 ) );
        }
        else {
            throw new RuntimeException( "Operation not defined" );
        }
    }

    @Override
    public String toString() {
        return String.valueOf( this.m_val );
    }

    @Override
    public boolean equals( Object o ) {
        if ( o instanceof Constant ) {
            Constant c = ( Constant ) o;
            return this.m_val == c.m_val;
        }
        else {
            return false;
        }
    }

    @Override
    public Constant clone() {
        return new Constant( this.m_val );
    }
}

变量类:(例如x,y,z)

public class Variable extends Monomial {

    final private String m_varName;

    public Variable( String varName ) {
        this.m_varName = varName;
    }

    @Override
    public Monomial add( RingElem e ) {
        if ( e instanceof Variable ) {
            if ( e.equals( this ) ) {
                return new Monomial( new Constant( 2 ) , this , new Constant( 1 ) );
            }
            else {
                throw new RuntimeException( "Operation would create a polynomial, which is not defined yet!" );
            }
        }
        else if ( e instanceof Monomial ) {
            throw new RuntimeException( "Operation would create a polynomial, which is not defined yet!" );
        }
        else {
            throw new RuntimeException( "operation not defined!" );
        }
    }

    @Override
    public Monomial multiply( RingElem e ) {
        if ( e instanceof Constant ) {
            Constant c = ( Constant ) e;
            return c.multiply( this );
        }
        if ( e instanceof Variable ) {
            return new Monomial( (Variable) e , this , new Constant( 1 ) );
        }
        else {
            return this.multiply( e );
        }
    }

    @Override
    public String toString() {
        return this.m_varName;
    }

    @Override
    public boolean equals( Object o ) {
        if ( o instanceof Variable ) {
            Variable v = ( Variable ) o;
            return this.m_varName.equals( v.m_varName );
        }
        else {
            return false;
        }
    }
}