Inheritance hierarchy for number system classes - java

For symbolic representation of mathematical expressions, I am trying to build a hierarchy of number system classes.
In addition to Integer and Real, I also need classes like Rational and Complex. I want all of these classes to inter-operate seamlessly with each other.
e.g. Adding a Complex number to an Integer would give a Complex number etc.
I made all of them to implement the Number interface. (NOT java.lang.Number)
For being able to add numbers of different types, I tried making hierarchy like following.
Integer extends Rational extends Real extends Complex
This makes an Integer to unnecessarily store imaginary part etc. This overhead is undesired.
Also allowing access to imaginary part of an Integer seems improper.
Can anyone suggest a better design where overhead is avoided and interoperation is still possible?

I'd rather create an interface that has something like getRealPart() and getImaginaryPart(). Then your integer can simply return 0 for getImaginaryPart(). That since you want Integer to "be" a Complex, but you don't want Integer to contain the internal implementation of Complex.

public interface Numberr {
public Numberr plus(Numberr n);
public Numberr minus(Numberr n);
public Numberr multiply(Numberr n);
public Numberr sqrt();
...
public Class<? extends Numberr> getType();
}
/////////////////////////////////////////////
public class Integerr implements Numberr {
protected BigInteger value;
#Override
public Numberr plus(Numberr n) {
if (n instanceof Integerr) {
return value.add(n.value);
} else {
// in case of more broad argument type, use method of that class
return n.plus(this);
}
}
....
}
///////////////////////////////////////////////
public class Rational implements Numberr {
protected BigInteger numerator;
protected BigInteger denominator;
#Override
public Numberr plus(Numberr n) {
if (n instance of Integerr) {
return new Rational(numerator.multiply(n.value), denominator);
} else if (n instanceof Rational) {
return new Rational(numerator.multiply(n.denominator).add(n.numerator.multiply(denominator)), denominator.multiply(n.denominator));
} else {
return n.plus(this);
}
}
....
}

