I want to make a two-dimensional vector that is holding two numeric values.
As usual vectors (even of different numerical type) should e.g. be addable.
In C++ you can just do something like:
template<typename T>
class vector2d{
T x{0};
T y{0};
public:
template<typename U> vector2d& operator+=(const vector2d<U>& vec){
x += vec.x;
y += vec.y;
return *this;
}
...
template<typename U>
friend class vector2d;
};
But when I try to achieve this in Java I am coming across some problems.
Here is what I tried to do:
class vector2d<T extends Number>{
private T x;
private T y;
public <U extends Number> vector2d add(vector2d<U> vec){
x += vec.x;
y += vec.y;
return this;
}
...
}
But this does not work. It would if i would use Integer or Float or whatever directly (because of Autoboxing). But this seems not to be the case when you just use the Number class directly. As I think there is no other interface that would satisfy the requirements, I am kind of stuck here.
So my question is if there are ways to make this work in Java.
One of possibilities to achieve this, is use BigDecimal class:
class vector2d{
private BigDecimal x;
private BigDecimal y;
public void add(vector2d vec){
x = x.add(vec.x);
y = y.add(vec.y);
}
...
}
But it can reduce performance of your code, as its operations aren't very fast.
You can also keep Number class and use doubleValue always:
class vector2d{
private Number x;
private Number y;
...
public void add(vector2d vec){
x = x.doubleValue() + vec.x.doubleValue();
y = y.doubleValue() + vec.y.doubleValue();
}
}
this will allow use any types of numbers:
vector2d v1 = new vector2d(1, 2.3);
vector2d v2 = new vector2d(1.3, 2);
v1.add(v2);
UPD: As #Jesper has mentioned, instead of Number just double type can be used, which will eliminate need of .doubleValue() invocation. So you have various way to do it.
Related
So I have a field called optionType and I want it to be able to take on 4 different integer values corresponding to certain options. For example optionType = 0 means the user wants to handle something a certain way, optionType = 1 means another way, etc.
But numbers by themselves are meaningless so I wanted to define constants instead in the class.
public class MyClass {
public static final int OPTION_TYPE_DO_THIS = 0;
public static final int OPTION_TYPE_DO_THAT = 1;
public static final int OPTION_TYPE_DO_SOMETHING_ELSE = 2;
public static final int OPTION_TYPE_DO_COOL_THING = 3;
private int optionType;
....
Is it considered normal to define all the constants out like that or is it better to use an enum like
public enum OPTION_TYPE {DO_THIS, DO_THAT, DO_SOMETHING_ELSE, DO_COOL_THING};
Or am I supposed to be using Enum instead somehow?
The key point is more on "how will that information be used at runtime". You see, if you starting thinking about writing code such as
switch(someEnum) {
case DO_THIS: ...
case DO_THAT:
... then you are already going into the wrong direction!
The point is: very often think that enums (or their even-more-low-level numeric constant cousins) are a good way to express such designs.
But that actually leads to quite some problems. Very often, the better, "more OO" way of thing is to use some abstract base class with specific subclasses; in other words: polymorphism!
Edit: just to make that more clear ... a "single" switch over an enum isn't really a problem. But far too often, people end up with many many places in code where they switch over their enums. And all of those places might need updates when you create additional enum constants. A coworker of mine calls that the "enum trap".
Take a look at this question and answer,
Even though it is written in the C# context, the conclusion states that:
Enums are great for lightweight state information.
Static class members would be able to support this multiple state without any extra functionality.
In java enums are more than just "enumerated names" as they are in other language (e.g. in C/C++).
My preferred use is to provide stateless behavior:
class Calculator {
enum Operation {
ADD{
double calculate(double a, double b){ return a + b;}
}
SUB{
double calculate(double a, double b){ return a - b;}
}
MUL{
double calculate(double a, double b){ return a * b;}
}
DIV{
double calculate(double a, double b){ return a / b;}
}
abstract double calculate(double a, double b);
}
Map<String,Operation> operations = new HashMap<>();
Calculator(){
operations.put("+",ADD);
operations.put("-",SUB);
operations.put("*",MUL);
operations.put("/",DIV);
}
public double calculate(double a, String operation, double b){
return operations.get(operation).calculate(a,b);
}
}
I am not primarily a Java programmer... I would like to find a corresponding Java syntax for class storing a function pointer (templatized) as a variable. The function pointer points to a function "outside" the class. The original code is in C++11:
#include <memory>
template <typename T>
using p_function = T(*)(T, T, T);
template <typename T>
class A
{
private:
int k;
p_function<T> pf;
public:
A() { pf = NULL; k = 0; }
A(p_function<T> pf_, int k_) { pf = pf_; k = k_; }
T getF(const T a1, const T a2, const T a3) const { return pf(a1, a2, a3); }
};
template <typename T>
T f1(T x, T y, T z) { return x + y + z; }
template <typename T>
T f2(T x, T y, T z) { return x - y - z; }
int main()
{
A<double> aa (f1<double>, 1.0);
double val= aa.getF(1.0, 2.0, 3.0);
}
Thinking about the problem, is it reasonable to use the interface?
public interface Function <T> {
T pf(T x, T y, T z);
}
or, is there any better way? Java is relatively rapidly develops, there might be "straighter" constructions than few years ago. There are several requirements which I am not able to join together. Could I ask for a short code sample in Java? Thank you very much for your help.
Use java 8. That uses "functional" interfaces (indeed) where an interface defines just one single function.
To not overuse the existing Function class, introduce your own name.
#FunctionalInterface
public interface TriFunction<T> {
T apply(T x, T y, T z);
}
Marking it with the FunctionalInterface annotation is a practice that prevents adding a second function and such.
class Foo {
public static Bar hop(Bar x, Bar y, Bar z) { ... }
}
TriFunction<Bar> pf = Foo::hop;
TriFunction<Integer> pg = (x, y, z) -> x + y + z;
Bar bara = pf.apply(a, b, c);
For primitive types better define own interfaces without generic parameter types. Above pg needs 3 times to unbox the wrapper objects, and one time to box it again to an object.
The package java.util.function contains many functional interfaces, like BinaryOperator and IntBinaryOperator.
In Java 8, you can use method references. More information here: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Basically, Java 8 gives interfaces with only one method the special property that they can be used (sort of) like function pointers. You can assign a lambda or a method reference to an object of such a type.
For example, somewhat related to your question:
public class HelloWorld {
public interface Function <T> {
T op(T x, T y);
}
public static class Functions {
static int add(int x, int y) { return x + y; }
static int sub(int x, int y) { return x - y; }
}
static Function<Integer> f1, f2; // <-- "function pointer"
public static void main(String []args) {
f1 = Functions::add; // <-- static method reference
f2 = Functions::sub; // <-- static method reference
System.out.println("Test: " + f1.op(1,2) + ", " + f2.op(1,2));
}
}
This code prints, as you'd expect:
Test: 3, -1
So that part of your question should work. However, the part where you define a generic addition is more problematic, because Java doesn't allow you to overload the operator '+'. So the following will not compile in Java:
T add(T x, T y) {
return x + y; // compile error -> no '+' defined for T
}
If you need T to be base types, you'll need to define your f1 and f2 for each base type you want to use. See also this question: Can I do arithmetic operations on the Number baseclass?
I am not sure if I get your question correctly, but have a look at this stackoverflow post.
There are several answers on how to implement function pointer in java.
EDIT
I am not experienced enough in C++ to provide a code sample.
EDIT 2
According to the post I mentioned above, you could try something like this:
public class WithFunction {
//Empty constructor, can be left out
public WithFunction () {...}
//The function you want to reference
public int myReferencedFunction () {...}
}
Then
public class MethodCaller {
public static Object call (Object theObject, String methodName) {
return theObject.getClass().getMethod(methodName).invoke(theObject);
//catch Exceptions
}
}
Then you can have it like
public static void main (String [] args) {
WithFunction obj1 = new WithFunction();
Object result = MethodCaller.call (obj1, "toString");
int result = (int) MethodCaller.call (obj1, "myReferencedFunction");
}
Notice:
You need to catch a lot of exceptions. Strong error handling needed..
If you use an interface, you can also implement it multiple times and should have the freedom you need
I need to write a vector class that accept any primitive number types in Java.
My vector class should only accept 2 components. Here is where I am having trouble.
I must write a function that adds two vectors and return a completely new vector.
If anyone knows a solution of allowing my vector class to accepts in primitive types and perform vector operations like Python, please point me in the right direction!
Something like in pseudocode:
AddVectors( V1, V2):
return new Vector( V1.getX + V2.getX, V1.getY + V2.getY)
Here is my some snipped code of my vector class:
public class Vector<T> {
private T x;
private T y;
public Vector(T x, T y){
this.x = x;
this.y = y;
}
public T getX(){
return x;
}
public T getY(){
return y;
}
}
I'm trying to compare two subclasses of Number inside a class with generics. In the code below, I'm trying to compare Number objects inside an instance of Datum.
How do I enforce that both parameters passed to the Datum constructor are of the same class, so that I can compare what I know to be comparable types - e.g. Float and Float, or Long and Long?
Float f1 = new Float(1.5);
Float f2 = new Float(2.5);
new Datum<Number>(f1, f2);
class Datum<T extends Number> {
T x;
T y;
Datum(T xNum, T yNum) {
x = xNum;
y = yNum;
if (x > y) {} // does not compile
}
}
You could restrict it to Comparable subclasses of Number:
class Datum<T extends Number & Comparable<? super T>> {
...
if (x.compareTo(y) > 0) { ... }
}
try
if (((Comparable)x).compareTo((Comparable)y)>0) {}
instead of
if (x > y) {}
Compare the outcome of Number#doubleValue() instead.
if (x.doubleValue() > y.doubleValue()) {}
You could always compare the double values
return ((Double)x.doubleValue()).compareTo(y.doubleValue());
If I have an enum object, is it considered a primitive or a reference?
It's a reference type. Java primitives are boolean byte short char int long float double.
You can get the enumeration constant's value by calling ordinal(), which is used by EnumSet and EnumMap iterator and "traverses the elements in their natural order (the order in which the enum constants are declared)"
You can even add your own members to the enum class, like this:
public enum Operation {
PLUS { double eval(double x, double y) { return x + y; } },
MINUS { double eval(double x, double y) { return x - y; } },
TIMES { double eval(double x, double y) { return x * y; } },
DIVIDE { double eval(double x, double y) { return x / y; } };
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}
//Elsewhere:
Operation op = Operation.PLUS;
double two = op.eval(1, 1);
The way enums work is actually not too different from how they were used before their introduction with Java 5:
public final class Suit {
public static final Suit CLUBS = new Suit();
public static final Suit DIAMONDS = new Suit();
public static final Suit HEARTS = new Suit();
public static final Suit SPADES = new Suit();
/**
* Prevent external instantiation.
*/
private Suit() {
// No implementation
}}
By instantiating the different suits on class loading it is ensured that these will be mutually exclusive and the private constructor ensures that no further instances will be created.
These would be comparable either through == or equals.
The Java 5 enum works pretty much the same way, but with some necessary features to support serialization etc.
I hope this background sheds some further light.
This article essentially shows you how enums are implemented, and as SLaks says, they are references.
Enums are reference types, in that they can have methods and can be executed from command line as well , if they have main method.
See following "Planet" example from Sun/Oracle
http://download.oracle.com/javase/tutorial/java/javaOO/enum.html