Generics - Zahlentypen

Ok,
hat zwar etwas gedauert, da ich auch privat einiges zu tun hatte, aber hier sind nun meine (vorläufig) fertigen Point und Ray Klassen. Die Pointklasse deckt dabei sowohl Vector als auch Point ab. Vielleicht hat der ein oder andere ja Interesse daran :D.
Noch mal vielen Dank an alle die mir hier geholfen haben :slight_smile: !

MfG,
~Oneric

Enum

package oneric.util.maths;

import java.nio.ByteBuffer;

public enum EnumPrimitiveType {
	
	BYTE(Byte.BYTES),
	SHORT(Short.BYTES),
	CHAR(Character.BYTES),
	INT(Integer.BYTES),
	FLOAT(Float.BYTES),
	DOUBLE(Double.BYTES),
	LONG(Long.BYTES);
	
	
	
	public final int byteSize;
	
	private EnumPrimitiveType(int size)
	{
		byteSize = size;
	}
	
	
	/** 
	 * Puts the Primitive into a ByteBuffer, starting at the given index.
	 * Longs are expected in the format {@link Double.longBitsToDouble()} 
	 * and will be reformatted as Long with {@link Double.doubleToRawLongBits()}
	 * 
	 * @param buffer The buffer to put the data into
	 * @param primitive The primitive who is going to be put into the buffer
	 * @param index The index where the data will be put into
	 * */
	public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index)
	{
		//Start with int, float, double, because they are the most used ones
		switch(this)
		{
		case INT:
			buffer.putInt(index, (int)primitive);
			break;
		case FLOAT:
			buffer.putFloat(index, (float)primitive);
			break;
		case DOUBLE:
			buffer.putDouble(index, primitive);
			break;
		case BYTE:
			buffer.put(index, (byte)primitive);
			break;
		case SHORT:
			buffer.putShort(index, (short)primitive);
			break;
		case CHAR:
			buffer.putChar(index, (char)primitive);
			break;
		case LONG:
			buffer.putLong(index, Double.doubleToRawLongBits(primitive));
			break;
		}
	}
	
	
	/** 
	 * Puts the Primitive into a ByteBuffer at the current position.
	 * Longs are expected in the format {@link Double.longBitsToDouble()} 
	 * and will be reformatted as Long with {@link Double.doubleToRawLongBits()}
	 * 
	 * @param buffer The buffer to put the data into
	 * @param primitive The primitive who is going to be put into the buffer
	 * */
	public void putIntoByteBuffer(ByteBuffer buffer, double primitive)
	{
		//Start with int, float, double, because they are the most used ones
		switch(this)
		{
		case INT:
			buffer.putInt((int)primitive);
			break;
		case FLOAT:
			buffer.putFloat((float)primitive);
			break;
		case DOUBLE:
			buffer.putDouble(primitive);
			break;
		case BYTE:
			buffer.put((byte)primitive);
			break;
		case SHORT:
			buffer.putShort((short)primitive);
			break;
		case CHAR:
			buffer.putChar((char)primitive);
			break;
		case LONG:
			buffer.putLong(Double.doubleToRawLongBits(primitive));
			break;
		}
	}
	
	
	/** 
	 * Gets a Primitive from a ByteBuffer, start reading at the given index.
	 * Longs will be returned in the format {@link Double.longBitsToDouble()} 
	 * and can be reformatted to a long with {@link Double.doubleToRawLongBits()}
	 * 
	 * @param buffer The buffer to read from
	 * @param index The index where the reading will start
	 *
	 * @return The primitive value at the given position, if the enum is invalid it returns NaN, if this happens you should report it to the author
	 * 
	 * @throws IndexOutOfBoundsException If index is negative or not smaller than the buffer's limit, minus three 
	 * */
	public double getFromByteBuffer(ByteBuffer buffer, int index)
	{
		//Start with int, float, double, because they are the most used ones
		switch(this)
		{
		case INT:
			return buffer.getInt(index);
			
		case FLOAT:
			return buffer.getFloat(index);
			
		case DOUBLE:
			return buffer.getDouble(index);
			
		case BYTE:
			return buffer.get(index);
			
		case SHORT:
			return buffer.getShort(index);
			
		case CHAR:
			return buffer.getChar(index);
			
		case LONG:
			return Double.longBitsToDouble(buffer.getLong(index));
		
		default:
			//TODO Log here
			return Double.NaN;
			//throw new InvalidObjectException("The given enum is unknown");
				
			
		}
	}
	
	
	/** 
	 * Gets a Primitive from a ByteBuffer, start reading at the current buffer's position
	 * Longs will be returned in the format {@link Double.longBitsToDouble()} 
	 * and can be reformatted to a long with {@link Double.doubleToRawLongBits()}
	 * 
	 * @param buffer The buffer to read from
	 * 
	 * @return The primitive value at the current position, if the enum is invalid it returns NaN, if this happens you should report it to the author
	 * 
	 * @throws BufferUnderflowException If there are fewer than the needed amount of bytes remaining in this buffer  
	 * */
	public double getFromByteBuffer(ByteBuffer buffer)
	{
		//Start with int, float, double, because they are the most used ones
		switch(this)
		{
		case INT:
			return buffer.getInt();
			
		case FLOAT:
			return buffer.getFloat();
			
		case DOUBLE:
			return buffer.getDouble();
			
		case BYTE:
			return buffer.get();
			
		case SHORT:
			return buffer.getShort();
			
		case CHAR:
			return buffer.getChar();
			
		case LONG:
			return Double.longBitsToDouble(buffer.getLong());
		
		default:
			//TODO Log here
			return Double.NaN;
			//throw new InvalidObjectException("The given enum is unknown");
				
			
		}
	}
	
	
	
	////////////// STATIC METHOD ///////////////
	
	public static EnumPrimitiveType getHighestPrecision(EnumPrimitiveType... list)
	{
		EnumPrimitiveType res = BYTE;
		for(EnumPrimitiveType p : list)
		{
			if(res.byteSize < p.byteSize)
				res = p;
			else if(res.byteSize == p.byteSize)
				/*TODO*/;
		}
		
		return res;	
	}

}