I don't see a problem here. Real number is a complex number, integer is a real number. Complex number can be expressed as a + bi and an integer is a complex number, such that a is an integer and b = 0. So every integer has b and it is equal to 0.
You may however consider using composition (and interfaces) over inheritance:
interface Complex {
Real a();
Real b();
}
interface Real extends Complex {
#Override
default Real b() {
return new Integer(0);
}
}
class Integer implements Real {
public Integer(int value) {
// ...
}
#Override
public Real a() {
return this;
}
// ...
}
The disadvantage of this approach is that Integer class can override b() method, so maybe inheritance would be better, because you can use final keyword on the method:
abstract class Complex {
abstract Real a();
abstract Real b();
}
abstract class Real extends Complex {
#Override
public final Real b() {
return new Integer(0);
}
}
class Integer extends Real {
public Integer(int value) {
// ...
}
#Override
public Real a() {
return this;
}
// ...
}
I have tried to model it myself and I came up with this terrible code below. I am not happy about it, because of the following problems:
Interface - InterfaceImpl antipattern
IntegerNumber has methods such as realPart() or numerator() and denominator()
some numbers (complex and rational) use other numbers, while others (real and integer) use Java primitives
Code:
public class Test {
public static void main(String[] args) {
ComplexNumber complexOne = new ComplexNumber(new RealNumber(1.25), new RealNumber(3));
ComplexNumber complexTwo = new ComplexNumber(new RealNumber(7), new RealNumber(18.875));
System.out.println("adding two complex numbers:");
System.out.println(complexOne.add(complexTwo));
RealNumber realOne = new RealNumber(15.125);
RealNumber realTwo = new RealNumber(7.375);
System.out.println("adding two real numbers:");
System.out.println(realOne.add(realTwo));
System.out.println(realTwo.add(realOne));
System.out.println("adding complex and real number:");
System.out.println(complexOne.add(realOne));
System.out.println(realOne.add(complexOne));
RationalNumber rationalOne = new RationalNumber(new IntegerNumber(1), new IntegerNumber(2));
RationalNumber rationalTwo = new RationalNumber(new IntegerNumber(1), new IntegerNumber(3));
System.out.println("adding two rational numbers:");
System.out.println(rationalOne.add(rationalTwo));
IntegerNumber integerOne = new IntegerNumber(6);
IntegerNumber integerTwo = new IntegerNumber(7);
System.out.println("adding two integers:");
System.out.println(integerOne.add(integerTwo));
System.out.println("adding real number and integer:");
System.out.println(integerOne.add(realOne));
System.out.println(realOne.add(integerOne));
System.out.println("adding complex number and integer:");
System.out.println(integerOne.add(complexOne));
System.out.println(complexOne.add(integerOne));
}
}
// interfaces
interface Complex {
Real realPart();
Real imaginaryPart();
default Complex add(Complex other) {
return new ComplexNumber(
this.realPart().add(other.realPart()),
this.imaginaryPart().add(other.imaginaryPart())
);
}
}
interface Real extends Complex {
double asDouble();
#Override
default Real imaginaryPart() {
return new IntegerNumber(0);
}
default Real add(Real other) {
return new RealNumber(this.asDouble() + other.asDouble());
}
}
interface Rational extends Real {
Integer numerator();
Integer denominator();
#Override
default Real realPart() {
return new RealNumber(1.0d * numerator().asInt() / denominator().asInt());
}
#Override
default double asDouble() {
return realPart().asDouble();
}
default Rational add(Rational other) {
return new RationalNumber(
this.numerator().multiply(other.denominator()).add(this.denominator().multiply(other.numerator())),
this.denominator().multiply(other.denominator())
);
}
}
interface Integer extends Rational {
int asInt();
#Override
default Integer numerator() {
return new IntegerNumber(asInt());
}
#Override
default Integer denominator() {
return new IntegerNumber(1);
}
default Integer add(Integer other) {
return new IntegerNumber(this.asInt() + other.asInt());
}
default Integer multiply(Integer other) {
return new IntegerNumber(this.asInt() * other.asInt());
}
}
// implementations
class ComplexNumber implements Complex {
private final Real realPart;
private final Real imaginaryPart;
public ComplexNumber(Real realPart, Real imaginaryPart) {
this.realPart = realPart;
this.imaginaryPart = imaginaryPart;
}
#Override
public Real realPart() {
return realPart;
}
#Override
public Real imaginaryPart() {
return imaginaryPart;
}
#Override
public String toString() {
return String.format("%s + %si", realPart, imaginaryPart);
}
}
class RealNumber implements Real {
private final double value;
public RealNumber(double value) {
this.value = value;
}
#Override
public Real realPart() {
return this;
}
#Override
public double asDouble() {
return value;
}
#Override
public String toString() {
return "" + value;
}
}
class RationalNumber implements Rational {
private final Integer numerator;
private final Integer denominator;
public RationalNumber(Integer numerator, Integer denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
#Override
public Integer numerator() {
return numerator;
}
#Override
public Integer denominator() {
return denominator;
}
#Override
public String toString() {
return String.format("%s/%s", numerator, denominator);
}
}
class IntegerNumber implements Integer {
private final int value;
public IntegerNumber(int value) {
this.value = value;
}
#Override
public int asInt() {
return value;
}
#Override
public String toString() {
return "" + value;
}
}
I am wondering whether interfaces should be abstract classes with implemented methods being final. In the end, I think it may be better to just go with simple inheritance and ignore the fact that every integer will have a field for imaginary part.
I hope this will give you some ideas.

Related

The use of a reference variable in this java code

Why is the reference variable ‚Input inside‘ necessary?
How does the ‚Input inside‘ work here?
What does the code: The code adds 5 to the x-value (in this case 4) and uses the square of the new value. So (4+5)^2.
Thank you. 😀
Code:
abstract class Input {
protected Input inside;
public Input() {
}
public Input(Input inside) {
this.inside = inside;
}
public int calculate(int value) {
if(inside == null) {
return value;
}
return inside.calculate(value);
}
public static void main(String[] args) {
Input chaincalculate = new Square(new AddFive());
int x;
x = 4;
System.out.println("The value is: " + (int) chaincalculate.calculate(x));
}
}
class AddFive extends Input {
public AddFive() {
}
public AddFive(Input inside) {
super(inside);
}
public int calculate(int value) {
value = super.calculate(value);
return value+5;
}
}
class Square extends Input {
public Square() {
}
public Square(Input inside) {
super(inside);
}
public int calculate(int value) {
value = super.calculate(value);
return value * value;
}
}
}
All the classes extending the abstract class Input, have their own calculate methods, and since, these classes, would want to use the abstract class Calculate method, the reference variable input inside is necessary to invoke/reference the calculate method residing in Input abstract class, to support the method chaining implemented in the code

