Implementing an ArrayQueue in java need toString method - java

I have an ArrayQueue I am implementing for a class in the java language.
I am storing transaction objects in the ArrayQueue and I am getting stuck at the display() method (aka my own toString()). But it is only returning the reference.
Here is my method:
//display the elements in the current queue
public String display() {
String result = "";
if(isEmpty()) {
throw new EmptyQueueException("Queue is empty.");
} else {
for (int i = 0; i < count; i++) {
result += "[" + Q[(front + i) % capacity] + "] ";
}
}
return result;
}
Does this mean I need a toString() method for my object and call it like: System.out.println(arrayqueue.display().toString())?

If you override toString() for your ArrayQueue class, you can use:
System.out.println(arrayqueue);
But if you choose to call it display(), then yes you need this:
System.out.println(arrayqueue.display())
How else is the runtime environment supposed to know you wanted the string representation instead of the object reference?

Does this mean I need a toString() method for my object and call it like: System.out.println(arrayqueue.display().toString())?
No, since display() returns a String, arrayqueue.display() should be sufficient. Are you perhaps trying to print the toString() value of arrayqueue? Without overriding toString(), it will return the class name and hash code by default.

When you call the code
result += "[" + Q[(front + i) % capacity] + "] ";
You are calling the toString() method on the object contained at that location in the Q array. Default object toString() will print its memory location. If you have different data already declared by your object to print, such as object.getClass() to print the objects class name for instance you won't have to override toString() but instead call that method within the above code. Of course if you want a custom string that better represents your object than its memory location, its good to override toString() within that object's class.

Related

Why is it common practice to override the method toString() in java to print the instance variables of the class?

As I've been learning and even some IDEs have it embeded in it, to override the toString() method to print out all instance variables of the class.
The original toString() defined in object.java is defined as follows:
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
And it's common practice to override it as:
public String toString() {
return "className{" +"var1="+var1+", var2="+var2+'}';
}
Why don't we keep the original functionality of the toString() method and create a new method (with a different name) with this functionality?
We could. But how will other classes, that know absolutely nothing about your subclasses with your myNewToString method, know how to print a string that textually represents, in a concise but informative way, arbitrary subclasses?
The toString method was designed to be overridden to do that. Yes, it does have default behavior but it's not very useful. Its authors wanted you to override it. Overriding it to return what's commonly practiced is more useful, but you don't have to do that. A toString method for an EmailAddress class can return
public String toString() {
return "EmailAddress{localPart = " + localPart + ", domainName = " + domainName + "}";
}
but it's usually more useful to return something like
public String toString() {
return localPart + "#" + domainName;
}
The reason to override toString() is that toString() is called implicit by the compiler every time an object which is not of type String, is added to a string.
So if you have
MyObject o=new MyObject();
C="Hello " + o;
Then the compiler will call o.toString() in order to get a string it can concat to "Hello "
And I should note that it checks if o is null before calling toString() on o. And if o is null, it just generate the string "null"
Opinion: The toString() method should in general and in most cases only be used for debugging (Print/Log) and not as part of the normal program flow.

When testing toString, why is calling toString required?

I've overwritten the toString method of my class. When testing the toString method, I've been left wondering why calling toString is required.
Let me elaborate -
toString in class People:
#Override
public String toString() {
return ("This Object is called " + this.name + ". For a list of weekdays: " + this.dates);
}
Working Test Case:
#Test
Human Tom = new Human("Tom"); // constructor creates an ArrayList<weekDay> named dates
weekDay someDay = new weekDay("Thursday");
Tom.addDate(someDay); // adds someDay to the ArrayList
String result = ("This Object is called " + this.name + ". For a list of weekdays: " + Tom.dates);
assertEquals(Tom.toString(), result);
assertEquals(Tom.toString(), result) will work fine. But, when instead I try assertEquals(Tom, result) eclipse will write something like "expected x" but was "y". Yet, "y" has the exact same content as "x". Why is the need for explicitly calling toString()?
assertEquals(Tom.toString(), result);
This is equivalent to writing:
Tom.toString().equals(result);
Which compares the two String values. When you attempt to do this:
assertEquals(Tom, result);
This is equivalent to:
Tom.equals(result);
Which is now invoking the .equals() method on your People class (if you defined one), or Object#equals if you did not.
Eclipse is printing out the toString() method after your test fails to give you details of the error, which is unfortunately confusing in this scenario.

How do I get object and not address without using String/ toString?