Point

package oneric.util.maths;

import java.nio.ByteBuffer;

public class Point3 {
	
	private ByteBuffer data;
	private final EnumPrimitiveType primitive;

	public Point3(EnumPrimitiveType type) {
		this.primitive = type;
		this.data = ByteBuffer.allocate(3 * type.byteSize);
		this.setDefault();
	}
	
	public Point3(Point3 p) {
		this.primitive = p.getPrimitiveType();
		this.data = ByteBuffer.allocate(3 * primitive.byteSize);
		
		this.setX(p.getX());
		this.setY(p.getY());
		this.setZ(p.getZ());
	}
	
	public Point3(EnumPrimitiveType type, double x, double y, double z) {
		this.primitive = type;
		this.data = ByteBuffer.allocate(3 * type.byteSize);
		this.setX(x);
		this.setY(y);
		this.setZ(z);
	}

	/** 
	 * Sets the Coordinates to (1 | 1 | 1)
	 * */
	private void setDefault() {
		for(int i = 0; i < 3; i++) {
			this.primitive.putIntoByteBuffer(data, 1);
		}
	}
	
	/////////////////////////////
	
	/** 
	 * @returns The primitive type of this Point
	 * */
	public EnumPrimitiveType getPrimitiveType() {
		return this.primitive;
	}
	
	/** 
	 * Returns the x value of this point as double
	 * May lose data if this is not a Double typed Point3  
	 * */
	public double getXDouble() {
		if (primitive == EnumPrimitiveType.DOUBLE)
			return this.data.getDouble(0);
		return this.getX();
	}

	/** 
	 * Returns the x value of this point as float
	 * May lose data if this is not a float typed Point3  
	 * */
	public float getXFloat() {
		if (primitive == EnumPrimitiveType.FLOAT)
			return this.data.getFloat(0);
		return (float) this.getX();
	}
	
	/** 
	 * Returns the x value of this point as int
	 * May lose data if this is not a integer typed Point3  
	 * */
	public int getXInt() {
		if (primitive == EnumPrimitiveType.INT)
			return this.data.getInt(0);
		return (int) this.getX();
	}
	
	///////////////////
	
	/** 
	 * Returns the y value of this point as double
	 * May lose data if this is not a Double typed Point3  
	 * */
	public double getYDouble() {
		if (primitive == EnumPrimitiveType.DOUBLE)
			return this.data.getDouble(this.primitive.byteSize);
		return this.getY();
	}