Java: multiply generic Number without changing its type

Is there a way in Java to implement this method?
public static <T extends Number> T doubleOf(T number){
//I don't know...
}
Thanks
As mentioned in other answers, there is no general solution.
Beside others, the operation you want to implement may not be well defined for some Number subclasses. For instance, what is the multiple of AtomicInteger? Is it the same instance with a multiplied value? Or a new instance of AtomicInteger? Or a new plain Integer? Theoretically, there might be a subclass of Number that does not allow to create new instances freely.
You may test the input for some known subclasses and implement the operation for those. Something like this:
#SuppressWarnings("unchecked")
public static <N extends Number> N multiply(N number, int multiplier) {
Class<? extends Number> cls = number.getClass();
if (cls == Integer.class) {
return (N) Integer.valueOf(number.intValue() * multiplier);
}
if (cls == Long.class) {
return (N) Long.valueOf(number.longValue() * multiplier);
}
throw new UnsupportedOperationException("unknown class: " + cls);
}
I am afraid the suppression of warnings will be necessary, in some form.
Unfortunately it is not possible in Java because you can't instantiate an object of type T.
See this section of the Java generics tutorial: http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createObjects
A little bit late, but today i had this same problem.
My solution:
public Number multiply(Number number, int multiplier) {
return new Number() {
#Override
public long longValue() {
return number.longValue() * multiplier;
}
#Override
public int intValue() {
return number.intValue() * multiplier;
}
#Override
public float floatValue() {
return number.floatValue() * multiplier;
}
#Override
public double doubleValue() {
return number.doubleValue() * multiplier;
}
};
}
Simple answer is no. Number have no appropriate methods.
But as long as Number have several well known implementation you can just implement it for all of them. Of course if someone create new one you implementation will fail but it is very unlikely
public static <T extends Number> T doubleOf(T number){
if(number instanceOf Integer){
return (T)(Object)number.intValue()*2;
} ... and so on
}
Although a bit weird, you could use the following:
public static <T extends Number & Multipliable> T doubleOf(T number)
{
}
interface Multipliable<T extends Number>
{
T multiply(Number number);
}
class MyDouble extends Number implements Multipliable<MyDouble>
{
Double d;
public MyDouble(final double d)
{
this.d = new Double(d);
}
#Override
public MyDouble multiply(Number number)
{
return new MyDouble(d.doubleValue() * number.doubleValue());
}
#Override
public double doubleValue()
{
return d.doubleValue();
}
#Override
public float floatValue()
{
return d.floatValue();
}
#Override
public int intValue()
{
return d.intValue();
}
#Override
public long longValue()
{
return d.longValue();
}
}
This could be used like this:
MyDouble result = new MyDouble(2d).multiply(new Short((short) 1));

DRY maxima tracking

