Define += for custom classes in Java [duplicate] - java

This question already has answers here:
Operator overloading in Java
(10 answers)
Closed 7 years ago.
I am making a simple 2D physics engine as my first attempt at making any kind of physics engine. Unfortunately for anybody who's a fan of teaching physics, this is not a physics related question. I simply wanted to know if there was a way to define something simple like addition for a custom class. For example, I have created a class named Vector2D. If I have a velocity vector, and an acceleration vector, it would be easiest to simply have the following code:
Vector2D velocity = new Vector2D(xAxisVelocity, yAxisVelocity);
Vector2D acceleration = new Vector2D(xAxisAcceleration, yAxisAcceleration);
void update() {
velocity += acceleration;
}
However, since velocity and acceleration are not primitive types, so I cannot just add them together. From what I know right now, I would have to add their components together like so:
velocity.x += acceleration.x
..and so on..
What I would like to know is: Is there a way to define addition for classes, similar to how toString() can be overridden?
Just to clear it up, it isn't that big of a deal for me to make a method for adding the two vectors together, I just want to know if overriding is possible.

No, there's no operator overloading in Java. It's a design choice and that's what we have to live with.
See Why doesn't Java offer operator overloading for more discussion.

No — there's no user-defined operator overloading in Java. (This is intentional; the language designers felt that this feature of C++ caused too many problems.)

Related

Create class with mathematic operations [duplicate]

This question already has answers here:
"+" operator for Java-classes
(5 answers)
Closed 5 years ago.
I'm trying to make a java library with a bunch of extra classes, and I was adding one for Imaginary numbers. Is there any way in java to make a custom class that is affected by mathematics operations
for example
Imaginary(10) * Imaginary(50) = "500i"
No, it is not possible to define custom arithmetic operators that overload default operators, but you can create methods like Imaginary.mutiply(Imaginary i).
You cannot overload operators in Java. See this previous answer to a similar question: https://stackoverflow.com/a/5883909/1701316
Your class will need to implement its operations as methods. If you'd like, since any character is allowed in a method name, you can name them with the typical operators, but they'll still need to be called with dot-notation: Imaginary(10).*(Imaginary(50))

Java - Add Support in a Class to Allow Multiplying

