Consider the class
public class Complex
{
private double x;
private double y;
public Complex(double x , double y)
{
this.x = x;
this.y = y;
}
}
That represents a Complex number x + y*i , where i is the imaginary part.
I have the following main :
public static void main(String args[])
{
Complex p1 = new Complex(1 , 2); // ok
Complex p2 = new Complex(3 , 4); // ok
Complex p3 = p1 + p2; // Not ok , doesn't compile
}
The third line Complex p3 = p1 + p2; doesn't compile , since there is no operator overloading
in Java . It would have worked in C++ .
Any way around this (in Java) ?
Much appreciated
Operator overloading is not possible in Java. What you have to do instead is to implement methods for the operations.
BigDecimal is a good example of how this should be done in Java:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
note that BigDecimal is a immutable class, this is often a very good idea when you have classes that you in C++ would have operator overload like this for. It makes for cleaner code that is easy to maintain.
Not really no. Operator overloading is not supported in Java for various reasons. You can just provide an add method or something similar.
There is no operator overloading in Java as in C/C++ world, so the + operator is used, let's say only, for primitive numbers (byte, short, int, long, float and double) incremental operations.
This saying you should not complain or get surprised when you find a special case where the + operator is overloaded when it comes to the String Class.
String s1 = "Hello ";
String s2 = "World";
String helloWorld = s1 + s2;
Look at the last line in above code, it is totally legal and will result on a concatenated String and the compiler will never complain about it. Remember that this is the one and only exception.
So instead of overloading some operators, you can seamlessly implement a method that handles your addition stuff:
public class Complex
{
private double x;
private double y;
public Complex(double x , double y)
{
this.x = x;
this.y = y;
}
public Complex add (Complex c)
{
Complex sum = new Complex();
sum.x = this.x + c.x;
sum.y = this.y + c.y;
return sum;
}
}
public static void main(String args[])
{
Complex p1 = new Complex(1 , 2);
Complex p2 = new Complex(3 , 4);
Complex p3 = p2.add(p1);
}
Related
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
Suppose I have class with 2 fields: x and y, of type double. Is it possible to define 2 constructors so constructor1 will create object setting its x property to what parameter in constructor tell and y to default and constructor2 vice versa?
public class Test {
private int x;
private int y;
public Test(int x) {
this.x = x;
}
public Test(int y) {
this.y = y;
}
}
I'm trying something like that and I know that it wont work because of overloading rules
No, you can't do that. Typically you'd do something like:
private Test(int x, int y) {
this.x = x;
this.y = y;
}
public static Test fromX(int x) {
return new Test(x, 0);
}
public static Test fromY(int y) {
return new Test(0, y);
}
You might want to consider that pattern (public static factory methods which in turn call private constructors) even when you don't have overloading issues - it makes it clear what the meaning of the value you're passing is meant to be.
No, You cannot have two methods or constructors with the same signature. What you can do is have named static factories.
public class Test {
private int x;
private int y;
private Test(int x, int y) {
this.x = x;
this.y = y;
}
public static Test x(int x) { return new Test(x, 0); }
public static Test y(int y) { return new Test(0, y); }
}
Test x1 = Test.x(1);
Test y2 = Test.y(2);
No, x and y have identical types, so both constructors would have the same type signature and the method resolution is based on parameter type, not name; the compiler has no way of differentiation.
The compiler looks for "Test.Test(int)" regardless of what the name of the parameter is.
The language would need additional feature added, such as named parameters, to do what you want.
If Java ever gets a syntax like C# for property initialization, you'll be able to use that idiom, using a default no-args constructor.
Besides the alternatives of using explicit factory methods, you could pass in a HashMap for your parameters.
public Test(HashMap<string,int> args) {
if(args.containsKey("x"))
x = args.get("x");
if(args.containsKey("y"))
y = args.get("y");
}
But static factory methods are cleaner for most cases. If you need much more, you may need to consider why you need such an idiom in the first place, and revise your class design.
Hi im new to java i am unsure how to use class function in java . my teacher gave us the point2d class and wants us to use the function in there. there is a function call distanceTo
// return Euclidean distance between this point and that point
public double distanceTo(final Point2D that) {
final double dx = this.x - that.x;
final double dy = this.y - that.y;
return Math.sqrt(dx*dx + dy*dy);
}
i am not sure how am i suppose to implement this. this is my code
public static int calc(int amount)
{
for (int t = 0; t < amount; t++)
{
double current = 0;
double x = StdRandom.random();
double y = StdRandom.random();
Point2D p = new Point2D(x, y);
if ( current < distanceTo(Point2D p ) )
{
}
i tried to use distanceTo(p) and distanceTo(Poin2D) and nothing works.
Thanks in advance
As it is a class function, you need a reference to an instance of the class as well. In this case something like
Point2D b;
p.distanceTo(b); // Invoke distanceTo on b from the point of view of p
This is because your method needs 2 objects to be referenced. The invoking object p and the passed object b, in your function referred to as this and that respectively.
public static int calc(int amount) is static, and distanceTo is not.
For not being static, distanceTo requires an enclosing instance of an object, say: new Point2D().distanceTo(...).
You can then call distanceTo to you some Point2D you already have, say p2:
p2.distanceTo(p);
Or you can try turning distanceTo into a static method, that would receive two points as arguments:
public static double distanceTo(final Point2D one, final Point2D that) {
final double dx = one.x - that.x;
final double dy = one.y - that.y;
return Math.sqrt(dx*dx + dy*dy);
}
And call it using just:
distanceTo(p, p2);
PS.: as an alternative, maybe your solution is to turn calc non-static. You should try it, maybe.
To call a non static method of a class use the . operator.
To call distanceTo, use following syntax:
p.distanceTo(p);
if it was static, use class name with . operator
Point2D.distanceTo(p);
Once again, I'm looking for a way to bypass this array problem, how? Is there any way other than clone()?
I'm asking because fighting with clone(), protection and implemention stuff didn't work for me...
//assuming you have proper class and constructor (point(int x, int y))
/*
point 7POINTSARRAY[]=new point[7];
for(int i=0;i<7;i++)
{
7POINTSARRAY[i].x=i;
7POINTSARRAY[i].y=i;
}
//This won't work, so...
*/
point B = new point(0,0); // You need this.
for(int i=0;i<7;i++){
7POINTSARRAY[i]=B; // And this.
//But I want to read and assign value only,
// not establish a reference, so it can work How?
7POINTSARRAY[i].x=i;
7POINTSARRAY[i].y=i;
System.out.println(7POINTSARRAY[i].x);
}
System.out.println(7POINTSARRAY[1].x);
Though desired output is A[1].x=1, it's been owerwritten several times, and now A[1].x = 7.
You need to a create a new point for every element of the array if you want them all to reference different objects:
for(int i=0;i<7;i++)
{
point B = new point(0,0); // Put this *inside* the loop
7POINTSARRAY[i]=B; // Now B is a new instance of point
7POINTSARRAY[i].x=i;
7POINTSARRAY[i].y=i;
System.out.println(7POINTSARRAY[i].x);
}
System.out.println(7POINTSARRAY[1].x); // should now print 1
I haven't changed your code formatting but improving that will make the above clearer and easier to understand.
Sorry but Java works only with references for complex objects. You should use and implement clone() correctly this can't be the problem. clone() is well defined approach.
Typical clone for first level class looks like following
#Override
public Object clone() {
try {
A ans = (A) super.clone();
// do complex stuff
return ans;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
the line
A ans = (A) super.clone();
does default clone, which includes cloning object but not it's members. You should cascade clone for members. Since clone() is a member, it has access to protected members of the parent.
If your parent is Cloneable you should write
#Override
public Object clone() {
A ans = (A) super.clone();
// do complex stuff
return ans;
}
because parent can't throw exception.
For example, if you have point class looking like follows
class point {
public point(double x, double y) { this.x = x; this.y = y; }
public double x;
public double y;
}
then you should just fix it in the following way
class point implements Cloneable {
public point(double x, double y) { this.x = x; this.y = y; }
public double x;
public double y;
}
to make it cloneable.
Then you will be able to write
point a = new point(1,2);
point b = (point) a.clone();
and you will get 2 separate copies.
the problem is with the line
7POINTSARRAY[i]=B
which means that each object in 7POINTSARRAY refer (or points) to the same object B.
so when you do inside the loop
7POINTSARRAY[i].x=i;
7POINTSARRAY[i].y=i;
you actually always changing B.
You should do instead:
for(int i=0;i<7;i++){
7POINTSARRAY[i] = new point(i,i);
}
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