Implementing compareTo using wildcard generics - java

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

Related

generic class that implements comparable

I have been assigned the problem: Write a generic WeightedElement<E,W> class which stores an
element of type E and a weight of type W. It should implement Comparable relying on W's compareTo(). You should enforce that W itself is comparable.
So far I have made the class and implemented comparable but am encountering issue when making the compareTo() method for W. I have:
public class WeightedElement<E, W extends Comparable<W>> {
public E element;
public W weight;
public WeightedElement() {
element = this.element;
weight = this.weight;
}
public int compareTo(W data) {
if (this.weight == data.weight) {
return 0;
} else if (this.weight < data.weight) {
return 1;
} else {
return 1;
}
}
}
I am encountering the issue that when I compare the weights, the weight for data is not found. Also are there any other methods I have to create to properly have a class that implements comparable on one of the variables? Thank you for any help
You have the generics right, but just like WeightedElement itself, you have to call compareTo on the weights -- you can't use < or == to do comparisons.
public class WeightedElement<E, W extends Comparable<W>> implements Comparable<WeightedElement<E, W>> {
private final E element;
private final W weight;
public WeightedElement(E element, W weight) {
this.element = element;
this.weight = Objects.requireNonNull(weight, "'weight' should not be null");
}
#Override
public int compareTo(WeightedElement<E, W> other) {
return other == null ? 1 : weight.compareTo(other.weight);
}
}

Inheritance hierarchy for number system classes

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.

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

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

Cast Abstract to Concrete type without knowing the implementation

Consider the code:
Number n=new Integer(20);
cast(n) //return's n casted to Integer
<T> T cast(Number num)//to cast from abstract to concrete implemenation
{
// Get which implementation of Number this by calling num.getClass()
//cast to Specific implementation and return
}
Is the above code possible ? Can casting be done when I'm not sure what the implementation is ? If so how should the above function be implemented ?
Casting is impacting on the type of the object not on the object.
so your method
cast(n)
will do nothing
Due to erasure, T will be compiled to Object and the result will be an (Object) cast anyway.
(I've seen a similar question here on SO with a more elaborate explanation. Can't find it now though.)
This compiles however. I can't see how it would be useful though, but perhaps you can :)
class Main {
public static void main(String[] args) {
Number n = new Integer(20);
Integer i = cast(n); //return's n casted to Integer
}
static <T> T cast(Number num) {
return (T) num;
}
}
The best option is to do this:
<T extends Number> T cast(Number num) {
return (T) num;
}
Or, better approach, it's a bit dirty but you get the point....
/**
* #author The Elite Gentleman
*
*/
public class Test {
/**
*
*/
public Test() {
// TODO Auto-generated constructor stub
Number n = new Integer(20);
Double t = cast(n, Double.class);
System.out.println(t);
}
#SuppressWarnings("unchecked")
public <T extends Number> T cast(Number num, Class<T> clazz) {
if (num instanceof Integer) {
return specificCast(num.intValue(), clazz);
}
// if (num instanceof Double) {
// return specificCast(num.doubleValue(), clazz);
// }
return (T) num;
}
#SuppressWarnings("unchecked")
private <T extends Number> T specificCast(int value, Class<T> clazz) {
if (clazz != null) {
if (clazz == Float.class) {
return (T)Float.valueOf((float)value);
}
if (clazz == Double.class) {
return (T)Double.valueOf((double)value);
}
if (clazz == Long.class) {
return (T)Long.valueOf((long)value);
}
if (clazz == Short.class) {
return (T)Short.valueOf((short)value);
}
if (clazz == Integer.class) {
return (T)Integer.valueOf(value);
}
}
return null;
}
public static void main(String[] args) {
new Test();
}
}
Output...
20.0

Categories

Resources