	/** 
	 * Returns the Y value of this point as float
	 * May lose data if this is not a float typed Point3  
	 * */
	public float getYFloat() {
		if (primitive == EnumPrimitiveType.FLOAT)
			return this.data.getFloat(this.primitive.byteSize);
		return (float) this.getY();
	}
	
	/** 
	 * Returns the Y value of this point as int
	 * May lose data if this is not a integer typed Point3  
	 * */
	public int getYInt() {
		if (primitive == EnumPrimitiveType.INT)
			return this.data.getInt(this.primitive.byteSize);
		return (int) this.getY();
	}
	///////////////////////////////
	
	
	/** 
	 * Returns the Z value of this point as double
	 * MaZ lose data if this is not a Double tZped Point3  
	 * */
	public double getZDouble() {
		if (primitive == EnumPrimitiveType.DOUBLE)
			return this.data.getDouble(2*this.primitive.byteSize);
		return this.getZ();
	}

	/** 
	 * Returns the Z value of this point as float
	 * MaZ lose data if this is not a float tZped Point3  
	 * */
	public float getZFloat() {
		if (primitive == EnumPrimitiveType.FLOAT)
			return this.data.getFloat(2*this.primitive.byteSize);
		return (float) this.getZ();
	}
	
	/** 
	 * Returns the Z value of this point as int
	 * MaZ lose data if this is not a integer tZped Point3  
	 * */
	public int getZInt() {
		if (primitive == EnumPrimitiveType.INT)
			return this.data.getInt(2*this.primitive.byteSize);
		return (int) this.getZ();
	}
	
	
	////////////////////////
	/** 
	 * Returns the x value of this point as double
	 * Longs are returned as {@link Double.longBitsToDouble}  
	 * */
	public double getX() { 
		return this.primitive.getFromByteBuffer(data, 0); // x --> pos 0
	}
	
	/** 
	 * Returns the y value of this point as double
	 * Longs are returned as {@link Double.longBitsToDouble}  
	 * */
	public double getY() { 
		return this.primitive.getFromByteBuffer(data, this.primitive.byteSize); // x --> pos byteSize
	}
	
	/** 
	 * Returns the z value of this point as double
	 * Longs are returned as {@link Double.longBitsToDouble}  
	 * */
	public double getZ() { 
		return this.primitive.getFromByteBuffer(data, 2*this.primitive.byteSize); // x --> pos 2*byteSize
	}

	/////////////////////////////
	// SET /////////////////////
	////////////////////////////
	
	
	/** 
	 * Sets the x value of this point as double
	 * May lose data if this is not a Double typed Point3  
	 * */
	public void setXDouble(double value) {
		if (primitive == EnumPrimitiveType.DOUBLE)
			this.data.putDouble(0, value);
		else
			this.setX(value);
	}

	/** 
	 * Sets the x value of this point as float
	 * May lose data if this is not a float typed Point3  
	 * */
	public void setXFloat(float value) {
		if (primitive == EnumPrimitiveType.FLOAT)
			this.data.putFloat(0, value);
		else
			this.setX(value);
	}
	
	/** 
	 * Sets the x value of this point as int
	 * May lose data if this is not a integer typed Point3  
	 * */
	public void setXInt(int value) {
		if (primitive == EnumPrimitiveType.INT)
			this.data.putInt(0, value);
		else
			this.setX(value);
	}
	
	///////////////////
	
	/** 
	 * Sets the Y value of this point as double
	 * May lose data if this is not a Double typed Point3  
	 * */
	public void setYDouble(double value) {
		if (primitive == EnumPrimitiveType.DOUBLE)
			this.data.putDouble(0, value);
		else
			this.setY(value);
	}

	/** 
	 * Sets the Y value of this point as float
	 * May lose data if this is not a float typed Point3  
	 * */
	public void setYFloat(float value) {
		if (primitive == EnumPrimitiveType.FLOAT)
			this.data.putFloat(0, value);
		else
			this.setY(value);
	}
	
	/** 
	 * Sets the Y value of this point as int
	 * May lose data if this is not a integer typed Point3  
	 * */
	public void setYInt(int value) {
		if (primitive == EnumPrimitiveType.INT)
			this.data.putInt(0, value);
		else
			this.setY(value);
	}
	///////////////////////////////
	
	
	/** 
	 * Sets the Z value of this point as double
	 * May lose data if this is not a Double typed Point3  
	 * */
	public void setZDouble(double value) {
		if (primitive == EnumPrimitiveType.DOUBLE)
			this.data.putDouble(0, value);
		else
			this.setZ(value);
	}

