Я бы начал с монома:
package poly;
public class Monomial
{
private final double coeff;
private final int expon;
public Monomial()
{
this(0.0, 0);
}
public Monomial(double coeff)
{
this(coeff, 0);
}
public Monomial(double coeff, int expon)
{
this.coeff = coeff;
this.expon = expon;
}
public double getCoeff()
{
return coeff;
}
public int getExpon()
{
return expon;
}
public Monomial add(Monomial other)
{
if (this.expon != other.expon)
throw new IllegalArgumentException("Exponents must match in order to add");
return new Monomial((this.coeff+other.coeff), this.expon);
}
public Monomial sub(Monomial other)
{
if (this.expon != other.expon)
throw new IllegalArgumentException("Exponents must match in order to subtract");
return new Monomial((this.coeff-other.coeff), this.expon);
}
public Monomial mul(Monomial other)
{
return new Monomial((this.coeff*other.coeff), (this.expon+other.expon));
}
public Monomial div(Monomial other)
{
return new Monomial((this.coeff/other.coeff), (this.expon-other.expon));
}
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
Monomial monomial = (Monomial) o;
if (Double.compare(monomial.coeff, coeff) != 0)
{
return false;
}
if (expon != monomial.expon)
{
return false;
}
return true;
}
@Override
public int hashCode()
{
int result;
long temp;
temp = coeff != +0.0d ? Double.doubleToLongBits(coeff) : 0L;
result = (int) (temp ^ (temp >>> 32));
result = 31 * result + expon;
return result;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
if (coeff != 1.0) sb.append(coeff);
if (expon != 0) {
sb.append('x');
if (expon != 1) sb.append('^').append(expon);
}
return sb.toString();
}
}
И юнит-тест, конечно же:
package poly;
import org.junit.Assert;
import org.junit.Test;
public class MonomialTest
{
private static final double DELTA = 0.001;
@Test
public void testConstructor_Default()
{
Monomial test = new Monomial();
Assert.assertEquals("0.0", test.toString());
}
@Test
public void testConstructor_Constant()
{
Monomial test = new Monomial(2);
Assert.assertEquals("2.0", test.toString());
}
@Test
public void testConstructor()
{
Monomial test = new Monomial(6, 3);
Assert.assertEquals("6.0x^3", test.toString());
Assert.assertEquals(6.0, test.getCoeff(), DELTA);
Assert.assertEquals(3, test.getExpon());
}
@Test
public void testAddSuccess()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(3, 3);
Monomial expected = new Monomial(5, 3);
Assert.assertEquals(expected, x.add(y));
}
@Test(expected = IllegalArgumentException.class)
public void testAdd_MismatchedExponents()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(3, 4);
x.add(y);
}
@Test
public void testSubSuccess()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(3, 3);
Monomial expected = new Monomial(-1, 3);
Assert.assertEquals(expected, x.sub(y));
}
@Test(expected = IllegalArgumentException.class)
public void testSub_MismatchedExponents()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(3, 4);
x.sub(y);
}
@Test
public void testMulSuccess()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(3, 3);
Monomial expected = new Monomial(6, 6);
Assert.assertEquals(expected, x.mul(y));
}
@Test
public void testDivSuccess()
{
Monomial x = new Monomial(4, 4);
Monomial y = new Monomial(2, 3);
Monomial expected = new Monomial(2, 1);
Assert.assertEquals(expected, x.div(y));
}
@Test
public void testEquals_null()
{
Monomial x = new Monomial();
Assert.assertFalse(x.equals(null));
}
@Test
public void testEquals_reflexive()
{
Monomial x = new Monomial(2, 3);
Assert.assertTrue(x.equals(x));
}
@Test
public void testEquals_symmetric()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(2, 3);
Assert.assertTrue(x.equals(y) && y.equals(x));
Assert.assertEquals(x.hashCode(), y.hashCode());
}
@Test
public void testEquals_transitive()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(2, 3);
Monomial z = new Monomial(2, 3);
Assert.assertTrue(x.equals(y) && y.equals(z) && z.equals(x));
Assert.assertEquals(x.hashCode(), y.hashCode());
Assert.assertEquals(y.hashCode(), z.hashCode());
Assert.assertEquals(z.hashCode(), x.hashCode());
}
@Test
public void testEquals_differentCoefficients()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(3, 3);
Assert.assertFalse(x.equals(y));
Assert.assertFalse(x.hashCode() == y.hashCode());
}
@Test
public void testEquals_differentExponents()
{
Monomial x = new Monomial(2, 3);
Monomial y = new Monomial(2, 4);
Assert.assertFalse(x.equals(y));
Assert.assertFalse(x.hashCode() == y.hashCode());
}
}
Тогда я бы написал полином, в котором List<Monomial>
был бы закрытым элементом данных.
Возможно, вам нужен общий интерфейс для двух, так как вы сказали Composite. Но это только начало.