I need to create my own String class called MyString without using default String class/vector API. I have to work on some required methods, and their return types are predetermined. I can add other methods as long as String is not used.
Expected use would be:
(at main) System.out.println(str.toLowerCase()) - returns lower case of str
When I want to work with toLowerCase() method with return type MyString, I can't return the object content but only return the address.
Normally, this problem would require modification of toString(), but since this method requires return type of String by default, I can't use modification of toString() for the assignment.
The assignment is supposed to be not so hard and should not require complex extensions. My constructor may be the problem, but I can't specify which part is.
Code
public class MyString {
private char value[];
MyString(char[] arr){
this.value = Arrays.copyOf(arr, arr.length);
}
...
MyString toLowerCase() { // can't change return type
for (int i =0; i<value.length; i++) {
if ((int)value[i] > 64 && (int)value[i] < 91) {
value[i] = (char) (value[i]+32);
}
}
return this; // this returns address, and I can't override toString
}
Problem with System.out.println(str.toLowerCase()) is it ends up calling PrintStream.println(Object o), but that method internally at some point calls o.toString() which uses code inherited from Object#toString() (since you couldn't override toString as it expect as result String which is forbidden in your project) which result in form TypeInfo#hexHashCode.
This means you can't use System.out.println(MyString).
BUT PrintStream (which instance is held by System.out) allows us to provide data to print in different forms. In this case you can use println(char[]). All you need to do is adding to MyString method like toCharArray() which would return (preferably a copy of) array of characters held by MyString class.
This way you can use it like System.out.println(myStringInstance.toCharArray()) so code from your main method would need to look like
System.out.println(str.toLowerCase().toCharArray());
// ^^^^^^^^^^^--this should return char[]
Firstly, the String class is an immutable type, i.e. the methods of String do not change the internal state (i.e. the char array), instead they return a new instance of type String.
To mirror that behavior you could implement something like this:
public MyString toLowerCase() {
char temp = new char[value.length];
// [...] Your code performing the actual logic on temp
return new MyString(temp);
}
The immutability (and its implications) of the String class is very important to understand in practice. For example, the following code procudes the intended result:
String word = "Word";
System.out.println("I can produce upper case (" + word.toUpperCase() + ") " +
"and lower case (" + word.toLowerCase() + ") " +
"without any side-effects on the original (" + word + ").");
However, it's not possible (without "hacky" solutions) to implement a method like this:
void shortenString(String inputAndOutput);
Second, the assignment expects that the class/method must be used as follows:
System.out.println(str.toLowerCase());
The attribute out is effectively a PrintStream, which offers (besides other methods) the following two:
println(Object x) - Prints an Object and then terminate the line.
println(String x) - Prints a String and then terminate the line.
If the method is called with an Object parameter, the internal implementation calls toString() on the given object, thus the only way to satisfy the requirement is to override this method. Unfortunately, this is not allowed by the assignment.
However, if it is not explicitly stated that the solution has to use java.lang.System, you could simply implement your own System class which accepts MyString, e.g.:
public class System {
public static class MyPrintStream /* optional: extends PrintStream */ {
public void println(MyString x) {
java.lang.System.out.println(x.getCharArray());
}
}
public static final out = new MyPrintStream();
}
This would allow you to use it exactly as described in the assignment:
import my.package.System;
public class Main {
public static void main(String[] args) {
// [...] Instantiate str
System.out.println(str.toLowerCase());
}
}

arraylist returning random numbers and not proper data

so I've got an arraylist
private static ArrayList<Job> teamNoOne = new ArrayList<Job>();
Of type Job, which has
public class Job {
//public long time;
public int teamNo;
public String regNo;
public String gridRef;
}
Then I'm getting data from a textField
Job job = new Job();
job.gridRef = tfGridRef.getText();
This all works, printed it to system etc.
When I add it to the arraylist, and print it out using the following code:
teamNoOne.add(job);
System.out.println(teamNoOne.get(0));
I just get this: Job#1c79dfc
cannot for the life of me figure out why,
Cheers
When a object is printed using sysout, its toString method is called. If toString method is not overridden in the class, then its default implementation will be used. Default implementation of an object toString method prints the class name and the unsigned hexadecimal representation of the hash code of the object separated by # symbol.
You need to override the toString method in your Job class in order to print the object in a pretty way. Most of the IDEs provide a way to auto- generate the toString method. Here is one generated through eclipse:
#Override
public String toString() {
return "Job [teamNo=" + teamNo + ", regNo=" + regNo + ", gridRef="
+ gridRef + "]";
}

Java array, prints something else

I'm trying to print the items from my array, but when I run the program, it prints out Orders:testorder#4, testorder#5 and so on. Any tips on how I can fix it so it writes 123 Buy?
package hej;
public class TestOrder {
public static void main(String[] args) {
Order order1 = new Order("123", "Buy");
Order order2 = new Order("456", "Sell");
Order order3= new Order("231", "Buy");
Order order4= new Order("987", "Buy");
OrderRegister orderregister = new OrderRegister();
orderregister.addOrder(order1);
orderregister.addOrder(order2);
orderregister.addOrder(order3);
orderregister.addOrder(order4);
System.out.println("Orders: ");
for (int i = 0; i < orderregister.getArrayList().size(); i++){
System.out.println(orderregister.getArrayList().get(i) + "-");
}
}
}
Because you don't have a toString() method defined for your Order class.
When Java tries to print an Object, it attempts to call the toString() method for that Object, if it can't find one it uses the toString() from the Object superclass.
And the Object toString() by default does this:
getClass().getName() + '#' + Integer.toHexString(hashCode())
which is exactly what you are seeing as output.
Have TestOrder override the toString() method.
When you concatenate an object with a String (like in your System.out.println(...) statements), the toString() method is called on the object to convert it to a String first.
You need to override the toString() method on your Order class and have it generate the string form of the order.
This is exactly what you should expect, given that you haven't told Java any other way to convert an Order to a String. Override Order.toString() if you want Java to use some particular way of converting an Order to a String.
You could/should try overriding the toString() method(which is called implicitly in your example) as others have suggested.
For example:
#Override public String toString()
{
return String.format("%s , %s", this.getID(), this.getAction());
}

Categories