	/** 
	 * Sets the Z value of this point as float
	 * May lose data if this is not a float typed Point3  
	 * */
	public void setZFloat(float value) {
		if (primitive == EnumPrimitiveType.FLOAT)
			this.data.putFloat(0, value);
		else
			this.setZ(value);
	}
	
	/** 
	 * Sets the Z value of this point as int
	 * May lose data if this is not a integer typed Point3  
	 * */
	public void setZInt(int value) {
		if (primitive == EnumPrimitiveType.INT)
			this.data.putInt(0, value);
		else
			this.setZ(value);
	}
	
	
	////////////////////////
	/** 
	 * Sets the x value of this point as double
	 * Longs are expected as {@link Double.longBitsToDouble}  
	 * */
	public void setX(double value) { 
		this.primitive.putIntoByteBuffer(data, value, 0); // x --> pos 0
	}
	
	/** 
	 * Sets the y value of this point as double
	 * Longs are expected as {@link Double.longBitsToDouble}  
	 * */
	public void setY(double value) { 
		this.primitive.putIntoByteBuffer(data, value, this.primitive.byteSize); // x --> pos byteSize
	}
	
	/** 
	 * Sets the z value of this point as double
	 * Longs are expected as {@link Double.longBitsToDouble}  
	 * */
	public void setZ(double value) { 
		this.primitive.putIntoByteBuffer(data, value, 2*this.primitive.byteSize); // x --> pos 2*byteSize
	}
	
	
	
	
	
	
	/** 
	 * @returns The length of this Vector
	 * */
	public double length()
	{
		return Math.sqrt(this.lengthSquared());
	}
	
	/** 
	 * @returns The squared length of this Vector
	 * */
	public double lengthSquared()
	{
		return MathHelper.square(getX()) + MathHelper.square(getY()) + MathHelper.square(getZ());
	}
	
	/** 
	 * Calculates the distance between two points
	 * 
	 * @returns The distance between the points
	 * */
	public double distance(Point3 point) {
		return Math.sqrt(this.distanceSquared(point));
	}
	
	/** 
	 * Calculates the squared distance between two points
	 * 
	 * @returns The squared distance between the points
	 * */
	public double distanceSquared(Point3 point)
	{
		return MathHelper.square(this.getX() - point.getX()) + MathHelper.square(this.getX() - point.getX()) + MathHelper.square(this.getX() - point.getX()); 
	}
	
	/** 
	 * Adds the given point to this Point
	 * 
	 * @param point The point to add to this one
	 * */
	public void add(Point3 point)
	{
		this.setX(this.getX() + point.getX());
		this.setY(this.getY() + point.getY());
		this.setZ(this.getZ() + point.getZ());
	}
	
	
	/** 
	 * Adds the given values to this Point
	 * 
	 * @param x The value to add to the x-Coordinate of this Point
	 * @param y The value to add to the y-Coordinate of this Point
	 * @param z The value to add to the z-Coordinate of this Point
	 * */
	public void add(double x, double y, double z)
	{
		this.setX(this.getX() + x);
		this.setY(this.getY() + y);
		this.setZ(this.getZ() + z);
	}
	
	/** 
	 * Subtracts the given point to this Point
	 * 
	 * @param point The point to subtract to this one
	 * */
	public void sub(Point3 point)
	{
		this.setX(this.getX() - point.getX());
		this.setY(this.getY() - point.getY());
		this.setZ(this.getZ() - point.getZ());
	}
	
	/** 
	 * Subtracts the given values to this Point
	 * 
	 * @param x The value to subtract from the x-Coordinate of this Point
	 * @param y The value to subtract from the y-Coordinate of this Point
	 * @param z The value to subtract from the z-Coordinate of this Point
	 * */
	public void sub(double x, double y, double z)
	{
		this.setX(this.getX() - x);
		this.setY(this.getY() - y);
		this.setZ(this.getZ() - z);
	}
	