Suppose I am importing table entries, where a single entry can be stored in a class:
class Foo {
int i1;
int i2;
double d1;
}
After the import is complete, I will need to have access to the imported values themselves, as well as to their normalized versions. So far, I have implemented this functionality as follows:
class FooWithMaxTracking {
private int i1;
private static int i1_max=0;
public void setI1(int value){
this.i1 = value;
if (value > i1_max) { i1_max = value; }}
public int getI1(){
return i1;}
public double normI1(){
return i1/((double)i1_max);}
private int i2;
private static int i2_max=0;
public void setI2(int value){ <code identical to written above> }
public int getI2(){ ... }
public double normI2(){ ... }
// and another set of similar 2 variables & 3 functions for 'double d1'
}
In this implementation I strongly dislike the fact that I had to write the same code many times (only three in this example, but about ten times in the real project). Is there any way to make the code more DRY ("don't repeat yourself")?
If you do not mind a slight loss of performance, you can put all the maxima in a static Map, define a class that holds a getter, a setter, and a norm methods, and replace the individual variables with instances of that class:
private static Map<String,Object> max = new HashMap<String,Object>();
private static class IntMaxTrack {
private final String key;
private int value;
public IntMaxTrack(String k, int v) {
key = k;
value = v;
max.put(key, value);
}
public int get() { return value; }
public void set(int v) {
int m = ((Integer)max.get(key)).intValue();
value = v;
if (value > m) {
max.put(key, value);
}
}
public double norm() {
int m = ((Integer)max.get(key)).intValue();
return val / ((double)m);
}
}
Make a similar class for double, i.e. DblMaxTrack Now you can replace primitives with instances of these classes, and call their get, set, and norm from the corresponding methods of your class.
What about defining one class with the necessary code, like:
public class Bar {
private int i1;
private static int i1_max = 0;
public void setI1(int value) {
// ...
}
public int getI1() {
// ...
}
public double normI1() {
// ...
}
}
And using it sevearl times, like:
class FooWithMaxTracking {
one = new Bar();
two = new Bar();
three = new BarForDouble();
}

Implementing compareTo using wildcard generics

I have to implement a class ComplexNumber. It has two generic parameter T and U, which must be from some class that inherits from Number class. The Complex class has 2 fields( instance variables) : real and imaginary part, and has to implement these methods :
ComplexNumber(T real, U imaginary) - constructor
getReal():T
getImaginary():U
modul():double - this is modulus of complex number
compareTo(ComplexNumber<?, ?> o) - this method makes comparison based on modulus of 2 complex numbers
I have implemented all these methods except the last one, compareTo, since I don't know how to manipulate with these wildcards.
Here is my code : help here - pastebin
class ComplexNumber <T extends Number,U extends Number> implements Comparable<ComplexNumber> {
private T real;
private U imaginary;
public ComplexNumber(T real, U imaginary) {
super();
this.real = real;
this.imaginary = imaginary;
}
public T getR() {
return real;
}
public U getI() {
return imaginary;
}
public double modul(){
return Math.sqrt(Math.pow(real.doubleValue(),2)+ Math.pow(imaginary.doubleValue(), 2));
}
public int compareTo(ComplexNumber<?, ?> o){
//HELP HERE
}
}
Anybody help with this method?
Since you only have to compare the modulus, you don't care about the type parameters.
#Override
public int compareTo(ComplexNumber<?, ?> o) {
return Double.valueOf(modul()).compareTo(Double.valueOf(o.modul()));
}
However, you have to add the wildcards in the type declaration as well
class ComplexNumber <T extends Number,U extends Number> implements Comparable<ComplexNumber<?, ?>>
Try it:
class ComplexNumber<T extends Number, U extends Number> implements Comparable<ComplexNumber<T, U>> {
#Override
public int compareTo(ComplexNumber<T, U> o) {
return 0;
}
}
It seems that both of your arguments can handle class that extends java.lang.Number and all the concrete classes have compare to one of the way you may want to do is as follows :
#Override
public int compareTo(ComplexNumber o) {
if (o.real instanceof BigInteger && this.real instanceof BigInteger) {
int realCompValue = ((BigInteger)(o.real)).compareTo((BigInteger)(this.real));
if (realCompValue == 0 ) {
return compareImaginaryVal(o.imaginary, this.imaginary);
} else {
return realCompValue;
}
} else if (o.real instanceof BigDecimal && this.real instanceof BigDecimal) {
int realCompValue = ((BigDecimal)(o.real)).compareTo((BigDecimal)(this.real));
if (realCompValue == 0 ) {
return compareImaginaryVal(o.imaginary, this.imaginary);
} else {
return realCompValue;
}
}
// After checking all the Number extended class...
else {
// Throw exception.
}
}
private int compareImaginaryVal(Number imaginary2, U imaginary3) {
// TODO Auto-generated method stub
return 0;
}

