Java toString Method (objects) - java

class Position {
private double x,y;
private int id;
public String toString(Position a){
String words ="(" + a.x + "," +a.y + ")";
return words;
So I'm getting a memory address returned here. What am I doing wrong? I want to get the actual values of x and y that were set using setters. I also have getters, and I tried instead of putting a.x putting getX(), but that still give me another memory address. What am I doing wrong?

Try:
public String toString(){
The code you have is adding a new method, instead of overriding the existing parameterless toString method of Object. That means the old method is still the one being called, and it gives the output you're seeing.

You're not actually overriding toString; rather, you're overloading it by defining a method with the same name but which expects different arguments. You don't pass a Position to toString; it should refer the current instance.

As a complement to other posts, why do you think you need to pass Position's reference to the method toString(), anyway. After all, the method exist in the same class, Position. You can use the variable/properties directly without any reference like this.
public String toString(){
return "(" + x + "," + y + ")";
}
Or in case you like to specifically have a reference then you can do it like this,
public String toString(){
return "(" + this.x + "," + this.y + ")";
}
I made the method one liner after refactoring.
In case you are interested in knowing which version folks like more, please refer to here, when to use this. And here is the tutorial/explanation on how overriding works in Java.

Since it is a homework, I would ask you step through a debugger. Your method is not called even though you expect it do so. ( toString() and toString(Someobject ) are different.

Related

Is there a way to create an anonymous Object array with data and an overridden toString method?

Object[] x = new Object[] {"Skye", "Eyks", 123}
{
#Override
public String toString()
{
return this[0] + " " + this[1] + " (" + this[3] + ")";
}
};
So that x.toString() would return "Skye Eyks (123)".
NetBeans says it expects a semi-colon and that it's an Illegal start of expression.
Why I want to use an anonymous array class is to display the data in a combo-box and get all the other data in my array once the user submits the form.
No, this is impossible.
Your code paste strongly suggests an alternate solution:
Java is a statically and nominally typed object oriented language. Java is very very bad at dealing with data stored in a heterogenerous, untyped, and unnamed 'grabbag of unknown mystery' - which is what Object[] is.
This is presumably what you're looking for:
public class Word {
final String word;
final int score;
public String getWord() {
return word;
}
public String getReverse() {
// ...
}
public int getScore() {
return score;
}
#Override public String toString() {
return word + " " + getReverse() + " (" + score + ")";
}
}
Now, it's got structure (the compiler now knows, and your editor can now help you out): a Word has properties like getWord() and getReverse(); getReverse() is far more informative than [1]. You now have a place to add documentation if you want (how do you intend to 'document' new Object[]?), and you have room for flexibility (for example, getReverse() could be calculated on the fly instead of passed in at construction).
You can now write methods that take a Word. This:
public void printWord(Word word) {}
is almost self evident. Compare to this:
/**
* This function requires that you pass a 3-sized object array, with:
* The first argument must be a string - this is the word to print.
* The second argument must be that string, reversed. It will be printed in light grey for a mirror effect.
* The third argument must be a boxed integer, this will be printed in the lower right corner as page number
*/
public void printWord(Object[] o) {}
That's a ton of documentation, and this is considerably worse: This documentation is unstructured - whereas with an actual class, the names of methods can carry most of this meaning and lets you document each fragment independently. You can also farm out any checks and other code to the right place, instead of ending up in a scenario where the code to check if the input array is proper needs to be called in many places, and you need to go out of your way to document, for everything, what happens if you pass invalid input (vs. having to do that only once, in Word's constructors).
If you end up with an Object[] due to external forces, such as, say, the arguments passed along to your main function, then the general aim is to convert that to a proper object once, and as soon as possible, so that your java code remains as uninfected by this heterogenous, untyped and unnamed mysterymeat as possible.
NB: Yes, that means you need to make a ton of classes, for everything you can think of, so you end up with clean code. Lombok's #Value can help with this, as can java15's records.

String Concatenation - valueOf or not

So I just perused for a while, all the different questions on here about .valueOf with strings, but they all seem to be about conversions. Comparing .valueOf to just + "".
I want to know if it is worth it or at all necessary to use .valueOf if it is a concatenation.
Example:
LOGGER.info("Final Score: " + String.valueOf(Math.round(finalScore * 100)) + "%");
VS
LOGGER.info("Final Score: " + Math.round(finalScore * 100) + "%");
It seems as though using String.valueOf is unnecessary if you have actual strings to go along with it. I understand it may be better to use .valueOf if you were just converting it and intended to use an empty string.
When we concatenate strings, the compiler actually translates it to StringBuffer.append().
The underlying implementations for StringBuffer.append(int) and String.valueOf(int) both eventually end up calling Integer.getChars(int,int,char[]) except that in case of String.valueOf(), there is a call to Integer.toString(int) first.
To conclude, for the given scenario, directly concatenating would be the way to go. But if you intend to be conscious about memory, then use string-builder to concatenate values first and then log it.
The source code for String#valueOf(Object) looks like this:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
So the only difference between valueOf and toString is that valueOf is null-safe. So let's see which one is used if we concatenate a string and an object.
Object foo = null;
System.out.println("foo " + foo); //foo null, no exception thrown
System.out.println("foo " + String.valueOf(foo)); //foo null, no exception thrown
So it looks like there's no difference whatsoever between concatenation and using valueOf in this context.
you are correct. When you are combining strings and other datatypes, the valueOf is not necessary. For only an int, I think the valueOf works, but anecdotally, the 2nd example is a lot more common
#Test
public void testStringValueOF(){
int num = 123;
// this works...
String test = String.valueOf(num);
// but this is more common
String test2 = "" + num;
}

Clarification about the toString method within an ADT class

This is the modified toString function within the Complex ADT class that i'm trying to implement (My doubt is only regarding this function so I havent included the private variables declared before and the other functions) :
class ComplexCart implements Complex{
public String toString(){
if(image == 0) return (real + "");
}
}
Why can't we write the following?
if(imag == 0) return(real);
Why do we need to add the additional "" ?
since the return type is String, and real is integer type. alternatively you can use real.toString()
Since real is int type where as toString() method expects String to return.So you need add "";
+ is String concatenation operator here.
public String toString(){
if(image == 0) return (real + "");
}
In the above code if real is not of type String it's compile time error.
if it is of type String.No errorrs occures.
To make real as string you are writing real + "".
Then , Immediate question is Then how it's working with + "" ??
Here the Docs of String
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java.
As a side note:
concatenating with String is a bad idea.There are some identical and better ways to do it.
1)Integer.toString(intval);
2)String.valueOf(intval);
It's because you have to return a String from toString(), and presumably real is not a String. real + "" performs string concatenation (converting real to a String and concatenating it with the empty string; see JLS ยง15.18.1) and results in a String, which is why you can validly return it.
Note that you should consider using something like Integer.toString(real) over real + "" (see Integer.toString()).