	/**
	 * Rotates the Point3 (can either be a point or vector) by rot degrees around an arbitrary axis defined by xA, yA and zA
	 * The arbitary Axis should be normalised, but if it isn't it will be done
	 * 
	 * @param rot The Rotation in degrees
	 * @param xA The x-Component of the arbitrary axis
	 * @param yA The y-Component of the arbitrary axis
	 * @param zA The z-Component of the arbitrary axis
	 * */
	public void rotate(double rot, double xA, double yA, double zA)
	{
		
		if(VectorHelper.lengthSquared(xA, yA, zA) != 1)
		{
			double[] d = VectorHelper.normalise(xA, yA, zA);
			xA = d[0];
			yA = d[1];
			zA = d[2];
		}
		
		double x = this.getX();
		double y = this.getY();
		double z = this.getZ();
		
		double sinA = Math.sin(MathHelper.degreesToRadians(rot));
		double cosA = Math.cos(MathHelper.degreesToRadians(rot));
		double OneMinCosA = 1-cosA; 
		
				
		this.setX( 	x * (xA*xA*OneMinCosA + cosA) + 
					y * (xA*yA*OneMinCosA - zA*sinA) + 
					z * (xA*zA*OneMinCosA + yA*sinA ) 	
				);
		
		this.setY( 	x * (xA*yA*OneMinCosA + zA*sinA) +
					y * (yA*yA*OneMinCosA + cosA) +
					z * (yA*zA*OneMinCosA - xA*sinA)
				);
		this.setZ( 	x * (xA*zA*OneMinCosA - yA*sinA) +
					y * (yA*zA*OneMinCosA + xA*sinA) +
					z * (zA*zA*OneMinCosA + cosA)
				);
	}
	
	/** 
	 * This method performs a unit scale
	 * @param scale The scale factor 
	 * */
	public void scale(double scale)
	{
		this.setX(getX()*scale);
		this.setY(getY()*scale);
		this.setZ(getZ()*scale);
	}
	
	/** 
	 * This method performs a non-unit scale
	 * 
	 * @param scaleX The x scale factor
	 * @param scaleY The y scale factor
	 * @param scaleZ The z scale factor 
	 * */
	public void scale(double scaleX, double scaleY, double scaleZ)
	{
		this.setX(getX()*scaleX);
		this.setY(getY()*scaleY);
		this.setZ(getZ()*scaleZ);
	}
	
	/** 
	 * Normalises the Vector
	 * */
	public void normalise()
	{
		double l = this.lengthSquared();
		if(l == 1) return;
		
		l = Math.sqrt(l);
		
		this.setX(getX()/l);
		this.setY(getY()/l);
		this.setZ(getZ()/l);
	}
	
	
	
	/*public static transform(Matrix4f mat){}
	
	public static transform(Matrix3f mat){}*/
	
	
	
	/////// STATIC METHODS /////////////////////
	
	/** 
	 * Adds the two given point and stores the result in the third point. If it's null a new point is created
	 * 
	 * @param pointLeft The point standing left on the calculation
	 * @param pointRight The point standing right on the calculation
	 * @param store The point to store the result, if equals null a new one is created using the more precise type
	 * */
	public static Point3 add(Point3 pointLeft, Point3 pointRight, Point3 store)
	{
		if(store == null) 
			store = new Point3(EnumPrimitiveType.getHighestPrecision(pointLeft.getPrimitiveType(), pointRight.getPrimitiveType()), pointLeft.getX() + pointRight.getX(), pointLeft.getY() + pointRight.getY(), pointLeft.getZ() + pointRight.getZ());
		else{
			store.setX(pointLeft.getX() + pointRight.getX());
			store.setY(pointLeft.getY() + pointRight.getY());
			store.setZ(pointLeft.getZ() + pointRight.getZ());
		}
		
		return store;
	}
	
	
	

}

Ray

package oneric.util.maths;

public class Ray3 {
	
	private Point3 origin;
	private Point3 direction; // Point as Vector
	
	public Ray3(Point3 origin, Point3 direction)
	{
		this.origin = origin;
		this.direction = direction;
	}
	
	/**
	 * Rotates this Ray3 by "angle" degrees around an arbitrary axis defined by x, y and z
	 * 
	 * @param angle The Rotation in degrees
	 * @param x The x-Component of the arbitrary axis
	 * @param y The y-Component of the arbitrary axis
	 * @param z The z-Component of the arbitrary axis
	 * */
	public void rotate(double angle, double x, double y, double z)
	{
		this.rotateDirection(angle, x, y, z);
		origin.rotate(angle, x, y, z);
	}
	