java generic addition

I'm attempting implement the add method mentioned in the Generic sparse matrix addition question
class Matrix<T extends Number>
{
private T add(T left, T right)
{
if (left instanceof Integer)
{
return new Integer(((Integer)left).intValue() + ((Integer)right).intValue());
}
}
The compiler errors with found java.lang.Integer Required T at the line where I return a new Integer. I'm not sure what I'm missing since T extends Number and Integer is a subclass of Number.
The compiler doesn't let you do this because T might be some other class, such as Double.
You know that T is Integer from the instanceof check, but the compiler doesn't.
Java's type system is simply not capable of expressing this. Here is a work around.
Create an interface Numeric that provides the numeric operations you are interested in, and write its implementations for the data types you are interested in.
interface Numeric<N> {
public N add(N n1, N n2);
public N subtract(N n1, N n2);
// etc.
}
class IntNumeric extends Numeric<Integer> {
public static final Numeric<Integer> INSTANCE = new IntNumeric();
private IntNumeric() {
}
public Integer add(Integer a, Integer b) {
return a + b;
}
public Integer subtract(Integer a, Integer b) {
return a - b;
}
// etc.
}
And rewrite your Matrix class constructor to accept this implementation.
class Matrix<N> {
private final Numeric<N> num;
private final List<List<N>> contents;
public Matrix(Numeric<N> num) {
this.num = num;
this.contents = /* Initialization code */;
}
public Matrix<N> add(Matrix<N> that) {
Matrix<N> out = new Matrix<N>(num);
for( ... ) {
for( ... ) {
out.contents.get(i).set(j,
num.add(
this.contents.get(i).get(j),
that.contents.get(i).get(j),
)
);
}
}
return out;
}
}
// Use site
Matrix<Integer> m = new Matrix<Integer>(IntNumeric.INSTANCE);
Hope that helps.
"I'm not sure what I'm missing since T extends Number and Integer is a subclass of Number."
This statement is false. In general if you have:
public class B extends A {
}
public class C extends A {
}
it does not mean that B can be cast to C. So writing something like:
public <T extends A> T method(T arg) {
return (B)arg;
}
and you calling it with B b = (B)method(C); is obviously wrong.
package generics;
public class Box<T> {
public T j,k;
int l;
float f;
#SuppressWarnings("unchecked")
public void add(T j,T k) {
this.j = j;
this.k=k;
if(j.toString().contains("."))
{
this.f=Float.parseFloat(j.toString())+Float.parseFloat(k.toString());
} else{
this.l=Integer.parseInt(j.toString())+Integer.parseInt(k.toString());
}
}
public int getInt() {
return l;
}
public float getFloat() {
return f;
}
public static void main(String[] args) {
Box<Integer> integerBox = new Box<Integer>();
Box<Float> floatBox = new Box<Float>();
integerBox.add(new Integer(10),new Integer(20));
floatBox.add(new Float(2.2),new Float(3.3));
System.out.printf("Integer Value :%d\n\n", integerBox.getInt());
System.out.printf("float Value :%f\n", floatBox.getFloat());
}
}

Categories

Resources