• Advertisement
Sign in to follow this  

[java] Another generics question

This topic is 4173 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I don't know if this is possible but I have this class to hold an X and Y value for a vector in two-dimensional space. I want it to be generic so I can have it be an Integer vector, or Double, or whatever kind of Number. Here is my class and my question.
public class Vector2D<T>{

	private T x;
	private T y;
	
	public Vector2D(){
		//Add something here to set default X and Y
	}
	
	public Vector2D(T x, T y){
		setX(x);
		setY(y);
	}

	public T getX(){
		return this.x;
	}
	
	public T getY(){
		return this.y;
	}
	
	public void setX(T x){
		this.x = x;
	}
	
	public void setY(T y){
		this.y = y;
	}
}

Is there anyway to have a no-arg constructor in this and have it set default variables? I have tried adding "this(0,0);" to call the other constructor but having that defeats generics. I don't want to always have to pass something in when I create a new vector. It's not like this is a big problem, it will only save me a couple keys strokes each time. Thanks for any suggestions.

Share this post


Link to post
Share on other sites
Advertisement
the only thing I can think of right now is this(null, null). However if you limit the Generic-Type to java.lang.Number, you could use any value of the implementing class.


public class Vector2D<T extends Number> {

..

public Vector2D() {
this(Integer.valueOf(0), Integer.valueOf(0));
}

..
}

Share this post


Link to post
Share on other sites
I do have another question. Is this ok to use generics like this? I mean everytime I want to use the X and Y it has to autobox. Will that make things go slower than to create a concrete class that only accepts int's or double's or any primitive number? I guess it wouldn't be too bad to create a seperate class for each primitive there isn't that many. I don't know.

Share this post


Link to post
Share on other sites
The Hotspot optimizer is really good (especially in server-mode), however it cannot optimize all.
For example it could optimize/repace the primitive double for every immutable Double, if and only if it is guaranteed that it cannot be null. Note however, it may not optimize even if it is possible, depending on the total application context.


Writing sperate classes for all primitive types means much more code, which increases the total number of bugs (e.g. copy & paste mistakes). Personally, I'm in favor of a single abstract class which provides all the functionality and derivates determing the data structure, e.g.:


public abstract class Vector2 {

// properties
public abstract double getX();
public abstract double getY();

public abstract void setX(double x);
public abstract void setY(double y);

// methods
public Vector2 setXY(float x, float y) {
setX(x);
setY(y);
return this;
}

public Vector2 negate(Vector2 source) {
return setXY(-source.getX(), -source.getY());
}

public Vector2 add(Vector2 left, Vector3 right) {
return setXY(left.getX() + right.getX(), left.getY() + right.getY()); // don't know why the 'plus' operator is not shown here :-(
}

// concrete class
public static class Float extends Vector2 {
// data structure
public float x,y;

// propterties implemetation
public double getX() { return x; }
..
public void setY(double y) { this.y = (float) y; }


// optional: modify return type
public Float add(Vector2 left, Vector2 right) {
return (Float) super.add(left, right);
}
}

// other concrete class
public static class DoubleArray extends Vector2 {
// data structure
public final double[] elems = new double[2];

// propterties implemetation
public double getX() { return elems[0]; }
..
public void setY(double y) { this. elems[1] = (float) y; }


// optional: modify return type
public DoubleArray negate(Vector2 source) {
return (DoubleArray) super.negate(source);
}
}
}



SUN's geometry approach is similiar, have a look at java.awt.geom.Point2D and its inner classes 'Float' and 'Double'.

Share this post


Link to post
Share on other sites
Quote:
Original post by CaptainJester
Auto-boxing is a compiler trick. You have less to do, but the same thing still happens behind the scenes.


Yep, just sintatic sugar. A few of the generics' use cases are also sintatic sugar. What I like the most about generics is that you can define such an interface:


public interface DataAccessObject < T extends BasicEntity > {

T load(Object uoi) throws Exception;

List < T > query(String sql, Map < String , Object > params) throws Exception;

// ...
}

public class AccountDao implements DataAccessObject < Account > {

// Legal Signature
Account load(Object uoi) throws Exception {}

// Legal Signature
List < Account > query(String sql, Map < String, Object > params) throws Exception {}

}



Which is, by the way, the approach used by the Collection framework itself, if I'm not mistaken.

Regarding the OP, though, I'd advice the use of inheritance: Vector2 <- Vector2f <- Vector2d, and so on.

Rodrigo

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement