Assignment Operator Overloading Java - java

Im having trouble figuring out how to implement the equivalent of overloading the assignment operator in C++ to Java. I know there is no such thing, but I need to simulate it. I've tried overriding the Clone() function, but no luck. Any ideas?
Below is my main
Queue p = new Queue();
Queue q = new Queue();
p.enqueue('a');
p.enqueue(9);
p.enqueue(10);
p.enqueue(310);
p.enqueue(8);
q = p;
System.out.print(p);
And here is the clone function
public void Clone(Queue other) throws Throwable
{
System.out.println("test\n");
if(this == other)
{
}
else
{
while(!isEmpty())
dequeue();
Node tmp = other.head;
while(tmp != null){
this.enqueue((T)tmp.element);
tmp = tmp.next;
}
}
}

Operator overloading is Not supported by Java.
Operator overloading violates one of the central tenets of the Java language design : transparency. It is against the language philosophy trying to overload an operator and should be avoided ...

Operator overloading cannot be done in Java. It requires support from the compiler to do just that. You can however create a preprocessor that understands java syntax and run it before building, that converts the call of your operator to an appropriate function but that is just overkill.
clone is not not related to operator overloading.

You're going to need to write an explicit copy constructor. In Java, everything's a pointer (or "reference" as they call them), so when you assign p to q, you're just saying that p and q point to the same object.
q = new Queue(p)
Is what you want, assuming you've implemented the appropriate constructor.
EDIT:
What you're proposing is just not possible with the syntax "q = p". If you want to "simulate" the assignment operator, then you're going to need to write a new method in Queue. For example, here's how Java programmers "simulate" overloading the addition operator:
a.add(b);
So in your case you'll need to write an "assign" method that takes a Queue, copies its data, and assigns these copies to the internal data of the other object.
q.assign(p);
public void assign(Queue other) {
this.primitive = other.primitive;
this.someObject = new SomeObject(other.someObject);
}
That's about as close as you're going to get.

There is no "equivalent" because you cannot overload the assignment operator in Java. You're attempting to imitate the behavior with the clone() method, but you've got it backwards. Without operator overloading, you have three options:
Write a function that mutates the invoking object to become a copy of the one passed in.
Write a function that makes a copy of the invoking object and returns it to something else that will store it.
Use a copy constructor.
1. Write a function that mutates the invoking object to become a copy of the one passed in.
Note that this is identical to the assignment operator overload, except it's named "copy" instead of "operator=".
If you want to do this:
foo A;
foo B;
A.copy(B); // A is now a copy of B.
In C++:
foo& copy(const foo& rhs)
{
if(&rhs != this)
{
this->m_someInt = rhs.m_someInt;
this->m_someBar = rhs.m_someBar;
}
return *this;
}
In Java:
foo copy(foo rhs)
{
this.m_someInt = rhs.m_someInt;
this.m_someBar.copy(rhs.m_someBar);
return this;
}
Note that in C++, assigning this->m_someBar to rhs.m_someBarcopies rhs.m_someBar by value, but in Java such an assignment would cause both foo objects to share the same Bar object. Therefore, a similar copying mechanism must be used on your subojects as well if you don't intend for them to be shared.
2. Write a function that makes a copy of the invoking object and returns it to something else that will store it.
If you want to do this:
foo A;
foo B;
A = B.clone(); // A is now a copy of B.
In C++:
foo clone() const // Ignoring the fact that this is unnecessary in C++ where assignments (and returns) are by-value anyway.
{
foo theCopy;
theCopy.m_someInt = this->m_someInt;
theCopy.m_someBar = this->m_someBar;
return theCopy;
}
In Java:
foo clone()
{
foo theCopy = new foo();
theCopy.m_someInt = this.m_someInt;
theCopy.m_someBar = this.m_someBar.clone();
return theCopy;
}
3. Use a copy constructor.
If you want to do this:
foo B;
foo A = new foo(B); // Java version
foo A(B); // C++ version
In C++:
foo(const foo& rhs)
:m_someInt(rhs.m_someInt), m_someBar(rhs.m_someBar)
{
}
// Or optionally:
foo(const foo& rhs) = default;
In Java:
foo(foo rhs)
{
m_someInt = rhs.m_someInt;
m_someBar = new Bar(rhs.m_someBar);
}
In conclusion, your issue is that you're trying to use clone() in the same way I use copy() above. The closest to an equivalent would be my copy method. My personal suggestion is to just use a copy constructor and call it a day.