	/**
	 * Rotates this Ray3s direction by "angle" degrees around an arbitrary axis defined by x, y and z
	 * 
	 * @param angle The Rotation in degrees
	 * @param x The x-Component of the arbitrary axis
	 * @param y The y-Component of the arbitrary axis
	 * @param z The z-Component of the arbitrary axis
	 * */
	public void rotateDirection(double angle, double x, double y, double z)
	{
		direction.rotate(angle, x, y, z);
	}
	
	public void translate(double x, double y, double z)
	{
		origin.add(x, y, z);
	}
	
	/** 
	 * This method performs a unit scale
	 * @param scale The scale factor 
	 * */
	public void scale(double scale)
	{
		direction.scale(scale);
	}
	
	/** 
	 * This method performs a non-unit scale
	 * 
	 * @param scaleX The x scale factor
	 * @param scaleY The y scale factor
	 * @param scaleZ The z scale factor 
	 * */
	public void scale(double scaleX, double scaleY, double scaleZ)
	{
		direction.scale(scaleX, scaleY, scaleZ);
	}
	
	/** 
	 *@returns The End of this Ray 
	 * */
	public Point3 getEndPoint()
	{
		return Point3.add(origin, direction, null);
	}
	
	/** 
	 *@returns The Start of this Ray 
	 * */
	public Point3 getStartPoint()
	{
		return origin;
	}
	
	/** 
	 *@returns The direction of this Ray 
	 * */
	public Point3 getDirection()
	{
		return direction;
	}
	

}

Also ich denke, die putInto- und getFromBuffer-Methoden, werde ich mal abschauen. Da spart man anscheinend unheimlich an switch-Anweisungen.