In programs such as Unity3D that have Vector2/Vector3's etc (I use C# coding in the program), you can multiply Unity's Vector objects by a float simply using the '*' operand and no explicit methods. Eg:
Vector2 oldVector = new Vector2(10f, 10f);
Vector2 newVector = oldVector * -2f
And then newVector would have the value (-20f, -20f).
As opposed to something using methods like:
Vector2 oldVector = new Vector2(10f, 10f);
Vector2 newVector = oldVector.multiply(-2f);
Basically how would you tell Java to handle this/implement it into your class? Is there even a way?
I realise this may just be convoluted and that it's likely significantly easier to just use methods, but I feel like it would be interesting to learn and maybe useful at a later stage.
Very simple: Java doesn't allow for operator overloading; which is the concept behind "hiding" a method call that way.
You see, in essence, that code is dealing with object/reference types in the end. So even when other languages allow you to write "*" instead of "multiply"; in the end, there is still a method that gets invoked.
Basically that was a decision made on purpose when Java was put in place. Many people disliked operator overloading (pointing at C++ where such things were often misused); so the argument was made that Java should not allow for it.
If your main concern is to use * instead of multiply; there are plenty of other languages that run on the JVM (Scala for example) that give you operator overloading (but to be honest: Scala doesn't have operator overloading, but it allows you to name your method "*").
Simply put: You can't.
Java does not support operand overloading. There are other languages that build on the JVM (groovy, kotlin and scala) that support it - but ultimately they're doing the same as your second example.
In detail: The Java Spec sheet does not account for any operator overloading (for example, here: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17)

I'm conditioned to avoid local variables - am I doing it right? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I've just realised that when I am programming in Java I avoid local variables like the plague, if I really have to I prefix a member with a lower case "L" and have a method that resets that object (if the object is mine, I usually have a private method called init or something that the constructor calls)
I've just realised that this is really ugly in so many ways. Am I doing it right?
C++ programmers will know exactly what I mean, locals that don't leave the function's scope are automatically destroyed for us (if it does leave the function scope, use a pointer, blah blah blah)
Pattern for when this happens
I've found that whenever I fit an adapter to a function parameter and interact with it through this adapter is when I use this.
I also tend tohave the adapter maintain a pool of any objects it uses (up to a certain number)
It also occurs when I want to use data-types that require "new" to initialise but only within the method.
The code is a part of some main loop usually, otherwise it wouldn't matter, obviously (it's not a one off thing)
GC Collection amount:
Amount (Mb): | 30| 60| 90| 120| 150| 180| 210| 240| 270| 300| 330| 360|
--------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
With pattern |## (14)
without |################################################################### (350)
The program was pushed through its unit tests the mean GC amount is shown. The standard deviation was less than 5 for both.
This feels like it is somehow related to the flywheel pattern...
There is no code for this because:
It can manifest itself in so many ways! If you have a ComplexNumber class for example, if you just create them as needed you will generate vast amounts of garbage, if you have any sort of vector or matrix classes, same thing.
Another area is anything involving some sort of graph which is carefully traversed to generate another structure, like a scene graph, critical path, even a stack representing the current directory.
Basically if you have "new" to assign to a local variable in a method that gets called a lot you will find this.
Sample used above
It came from a program I wrote to teach people about finite state automata and other state-machines (Markov Chains, so forth), I noticed crippling ram usage and decided to investigate.
Comparison with other languages
Obviously C++ doesn't have this problem. But nor does Python you'll be glad to know. Python's reference counting means (provided you haven't got any cricles) that the moment the method ends things are deleted, infact there is a meta-method for it and you can use it reliably as a destructor (provided you are disciplined enough not to leak it from the method)
I can't be the first to have this problem, looking at similar questions suggests that there is no solution, but I can't believe that this hasn't been encountered before!
About me
I'm coming from C++ and Python (love them both!) to Java, I am "experienced" in Java in that I can read/write stuff that works, it follows a nice design philosophy and such, but I tend to be very mindful of performance and resources. I'm suffering withdrawal from const, I was a total const whore.
How this is not pooling
Suppose you have a GroupElement class - that represents a member of an algebraic group, we'll use additive notation.
Suppose that g.add(h) returns a new element, if you do this MANY many times you have a lot of elements. if instead you have:
GroupElement f = new GroupElement(0); //identity
g.add(f,h);
where:
add's first argument is the place to put the result, we generate no garbage.
The people who don't follow the above
You should know what a complex number is? Suppose a complex number has a method called add that takes a complex number and returns a new complex number. If you do a=b.add(c); A LOT of times, you get A LOT minus 1 garbage complex numbers floating around.
If you have inplaceAdd(ComplexNumber target, ComplexNumber value) say where:
target.real = value.real+real;
target.im = value.im+im;
you create no garbage if you do: b.inplaceAdd(a,c) - which does the same as the above a=b.add(c)
BTW add could do this: return new ComplexNumber(real+value.real,im+value.im) - see what I mean now?
Implementation of example (seriously guys, how do you not get this!)
public class ComplexNumber {
private double real;
private double im;
public ComplexNumber(double r, double i) {
real = r;
im = i;
}
public ComplexNumber add(ComplexNumber value) {
return new ComplexNumber(real + value.real, im + value.im);
}
public void inplaceAdd(ComplexNumber target, ComplexNumber value) {
target.real = real + value.real;
target.im = im + value.im;
}
}
If you have a ComplexNumber class for example, if you just create them as needed you will generate vast amounts of garbage, if you have any sort of vector or matrix classes, same thing.
Keep in mind that garbage is free; the cost of garbage collection is determined by the non-garbage that has to be traversed. (I mean, the VM spec doesn't actually specify exactly how GC must be implemented, but that's how the major ones all work.) And this is intentional: obviously there's no technical reason that a Java implementation can't use reference-counting; it's just that it's not considered very robust/efficient/reliable/etc. (In C++ and Perl and Python, the reference-counting gives you the advantage of predictable destructors. Java doesn't offer that; instead, it offers finally blocks and try-with-resources.)

Why isn't .length() a method for arrays in Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java - Array’s length property
String.length() vs Array.length
I'm currently in my AP Computer Science class in high school and I came across this in my reading.
From what I understand, .length() is a method used for strings, but why isn't .length() a method when applied on arrays? I understand that they're different objects, but why didn't Java just make another method for finding the length of arrays?
I appreciate any response I get. Thanks!
Since arrays are fixed length defined at the time they are instantiated length is a public final field on the class. There is no need to make it a method since there is no calculation to be done at run time.
See this section of the Java Spec for details:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.7
Now, as for the design question of why they didn't provide an accessor method to obtain the value isn't specified. Perhaps this was done before any other convention was set and this is just a legacy thing. Only the language designers would know the "why" portion of their decision to do it this way.
Arrays are defined in the Java Language Specification #10.7. In particular:
The members of an array type are all of the following:
The public final field length, which contains the number of components of the array. length may be positive or zero.
[...]
I can't answer why this approach was chosen by the language designers.
Interestingly, it was already the case in the Oak specifications, which is the ancestor of Java.
I doubt that there's a good technical reason for this.
I suspect that this is one of those little inconsistencies that didn't get spotted early enough to get fixed without breaking a ton of code.

What is operator overloading and is it different from Polymorphism?

I program in Java and have been trying to understand exactly what operator overloading is. I'm still a bit puzzled.
An operator can take on different meanings depending on which class uses it? I've read that it is "Name Polymorphism".
Java apparently does not support it and there seems to be a lot of controversy around this. Should I worry about this?
As a last question, in an assignment the teacher has stated that the assignment uses operator overloading, he is a C++ programmer mainly but we are allowed to write the assignment in Java. since Java does not support overloading, is there something I should be wary of?
Operator overloading basically means to use the same operator for different data types. And get different but similar behaviour because of this.
Java indeed doesn't support this but any situation where something like this could be useful, you can easily work around it in Java.
The only overloaded operator in Java is the arithmetic + operator. When used with numbers (int, long, double etc.), it adds them, just as you would expect. When used with String objects, it concatenates them. For example:
String a = "This is ";
String b = " a String";
String c = a + b;
System.out.print (c);
This would print the following on the screen: This is a String.
This is the only situation in Java in which you can talk about operator overloading.
Regarding your assignment: if the requirement is to do something that involves operator overloading, you can't do this in Java. Ask your teacher exactly what language you are allowed to use for this particular assignment. You will most likely need to do it in C++.
PS: In case of Integer, Long, Double etc. objects, it would also work because of unboxing.
Java doesn't allow overloading operators. It uses a very limited kind of operator overloading though, since + does addition or concatenation depending on the context.
If your assignment asks you to implement something by overloading operators, you won't be able to do it in Java. Maybe you should ask the teacher why he allows Java for such an assignment.
If your assignment only asks you to use an overloaded operator, then having your program use + for concatenation and addition would fit the bill. But I would ask the teacher, because I doubt that it's what he expects.
Java apparently does not support it and there seems to be a lot of
controversy around this.
There is no controversy about this. Some people might disagree with the decision, but James Gosling and others decided from day one to leave operator overloading by class developers out of the language. It's not likely to change.
As pointed out by others here, they reserved the right for the JVM to overload operators on a limited basis. The point is that you can't do it when you're developing your own classes.
They did it because there were examples of C++ developers abusing the capability (e.g. overloading the dot operator.)
Should I worry about this?
No. Java won't explode. You just won't be able to do it for your classes. If you feel like you need to, you'll just have to write C++ or some other language.
As to your query about the difference between operator overloading and polymorphism. Polymorphism is a standard OOP concept where an instance of a class may exhibit different characteristics depending on the underlying type. For example in C++:
class Shape {
...
virtual void draw()=0;
}
class Circle :public Shape {
virtual void draw() {...draw a circle...}
}
class Square:public Shape {
virtual void draw() {...draw a square...}
}
..
Shape *s = new Circle();
s->draw(); // calls Circle::draw();
s=new Square(); // calls Square::draw();
Hence s is exhibiting polymorphism.
This is different from operator overloading but you already have been explained what that is in the other answers.
Can either use natural a != b (a is not equal to b) or a.Equals(b)
b.set(1, 0);
a = b;
b.set(2, 0);
assert( !a.Equals(b) );
But java has a limited set of operator overloading than other languages http://en.wikipedia.org/wiki/Operator_overloading

Categories

Resources