How to print the address of an object if you have redefined toString method

I'm a newbie to Java. Now I'm studying equals and == and redefinition of equals and toString.
I would like to use both the toString method that I have redefied and the default method that is inherited from the Object class.
I failed to use that super modificator to reach that method.
This is for educational purposes only. What I would like to get is more clear if you will have a look at the comments in my code.
Could you help me here?
My code is:
public class EqualTest{
public static void main(String[] args){
Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
//System.out.super.println(alice1);
Employee alice2 = alice1;
//System.out.super.println(alice2);
Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
//System.out.super.println(alice3);
System.out.println("alice1==alice2: " + (alice1==alice2));
System.out.println("alice1 == alice3: " + (alice1==alice3));
System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));
}
}
class Employee{
...
public String toString(){
return getClass().getName() + "[name = " + name +
", salary=" + salary + ", hireDay=" + hireDay + "]";
}
}
Strictly speaking, you can't print the address of an object in pure Java. The number that looks like an object address in the String produced by Object.toString() is the object's "identity hashcode". It may or may not be related to the object's current address:
The specs do not say how the identity hashcode number is calculated. It is deliberately left unspecified.
Since the number is a hashcode, it cannot change. So even though it is (typically) related to an object address, that will be the object's address at the time when the hashcode was first accessed. This could be different to its current address, and it will be different if the GC has moved the object since the first time the object's identity hashcode was observed.
On a 64bit JVM (with a large enough heap size / not using compressed oops) addresses won't fit into an identity hashcode number which is returned as an int.
Anyhow, the way to get this number is to call System.identityHashCode(obj).
If you really want an object's current address, you can get it using JNI and a native method (and some abstraction breaking), or by using methods in the Unsafe class (see How can I get the memory location of a object in java?). But beware that both of these approaches are non-portable. Also, the object addresses that they give you are liable to "break" when the GC moves the object which renders them problematic for many (probably most) potential use-cases.
For the doubters, this is what the Java 10 javadocs say on the "hashcode != address" point:
"(The hashCode may or may not be implemented as some function of an object's memory address at some point in time.)"
Emphasis added. Indeed, with recent JVMs, the default algorithm does NOT derive the hashCode from a memory address at all. It has been that way since at least Java 7.
You can confirm this by including -XX:+PrintFlagsFinal in the command line options to find out what the hashcode flag defaults to, and then looking at the OpenJDK source code to see what it means. (The code is in the "vm/runtime/synchronizer.cpp" file in some versions, but YMMV.)
If you want to achieve sort-of default toString() behavior, you can make use of System.identityHashCode() method. Default toString() will then look like this:
public String toString(Object o) {
return o.getClass().getName() + "#" +
Integer.toHexString(System.identityHashCode(o));
}
You can call super() method to execute the corresponding superclass method.
class Employee{
...
public String toString(){
String s = super.toString();
return getClass().getName() + "[name = " + name +
", salary=" + salary + ", hireDay=" + hireDay + "]" + s;
}
toString() in Object class is as follows
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
Here is an in-depth answer about overriding equals and hashcode
What issues should be considered when overriding equals and hashCode in Java?
The key point being
The relation between the two methods is:
Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
You may create another method inside your Employee class to use super toString method.
See example:
public class Employee {
public String toString() {
return "MyToStringMethod";
}
public String superToString() {
return super.toString();
}
public static void main(String[] args) {
Employee b = new Employee();
System.out.println(b);
System.out.println(b.superToString());
}
}
or combine both in one method:
public class Employee {
public String toString() {
return super.toString() + " MyToStringMethod";
}
public static void main(String[] args) {
Employee b = new Employee();
System.out.println(b);
}
}

Pass by Reference and recursion

I have the following recursive function prototype:
public void calcSim(Type<String> fort, Integer metric)
Integer metric = 0;
calcSim(fort, metric);
System.out.println("metric: " + metric);
}
I want to print the value of metric as shown above. However it is always zero. Now, when I print at the end of the function, I do get a valid number.
How do I pass by reference or get the equivalent functionality like in C++
What all can I do with regards to my parameter passing? (by value, by reference, etc...)
There is no such thing as pass by reference in Java, sorry :(
Your options are either to give the method a return value, or use a mutable wrapper and set the value as you go. Using AtmoicInteger cause it is in JDK, making your own that doesn't worry about threadsafety would of course be mildly faster.
AtomicInteger metric = new AtomicInteger(0);
calcSim(fort, metric);
System.out.println("metric: " + metric.get());
Then inside the calcSim set it with metric.set(int i);
To get the behavior of pass by reference, you can create a wrapper class, and set the value in that class, eg:
class MyWrapper {
int value;
}
Then you can pass a MyWrapper to your method and change the value, for example like this:
public void calcSim(Type<String> fort, MyWrapper metric)
metric.value++;
System.out.println("metric: " + metric.value);
calcSim(fort, metric);
}
Integer is wrapper class. Wrapper classes are immutable. So, what you are expecting can't be achieved with Integer type.
You may create mutable wrapper class around primitive and update the object to achieve what you want.
Two big issues:
You are redefining metric with the same name in your method as well. How is program printing anything. It should complain at compilation time.
No defined exit criteria. Does you program(method) stops?
I think you wanted something as (pseudo code as I don't know what are you doing):
public void calcSim(Type<String> fort, Integer metric)
if(condtion){
//print or return
}else{
//modify fort or metric so that it exits
calcSim(fort, metric); //call this with modified value
System.out.println("metric: " + metric.value);
}
}

Categories

Resources