Hmm. Im Enum kann man Nutzen davon ziehen, dass man auch Methoden überschreiben darf. Damit wird das dann auch typsicher, man spart sich das switch und auch den default case. Man kann auch keinen Fall mehr vergessen bei einer Erweiterung hinzuzufügen, weil die abstrakte Methode ansonsten nicht überschrieben ist. Und eine Handvoll Zeilen spart man sich auch (ist aber auch ein bisschen geschummelt, ich hab die @Override weggelassen):


    BYTE(Byte.BYTES) {
        public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index) {
            buffer.put(index, (byte) primitive);
        }

        public void putIntoByteBuffer(ByteBuffer buffer, double primitive) {
            buffer.put((byte) primitive);
        }

        public double getFromByteBuffer(ByteBuffer buffer, int index) {
            return buffer.get(index);
        }

        public double getFromByteBuffer(ByteBuffer buffer) {
            return buffer.get();
        }
    },
    SHORT(Short.BYTES) {
        public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index) {
            buffer.putShort(index, (short) primitive);
        }

        public void putIntoByteBuffer(ByteBuffer buffer, double primitive) {
            buffer.putShort((short) primitive);
        }

        public double getFromByteBuffer(ByteBuffer buffer, int index) {
            return buffer.getShort(index);
        }

        public double getFromByteBuffer(ByteBuffer buffer) {
            return buffer.getShort();
        }
    },
    CHAR(Character.BYTES) {
        public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index) {
            buffer.putChar(index, (char) primitive);
        }

        public void putIntoByteBuffer(ByteBuffer buffer, double primitive) {
            buffer.putChar((char) primitive);
        }

        public double getFromByteBuffer(ByteBuffer buffer, int index) {
            return buffer.getChar(index);
        }

        public double getFromByteBuffer(ByteBuffer buffer) {
            return buffer.getChar();
        }
    },
    INT(Integer.BYTES) {
        public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index) {
            buffer.putInt(index, (int) primitive);
        }

        public void putIntoByteBuffer(ByteBuffer buffer, double primitive) {
            buffer.putInt((int) primitive);
        }

        public double getFromByteBuffer(ByteBuffer buffer, int index) {
            return buffer.getInt(index);
        }

        public double getFromByteBuffer(ByteBuffer buffer) {
            return buffer.getInt();
        }
    },
    FLOAT(Float.BYTES) {
        public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index) {
            buffer.putFloat(index, (float) primitive);
        }

        public void putIntoByteBuffer(ByteBuffer buffer, double primitive) {
            buffer.putFloat((float) primitive);
        }

        public double getFromByteBuffer(ByteBuffer buffer, int index) {
            return buffer.getFloat(index);
        }

        public double getFromByteBuffer(ByteBuffer buffer) {
            return buffer.getFloat();
        }
    },
    DOUBLE(Double.BYTES) {
        public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index) {
            buffer.putDouble(index, primitive);
        }

        public void putIntoByteBuffer(ByteBuffer buffer, double primitive) {
            buffer.putDouble(primitive);
        }

        public double getFromByteBuffer(ByteBuffer buffer, int index) {
            return buffer.getDouble(index);
        }

        public double getFromByteBuffer(ByteBuffer buffer) {
            return buffer.getDouble();
        }
    },
    LONG(Long.BYTES) {
        public void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index) {
            buffer.putLong(index, Double.doubleToRawLongBits(primitive));
        }

        public void putIntoByteBuffer(ByteBuffer buffer, double primitive) {
            buffer.putLong(Double.doubleToRawLongBits(primitive));
        }

        public double getFromByteBuffer(ByteBuffer buffer, int index) {
            return Double.longBitsToDouble(buffer.getLong(index));
        }

        public double getFromByteBuffer(ByteBuffer buffer) {
            return Double.longBitsToDouble(buffer.getLong());
        }
    };


    public final int byteSize;

    private EnumPrimitiveType(int size) {
        byteSize = size;
    }

    /**
     * Puts the Primitive into a ByteBuffer, starting at the given index.
     * Longs are expected in the format {@link Double.longBitsToDouble()}
     * and will be reformatted as Long with {@link Double.doubleToRawLongBits()}
     *
     * @param buffer    The buffer to put the data into
     * @param primitive The primitive who is going to be put into the buffer
     * @param index     The index where the data will be put into
     */
    public abstract void putIntoByteBuffer(ByteBuffer buffer, double primitive, int index);

    /**
     * Puts the Primitive into a ByteBuffer at the current position.
     * Longs are expected in the format {@link Double.longBitsToDouble()}
     * and will be reformatted as Long with {@link Double.doubleToRawLongBits()}
     *
     * @param buffer    The buffer to put the data into
     * @param primitive The primitive who is going to be put into the buffer
     */
    public abstract void putIntoByteBuffer(ByteBuffer buffer, double primitive);

    /**
     * Gets a Primitive from a ByteBuffer, start reading at the given index.
     * Longs will be returned in the format {@link Double.longBitsToDouble()}
     * and can be reformatted to a long with {@link Double.doubleToRawLongBits()}
     *
     * @param buffer The buffer to read from
     * @param index  The index where the reading will start
     * @return The primitive value at the given position, if the enum is invalid it returns NaN, if this happens you should report it to the author
     * @throws IndexOutOfBoundsException If index is negative or not smaller than the buffer's limit, minus three
     */
    public abstract double getFromByteBuffer(ByteBuffer buffer, int index);

    /**
     * Gets a Primitive from a ByteBuffer, start reading at the current buffer's position
     * Longs will be returned in the format {@link Double.longBitsToDouble()}
     * and can be reformatted to a long with {@link Double.doubleToRawLongBits()}
     *
     * @param buffer The buffer to read from
     * @return The primitive value at the current position, if the enum is invalid it returns NaN, if this happens you should report it to the author
     * @throws BufferUnderflowException If there are fewer than the needed amount of bytes remaining in this buffer
     */
    public abstract double getFromByteBuffer(ByteBuffer buffer);

    ////////////// STATIC METHOD ///////////////

    public static EnumPrimitiveType getHighestPrecision(EnumPrimitiveType... list) {
        EnumPrimitiveType res = BYTE;
        for (EnumPrimitiveType p : list) {
            if (res.byteSize < p.byteSize)
                res = p;
            else if (res.byteSize == p.byteSize)
                /*TODO*/ ;
        }

        return res;
    }
}```

[QUOTE=cmrudolph]Hmm. Im Enum kann man Nutzen davon ziehen, dass man auch Methoden überschreiben darf. Damit wird das dann auch typsicher, man spart sich das switch und auch den default case. Man kann auch keinen Fall mehr vergessen bei einer Erweiterung hinzuzufügen, weil die abstrakte Methode ansonsten nicht überschrieben ist. Und eine Handvoll Zeilen spart man sich auch (ist aber auch ein bisschen geschummelt, ich hab die @Override weggelassen):[/QUOTE]Genauso habe ich es grad’ umgesetzt (inkl. aller @Override ;)). Hat keine 20 Minuten gedauert, wie ihr seht. Sagt also nicht, es würde sich nicht lohnen. :lol: