通用类,可以采用任何数字或可以添加的其他任何形式

时间:2019-04-11 13:48:59

标签: java generics wildcard

标题一定是令人困惑的,让我解释一下:我正在编写多项式,到目前为止,它仅适用于双系数。

我的想法是使此类成为通用类,用户可以在其中指定系数的类型,例如Polynomial<Double>。现在,系数不能是任何类的对象,因为它们必须具有加法,减法...方法。

为解决这个问题,我用必要的方法(加,减,乘,除)和现在的Polynomial<? extends Arithmetic>制作了一个算术接口。

但是,由于Double没有实现此接口,因此用户当然不能再使用多项式。

最后我的问题是:如何以用户可以传递java.lang.Number(或至少Double)或我的算术接口的子类的方式使多项式通用?如果无法解决,该怎么办?

2 个答案:

答案 0 :(得分:2)

一种方法是定义一个Polynomial<T>不受任何限制的T 接口

然后执行ArithmeticPolynomial implements Polynomial<Arithmetic>

然后,您可以为Number类型执行另一种实现,只需重复使用ArithmeticPolynomial,如下所示:NumberPolynomial<T extends Number> implements Polynomial<T>。这将使用包装器/适配器类NumberArithmetic。将Number封装(适应)到Arithmetic

如果我对您的理解正确,那就可以了。

答案 1 :(得分:1)

我将使用递归数据结构来解决这个问题。

import java.util.ArrayList;
import java.util.List;

public class Polynomial {

private static class Term{
    Object coefficient;
    Object base;
    Object power;

    Term(Variable v){
        this.coefficient = 1;
        this.base = v;
        this.power = 1;
    }

    Term(Number n){
        this.coefficient = 1;
        this.base = n;
        this.power = 1;
    }

    public String toString(){
        String tmp = "";
        if(coefficient instanceof Number){
            double c = ((Number) coefficient).doubleValue();
            if(c != 1.0)
                tmp += ((Number) coefficient).doubleValue();
        }
        if(coefficient instanceof Polynomial){ tmp += "(" + coefficient.toString() + ")";}

        if(!tmp.isEmpty())
            tmp += "•";

        if(base instanceof  Number){ tmp += ((Number) base).doubleValue(); }
        if(base instanceof Variable){tmp += base.toString(); }

        if(power instanceof Number){
            double p = ((Number) power).doubleValue();
            if(p != 1.0)
                tmp += ((Number) power).doubleValue();
        }
        if(power instanceof Polynomial){tmp += base.toString(); }

        // return
        return tmp;
    }
}

private List<Term> terms = new ArrayList<>();

public Polynomial add(Variable variable){
    if(terms.isEmpty()){
        terms.add(new Term(variable));
        return this;
    }
    // search for same variable
    for(Term t : terms){
        if(t.base.equals(variable)){
            addToCoefficient(t);
            return this;
        }
    }
    // similar term not found
    terms.add(new Term(variable));
    return this;
}

public Polynomial add(Number number){
    if(terms.isEmpty()){
        terms.add(new Term(number));
        return this;
    }
    // search for any number
    for(Term t : terms){
        if(t.base instanceof Number){
            t.base = ((Number) t.base).doubleValue() + number.doubleValue();
            return this;
        }
    }
    // default
    return this;
}

private void addToCoefficient(Term t){
    if(t.coefficient instanceof Number){ t.coefficient = ((Number) t.coefficient).doubleValue() + 1.0; }
    if(t.coefficient instanceof Polynomial){ t.coefficient = ((Polynomial) t.coefficient).add(1); }
}

public String toString(){
    String tmpA = "";
    String tmpB = "";
    for(Term t : terms) {
        tmpA = t.toString();
        tmpB += (tmpA.startsWith("+") || tmpB.startsWith("-")) ? tmpA : ("+" + tmpA);
    }
    return tmpB;
}

}

此类实际上将多项式存储为项列表。

只要需要运算(例如加法),多项式类就会决定:

  • 我是否需要为此单独创建一个术语
  • 还是我需要将算术委托给现有术语

创建一个单独的术语很简单

委派一个现有术语通常意味着对该术语的功效或系数进行某种运算。

要么是数字(在这种情况下为easy peasy),要么是多项式,您只需递归到数据结构中即可。

我提供的代码可以这样称呼:

public static void main(String[] args) {

    Polynomial p = new Polynomial();
    p.add(3)
            .add(10)
            .add(new Variable("a"))
            .add(new Variable("a"));

    System.out.println(p);
}

哪个输出:

  

+ 13.0 + 2.0•a