If you're trying to override the clone method on Object, it needs to have the same signature (and capitalization). Your method signature is Clone(Queue).
It's not really clear how this relates to trying to simulate operator overloading though, or what operator you're trying to overload...

I'm from a C++ background so I know where you are coming from.
I think it is the clone method you are after. Don't forget to implement the Cloneable interface to tell 'Object' that this object is a cloneable object. See Effective Java (2nd Ed) item 11 for a thorough explanation.

Related

Pointer to pointer equivalent in java [duplicate]

This question already has answers here:
C++ Pointers to Pointers in Java
(5 answers)
Closed 7 years ago.
For last some day I am learning Java while I have some knowledge in C. Now I am trying to convert code written in C to a Java code. There I found a pointer to pointer (pptr)variable declaration like this -
int n;
int *ptr;
int **pptr;
n = 13;
ptr = &n;
pptr = &ptr;
As far as I know, in Java there is no pointer type variable. My question is there any way to represent pptr or anything equivalent of pptr in Java?
Let's look at some of the use cases for multiple indirection in C, and see how they apply to Java.
Use Case #1: you want a function or method to change the value of a pointer or reference parameter such that it points to a new object, and have that change reflected in the caller.
In C, that would look something like this:
void foo( T **p )
{
*p = new_value(); // update the thing p points to
}
void bar( void )
{
T *var; // for any type T
foo( &var ); // foo will set var to point somewhere else
}
var is a pointer to something, and we want the function foo to change var such that it points to something else. Since C passes all function arguments by value, if we want foo to update var, we must pass a pointer to var, giving us a pointer to pointer type in foo.
Java doesn't expose operations on pointer types (no unary & address-of or * indirection operators), so we can't do this directly. We'd have to wrap the reference we want to change in another reference type and pass that wrapper type to the method, and even then I'm not sure it would do the same thing as the C code above:
public class thing
{
// attributes
}
public class thingWrapper {
{
public thing t;
}
public void pointToNewThing( thingWrapper tw )
{
tw.t = newThing();
}
public void bar()
{
thing t = new thing();
...
thingWrapper tw = new thingWrapper();
tw.t = t;
pointToNewThing( tw );
t = tw.t;
...
}
Use Case #2: you want to allocate a multi-dimensional array in a piecemeal fashion, rather than in a single operation. This is useful if you want a "jagged" array (where the number of elements in each row isn't uniform) or if you're trying to allocate a lot of memory and don't have a single available block large enough for the whole thing.
In C, you'd do something like
T **arr = malloc( N * sizeof *arr );
if ( arr )
{
for ( int i = 0; i < N; i++ )
{
arr[i] = malloc( M * sizeof *arr[i] );
}
}
because C arrays are not "first class" objects, and cannot be manipulated and assigned directly, so you have to do this through pointers.
Java treats arrays completely differently such that you don't need to do the pointer-to-pointer dance at all:
T arr[][] = new arr[N];
for ( i = 0; i < N; i++ )
{
arr[i] = new arr[M];
}
I can't think of other use cases off the top of my head, but that should give you a flavor of how you'd translate the C concept to Java.
The short answer is yes. But first, a lesson in Java...
In Java, whenever you use objects, pointers are involved. If you have an object, the variable that "holds" that object is actually a pointer to that object. So if you are working with objects, you are already using pointers.
Now for primitive data types (e.g., integers, chars, or floating point numbers), Java does not use pointers, though. So if you want pointers for primitive data types, you need to use a wrapper class, such as Integer, which effectively promotes the value to an object.
Note, however, that the default wrapper classes are immutable.
If you want double-pointers (a pointer to a pointer) or triple pointers, you will need to create custom wrapper classes, like an ObjectWrapper class, that allows you to set up an arbitrary number of objects each pointing to (or "holding") the next.
What you can do is create an int array even with a size of 1 this way when you access the array it will always refer to the same place in memory as far as your programming is concerned.

Need explanation on this Java object initialization syntax

I'm a C\C++ programmer just starting on Java.
I came across this working Java snippet syntax that I understand what it does but I can't understand the logic of the syntax.
object x = new object
.SetContent(aaa)
.SetIcon(bbb)
.SetText(ccc);
I get that the equivalent C++ code is:
object* x = new object;
x->SetContent(aaa);
x->SetIcon(bbb);
x->SetText(ccc);
Can anyone explain to me the logic in the Java syntax?
Is this something like the Visual Basic's With Statement?
P.S.
Don't think it matters but the Java snippet is from an Android program.
Those chain calls are possible because each setter method returns a reference to this:
public object SetContent(final String input){
this.aaa = input;
return this;
}
This is method chaining in java, where each method returns the current instance so that you can invoke the next method on current returned object from that method.
It's method chaining, where each method invocation returns the object it was invoked on. It's very common to see in Java when creating an object with a Builder, e.g.
Foo foo = FooBuilder.builder()
.setBar("bar")
.setVolume(11)
.setAnswer(42)
.build();
Where each .set___() method returns the updated builder object, and the final build() call returns the actual Foo instance. It would be perfectly equivalent to do this:
FooBuilder builder = FooBuilder.builder();
builder = builder.setBar("bar");
builder = builder.setVolume(11);
builder = builder.setAnswer(42);
Foo foo = builder.build();
But IMO the first version is much more readable. I'm not much of a C++ guy but I think you can do the same thing there.
EDIT: Here's a real life example:
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableSet.Builder.html
This syntax is creating the 'x' object, you should know that objects are references in Java.
this syntax is equivalent to:
private object x = new object();
x.setContent(aaa);
x.setIcon(bbb);
x.setText(ccc);
so first it create the object and then it calls each method.
The instance of that Object is returned by each of the methods called,the next subsequent method uses that returned instance to operate further. This is internally done by returning this .
Example:
Object methodFirst(Object ob1)
{
ob1.doSomeOperations();
return this;
}
Object methodSecond(Object ob1)
{
ob1.doSomeOtherOperations();
return this;
}
the above methods can be called like :
Object newObject = oldObject.methodFirst().methodSecond();
A more comprehensive and deep explanation can be found here

Is it necessary to deep copy an array in java?

As far as I know and researched, arrays in Java are not objects but they're reference-types. My doubt is, when I want to return an array should I return a deep copy (like you would do with an object) with a clone() method for example, or can I return the variable countaining the array like it was a simple-type variable (ie. int or double) with a get method? For clarification porpuses, I will insert an example code to expose this situation:
public class List
{
// Instance Variables ----------
private int[] list1;
private int[] list2;
// Constructors ----------
public List()
{
list1 = new int[0]; list2 = new int[0];
}
public List(List x)
{
list1 = x.getList1();
list2 = x.getList2();
}
// Get methods
public int[] getList1()
{
return list1;
}
public int[] getList2()
{
return list2;
}
// Set methods
public void setList1(int size)
{
list1 = new int[size];
}
public void setList2(int size)
{
list2 = new int[size];
}
// Compare reference between an array and the instance variables
public boolean equals (int[] x)
{
if ( x == list1 || x == list2)
return true;
else
return false;
}
}
And now I have a TestClass the uses class List like this:
List listx = new List();
int[] listy = listx.getList2();
boolean test = listx.equals(listy);
System.out.printf("Result: " + test );
With this said, when I use the method equals to see if the two arrays share the same reference or adress, I get always the result true!! Am I breaking OOP basic principals with this? Will I loose control because listy is pointing to listx instance variable?
Well, I'm really confused with this and I don't know if this is right(being array a non-instantiable class) or If I should send some kind of deepcopy insted of shallow using a Clone method in other to ensure that all basic OOP principals are fulfilled, and with this principals I mean that the class method should be acessed only by the API and that the internal state(instance variables) can only be acessed by the class itself.
You are not breaking OOP principals. However, you are breaking principals of functional programming. Functional programming views leaking of access as losing of control.
Whether or not you want to practice functional programming is up to you, Java doesn't take a stance in that matter.
You may want to consider if it's important not to leak access for this particular class. If you find it important not to leak access then make this class immutable.
You can also guard the instance variables. In this scenario any possible changes to the variables must be handled by the instance class. However, the instance could be modified from separate contexts and result in loss of control. For this reason functional programming only allows immutable classes.
If you want the invoker of the method to be able to modify the original array, you don't need to do a copy. Otherwise, you do.
Check your implementation of equals(). It should be reflexive, symmetric, and transitive, which is not the case on yours.
It depends on your use-case if you want to deep copy or not. If your elements are immutable you normally not need to do a deep copy. If they can change, it depends if you want to see the changes in your receiver of the copy or not. Typically when you want a snapshot of the given data you will have to deep copy it. However keep in mind that Arrays are most of the time not a good argument or return type for APIs anyway.

Java - pass a pointer to an object to a function

What I want to achieve is something like this:
MyClass object = null;
doStuff(&object);
// `object` can now be non-null
What I'm currently doing is this, but I think there must be a better way to achieve this behavior in Java:
MyClassPointer pointer = new MyClassPointer(null);
// pointer.object is null
doStuff(pointer);
// pointer.object can now be non-null
If you really want doStuff to return two values: There may well be a better way to design this. Nevertheless, if you've decided that having doStuff return two values is really the best design, it can be done with a simple helper class:
static class MyClassAndBoolean {
public MyClass obj;
public boolean b;
public MyClassAndBoolean(MyClass obj, boolean b) { this.obj = obj; this.b = b; }
}
and then change doStuff's return type to MyClassAndBoolean. This is one of the very few cases where I think public fields in a class are OK. Since you're defining a simple class just to use as a function result, rather than representing a coherent concept, the usual concerns about defining accessors instead of exposing fields, etc., don't really apply. (P.S. I just guessed at boolean for the other type, but it can be anything, of course.)
Another workaround:
MyClass[] obj = new MyClass[1];
result = doStuff(obj);
Change doStuff's parameter type to MyClass[], and have it stuff the new object into parameter[0]. I do see this idiom used in some of the Java and Android library methods.
Why not simply:
MyClass object = doStuff();
which is much more intuitive IMHO. Otherwise you have to pass a reference (not pointer!) to a container object to your method, as you've identified. That's not a common pattern in the Java world.
As far as I know java language it is the only way to do that.
But you can simply implement method into your class. And in your method also there is possibility to return your object.
public MyObject myFunction(){
//do stufff...
return new MyObject();
}
MybObject object = myFucntion();
Or you can do it in your way. Also using Reflection you can invoke your method.
Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);
No, there is no better way since in Java you don't have pointers the way you have them in C++.
In Java references (much like pointers in C++) can't be directly accessed and are always passed by value. Thus you can't change the value of a reference within a method.
Use the Visitor pattern, your MyClass being what have to be 'visited' by dostuff

java why should equals method input parameter be Object

I'm going through a book on data structures. Currently I'm on graphs, and the below code is for the vertex part of the graph.
class Vertex<E>{
//bunch of methods
public boolean equals(Object o){
//some code
}
}
When I try to implement this equals method my compiler complains about not checking the type of the parameter and just allowing any object to be sent it. It also does seem a bit strange to me why that parameter shouldn't be a Vertex instead of an Object. Is there a reason why the author does this or is this some mistake or antiquated example?
#Override
public boolean equals(Object obj)
{
if (!(obj instanceof Vertex)) return false;
else return // blah blah
}
equals(Object) is the method defined in the root - Object. If you don't match the signature exactly, Object's version will be called when someone checks if two objects are equal. Not what you want.
You've probably seen other methods (like Comparator) where you can use the exact time. That's because those APIs were generic-ified with Java 5. Equals can't be because it is valid to call equals with two separate types. It should return false, but it is valid.
equals is a method inherited from Object, is defined to be flexible enough so that you can take any object and test if it is equal to any other object (as it rightfully should be able to do), so how could it be any other way?
Edit 1
Comment from jhlu87:
so is it not good form to write an equals method that has an input parameter of vertex?
You are welcome to create your own overload to any method, including equals, but doing so without changing the name could risk confusing many who would assume that your equals is the one that inherits from Object. If it were my code and I wanted a more specific equals method, I'd name it slightly different from just "equals" just to avoid confusion.
If your method doesn't take an argument of type Object, it isn't overriding the default version of equals but rather overloading it. When this happens, both versions exist and Java decides which one to use based on the variable type (not the actual object type) of the argument. Thus, this program:
public class Thing {
private int x;
public Thing(int x) {
this.x = x;
}
public boolean equals(Thing that) {
return this.x == that.x;
}
public static void main(String[] args) {
Thing a = new Thing(1);
Thing b = new Thing(1);
Object c = new Thing(1);
System.out.println(a.equals(b));
System.out.println(a.equals(c));
}
}
confusingly prints true for the first comparison (because b is of type Thing) and false for the second (because c is of type Object, even though it happens to contain a Thing).
It's because this method existed before generics, so for backward compatabitity it has to stay this way.
The standard workaround to impose type is:
return obj instanceof MyClass && <some condition>;
It is because the author is overriding equals. Equals is specified in java.lang.Object and is something that all classes inherrits from.
See the javadoc for java.lang.Object

Categories