Related
Can anybody explain to me the concept of the toString() method, defined in the Object class? How is it used, and what is its purpose?
From the Object.toString docs:
Returns a string representation of the
object. In general, the toString
method returns a string that
"textually represents" this object.
The result should be a concise but
informative representation that is
easy for a person to read. It is
recommended that all subclasses
override this method.
The toString method for class Object
returns a string consisting of the
name of the class of which the object
is an instance, the at-sign character
`#', and the unsigned hexadecimal
representation of the hash code of the
object. In other words, this method
returns a string equal to the value
of:
getClass().getName() + '#' + Integer.toHexString(hashCode())
Example:
String[] mystr ={"a","b","c"};
System.out.println("mystr.toString: " + mystr.toString());
output:- mystr.toString: [Ljava.lang.String;#13aaa14a
Use of the String.toString:
Whenever you require to explore the constructor called value in the String form, you can simply use String.toString...
for an example...
package pack1;
import java.util.*;
class Bank {
String n;
String add;
int an;
int bal;
int dep;
public Bank(String n, String add, int an, int bal) {
this.add = add;
this.bal = bal;
this.an = an;
this.n = n;
}
public String toString() {
return "Name of the customer.:" + this.n + ",, "
+ "Address of the customer.:" + this.add + ",, " + "A/c no..:"
+ this.an + ",, " + "Balance in A/c..:" + this.bal;
}
}
public class Demo2 {
public static void main(String[] args) {
List<Bank> l = new LinkedList<Bank>();
Bank b1 = new Bank("naseem1", "Darbhanga,bihar", 123, 1000);
Bank b2 = new Bank("naseem2", "patna,bihar", 124, 1500);
Bank b3 = new Bank("naseem3", "madhubani,bihar", 125, 1600);
Bank b4 = new Bank("naseem4", "samastipur,bihar", 126, 1700);
Bank b5 = new Bank("naseem5", "muzafferpur,bihar", 127, 1800);
l.add(b1);
l.add(b2);
l.add(b3);
l.add(b4);
l.add(b5);
Iterator<Bank> i = l.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
}
}
... copy this program into your Eclipse, and run it... you will get the ideas about String.toString...
The toString() method returns a textual representation of an object. A basic implementation is already included in java.lang.Object and so because all objects inherit from java.lang.Object it is guaranteed that every object in Java has this method.
Overriding the method is always a good idea, especially when it comes to debugging, because debuggers often show objects by the result of the toString() method. So use a meaningful implementation but use it for technical purposes. The application logic should use getters:
public class Contact {
private String firstName;
private String lastName;
public Contact (String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {return firstName;}
public String getLastName() {return lastName;}
public String getContact() {
return firstName + " " + lastName;
}
#Override
public String toString() {
return "["+getContact()+"]";
}
}
It may optionally have uses within the context of an application but far more often it is used for debugging purposes. For example, when you hit a breakpoint in an IDE, it's far easier to read a meaningful toString() of objects than it is to inspect their members.
There is no set requirement for what a toString() method should do. By convention, most often it will tell you the name of the class and the value of pertinent data members. More often than not, toString() methods are auto-generated in IDEs.
Relying on particular output from a toString() method or parsing it within a program is a bad idea. Whatever you do, don't go down that route.
toString() returns a string/textual representation of the object.
Commonly used for diagnostic purposes like debugging, logging etc., the toString() method is used to read meaningful details about the object.
It is automatically invoked when the object is passed to println, print, printf, String.format(), assert or the string concatenation operator.
The default implementation of toString() in class Object returns a string consisting of the class name of this object followed by # sign and the unsigned hexadecimal representation of the hash code of this object using the following logic,
getClass().getName() + "#" + Integer.toHexString(hashCode())
For example, the following
public final class Coordinates {
private final double x;
private final double y;
public Coordinates(double x, double y) {
this.x = x;
this.y = y;
}
public static void main(String[] args) {
Coordinates coordinates = new Coordinates(1, 2);
System.out.println("Bourne's current location - " + coordinates);
}
}
prints
Bourne's current location - Coordinates#addbf1 //concise, but not really useful to the reader
Now, overriding toString() in the Coordinates class as below,
#Override
public String toString() {
return "(" + x + ", " + y + ")";
}
results in
Bourne's current location - (1.0, 2.0) //concise and informative
The usefulness of overriding toString() becomes even more when the method is invoked on collections containing references to these objects. For example, the following
public static void main(String[] args) {
Coordinates bourneLocation = new Coordinates(90, 0);
Coordinates bondLocation = new Coordinates(45, 90);
Map<String, Coordinates> locations = new HashMap<String, Coordinates>();
locations.put("Jason Bourne", bourneLocation);
locations.put("James Bond", bondLocation);
System.out.println(locations);
}
prints
{James Bond=(45.0, 90.0), Jason Bourne=(90.0, 0.0)}
instead of this,
{James Bond=Coordinates#addbf1, Jason Bourne=Coordinates#42e816}
Few implementation pointers,
You should almost always override the toString() method. One of the cases where the override wouldn't be required is utility classes that group static utility methods, in the manner of java.util.Math. The case of override being not required is pretty intuitive; almost always you would know.
The string returned should be concise and informative, ideally self-explanatory.
At least, the fields used to establish equivalence between two different objects i.e. the fields used in the equals() method implementation should be spit out by the toString() method.
Provide accessors/getters for all of the instance fields that are contained in the string returned. For example, in the Coordinates class,
public double getX() {
return x;
}
public double getY() {
return y;
}
A comprehensive coverage of the toString() method is in Item 10 of the book, Effective Java™, Second Edition, By Josh Bloch.
Whenever you access an Object (not being a String) in a String context then the toString() is called under the covers by the compiler.
This is why
Map map = new HashMap();
System.out.println("map=" + map);
works, and by overriding the standard toString() from Object in your own classes, you can make your objects useful in String contexts too.
(and consider it a black box! Never, ever use the contents for anything else than presenting to a human)
Correctly overridden toString method can help in logging and debugging of Java.
Coding:
public class Test {
public static void main(String args[]) {
ArrayList<Student> a = new ArrayList<Student>();
a.add(new Student("Steve", 12, "Daniel"));
a.add(new Student("Sachin", 10, "Tendulkar"));
System.out.println(a);
display(a);
}
static void display(ArrayList<Student> stu) {
stu.add(new Student("Yuvi", 12, "Bhajji"));
System.out.println(stu);
}
}
Student.java:
public class Student {
public String name;
public int id;
public String email;
Student() {
}
Student(String name, int id, String email) {
this.name = name;
this.id = id;
this.email = email;
}
public String toString(){ //using these toString to avoid the output like this [com.steve.test.Student#6e1408, com.steve.test.Student#e53108]
return name+" "+id+" "+email;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getId(){
return id;
}
public void setId(int id){
this.id=id;
}
public String getEmail(){
return email;
}
public void setEmail(String email){
this.email=email;
}
}
Output:
[Steve 12 Daniel, Sachin 10 Tendulkar]
[Steve 12 Daniel, Sachin 10 Tendulkar, Yuvi 12 Bhajji]
If you are not used toString() in Pojo(Student.java) class,you will get an output like [com.steve.test.Student#6e1408, com.steve.test.Student#e53108].To avoid these kind of issue we are using toString() method.
Apart from what cletus answered with regards to debugging, it is used whenever you output an object, like when you use
System.out.println(myObject);
or
System.out.println("text " + myObject);
The main purpose of toString is to generate a String representation of an object, means the return value is always a String. In most cases this simply is the object's class and package name, but on some cases like StringBuilder you will got actually a String-text.
/**
* This toString-Method works for every Class, where you want to display all the fields and its values
*/
public String toString() {
StringBuffer sb = new StringBuffer();
Field[] fields = getClass().getDeclaredFields(); //Get all fields incl. private ones
for (Field field : fields){
try {
field.setAccessible(true);
String key=field.getName();
String value;
try{
value = (String) field.get(this);
} catch (ClassCastException e){
value="";
}
sb.append(key).append(": ").append(value).append("\n");
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return sb.toString();
}
If you learn Python first and then Java. I think it plays the same role as __str__() method in Python, it is a magic method like __dict__() and __init__() but to refer to a string representing the the object.
the toString() converts the specified object to a string value.
Im trying to make a program that allows the client to input a String. The string length should have 3 characters only and should contain the letters .
My program have to pass through this table and check what this string refers to..
Let's say the client passed this String "AUG", my program should show the name of this String which is "Met".
I made a code, and it worked but it has more then 15 if else-if condition.
My question is : Is there any other way to do it without using if else-if (or switch).
And does polymorphism work in this case ?
Have a look at HashMap
You can build your table with:
Map<String, String> table = new HashMap<>();
table.put("AUG", "Met");
table.put(...);
Then access your table using the user's input:
if(table.containsKey(input)){
return table.get(input);
}
I think I'd go about it with an enum personally (provided performance wasn't a significant concern):
public enum Abbreviations {
Ala("GCU", "GCC", "GCA", "GCG"),
Arg("CGU", "CGC", "CGA", "CGG", "AGA", "AGG")
// ...
;
private final List<String> codons;
private Abbreviations(final String... codons) {
this.codons = Arrays.asList(codons);
}
public boolean contains(final String codon) {
return this.codons.contains(codon);
}
}
And then you can find their matching from the String using something like:
public String find(final String codon) {
for (final Abbreviations abb : Abbreviations.values()) {
if (abb.contains(codon)) {
return abb.name();
}
}
throw new IllegalArgumentException("Unknown codon: '" + codon + "'");
}
You could try an Object Oriented Aproach:
//This is your representation of Codon
//Which has a name e.g. Alanine and an Abreviation object.
public class Codon {
private String name;
private Abreviation abreviation;
public Codon(String name, Abreviation abreviation) {
this.name = name;
this.abreviation = abreviation;
this.abreviation.addCodon(this);
}
#Override
public String toString() {
return "Codon [name=" + name + ", abreviation=" + abreviation + "]";
}
}
import java.util.ArrayList;
import java.util.List;
// This is a representation of an abreviation object
// Which has an abreviation: ALA;
// and the name of the abreviation "Alanine".
public class Abreviation {
private String abreviation;
private String name;
private List<Codon> codons = new ArrayList<>();
public Abreviation(String abreviation, String name) {
super();
this.abreviation = abreviation;
this.name = name;
}
public boolean addCodon(Codon codon) {
return this.codons.add(codon);
}
#Override
public String toString() {
return "Abreviation [abreviation=" + abreviation + ", name=" + name + "]";
}
}
// Here is your program, where it's being build all the Codons structure with your respective Abbreviation.
public class App {
public static void main(String[] args) {
// This is abreviation, it'll will associated with the codon
Abreviation alanine = new Abreviation("Ala", "Alanine");
// Here it's being build the codon CGU, which has abreviation alanine
Codon GCU = new Codon("GCU", alanine);
// Then using toString method it prints what have been done
System.out.println(GCU);
}
}
You can put all of your codons into a List, so you can search and retrieve then.
This is probably a bad question, but i have constructed a DVD object in java:
DVD myDVD = new DVD (11.17 , 9 , 120 , " Howl ’s Moving Castle " , " Hayao Miyazaki " );
I have a toString to print the whole object, but I've been asked to print the director (Hayao Miyazaki) of the object without the rest, is there a way to do this?
If you need any more information in order to help, please comment. Thanks
create a get method for the director
public String getDirector(){
return director;
}
System.out.print(myDVD.getDirector());
Assuming your code is Java code, in your DVD class, you can override the toString method in order to print what you want:
public class DVD {
private String director;
//more fields and stuff
#Override
public String toString() {
return director;
}
}
If you already have a toString implementation and need another one, you can add another method to get the director:
public String getDirector(){
return director;
}
and print it:
System.out.print(myDVD.getDirector());
Or you may want a method to do the printing itself:
public void printDirector() {
System.out.println(director);
}
You could make it as simple as writing a new method printDirector() which would do just that, OR...
You could leave the responsibility of printing the information to some other class, and make the DVD object responsible only for providing its information:
public class Movies {
public class DVD {
private director;
public DVD(String director) {
this.director = director;
}
public String getDirector() {
return director;
}
}
public static void main(String... arg) {
DVD howl = new DVD("Miyazaki");
String director = howl.getDirector();
SomePrinterClass.print(director);
}
}
Ultimately that's a design decision, either will produce the same result.
I use a method
public String introduce()
{
return super.introduce();
}
which returns the value from introduce() method of super class. And assume introduce() method returns
Hey! I'm Steve and I'm 26 years old
In the same class,I also have another method
public String getAlter() {
return alter;
}
Now alter contains the value:
Jobs
Now, the question is how do I return the value
Hey! I'm Steve and I'm 26 years old. I'm also known as Jobs!
from the overridden method, ie
public String introduce()
{
return super.introduce();
}
Just concatinate the strings returned by the two methods:
#Override
public String introduce() {
return super.introduce() + ". I'm also known as " + getAlter() + "!";
}
You have to override the method introduce:
1) call the super class method introduce() -> returns "Hey! I'm Steve and I'm 26 years old"
2) use method getAlter() inside the overridden method introduce()"
public String getAlter() {
return "Jobs";
}
#Override
public String introduce() {
String msg = super.introduce();
String name = this.getAlter();
msg = msg + ". I'm also known as " + name + "!";
return msg;
}
public static void main(String[] args) {
Jobs jobs = new Jobs();
String msg = jobs.introduce();
System.out.println(msg);
}
public String introduce()
{
return super.introduce()+" I'm also known as "+getAlter();
}
You can use the result of super.introduce() to build your final result.
#Override
public String introduce() {
return super.introduce() + ". I'm also known as " + getAlter() + "!";
}
Note the #Override annotation to make it clear that I am hiding the super implementation.
Don't immediately return your call to super:
public String introduce()
{
return super.introduce() + getAlter();
// for clarity, you are essentially performing these operations:
// String response = super.introduce();
// response = response + " I'm also known as ";
// response = response + getAlter();
// return response;
}
Simple way is to append them like:
#Override
public String introduce() {
StringBuilder strBuilder = new StringBuilder();
strBuilder.append(super.introduce());
strBuilder.append(" I'm also known as");
strBuilder.append(getAlter());
return strBuilder.toString();
}
Hope this help!
I have a Model class DOModel :
package amarsoft.dbmp.credit.web.model;
import ejp.annotations.ConcreteTableInheritance;
import amarsoft.rcp.base.databinding.BindableModel;
#ConcreteTableInheritance
public class DOModel extends BindableModel {
/**
* 编号
*/
private String id;
/**
* 名称
*/
private String name;
/**
* 模板类型,没有太大意义
*/
private String type;
/**
* 模板参数
*/
private String args;
private String updateTable;
private String updateWhere;
private String fromClause;
private String whereClause;
private String groupClause;
private String orderClause;
public String getId() {
return id;
}
public void setId(String id) {
this.firePropertyChange("id", this.id, this.id = id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.firePropertyChange("name", this.name, this.name = name);
}
public String getType() {
return type;
}
public void setType(String type) {
this.firePropertyChange("type", this.type, this.type = type);
}
public String getArgs() {
return args;
}
public void setArgs(String args) {
this.firePropertyChange("args", this.args, this.args = args);
}
public String getUpdateTable() {
return updateTable;
}
public void setUpdateTable(String updateTable) {
this.firePropertyChange("updateTable", this.updateTable, this.updateTable = updateTable);
}
public String getDoUpdateWhere() {
return updateWhere;
}
public void setDoUpdateWhere(String doUpdateWhere) {
this.firePropertyChange("updateWhere", this.updateWhere, this.updateWhere = doUpdateWhere);
}
public String getFromClause() {
return fromClause;
}
public void setFromClause(String fromClause) {
this.firePropertyChange("fromClause", this.fromClause, this.fromClause = fromClause);
}
public String getWhereClause() {
return whereClause;
}
public void setWhereClause(String whereClause) {
this.firePropertyChange("whereClause", this.whereClause, this.whereClause = whereClause);
}
public String getGroupClause() {
return groupClause;
}
public void setGroupClause(String groupClause) {
this.firePropertyChange("groupClause", this.groupClause, this.groupClause = groupClause);
}
public String getOrderClause() {
return orderClause;
}
public void setOrderClause(String orderClause) {
this.firePropertyChange("orderClause", this.orderClause, this.orderClause = orderClause);
}
#Override
public String toString() {
return "DOModel [id=" + id + ", name=" + name + "]";
}
#Override
public int dataValueHashCode() {
int code = 0;
if (id != null) {
code += id.hashCode();
}
if(name != null){
code += name.hashCode();
}
if(type != null){
code += type.hashCode();
}
if(args != null){
code += args.hashCode();
}
if(updateTable != null){
code += updateTable.hashCode();
}
if(updateWhere != null){
code += updateWhere.hashCode();
}
if(fromClause != null){
code += fromClause.hashCode();
}
if(whereClause != null){
code += whereClause.hashCode();
}
if(groupClause != null){
code += groupClause.hashCode();
}
if(orderClause != null){
code += orderClause.hashCode();
}
return code;
}
}
this class is used in ORM, when one or more property of DOModel's instance is changed, I need to persist the DOModel's instance back to database.
so there is a problem for me: how can I know a DOModel instance object is modified compared to a specific time ?
please notice the method dataValueHashCode, I use a combination of the hash code of all the properties to measure if a model is changed.the basic flow is:
1.load the a DOModel object from database
2.call dataValueHashCode method and cache it
3.(optional)modify property values
4.when need to save the object back to database, call dataValueHashCode method again
and compare it to the cached one
5.if match, no change. if not match, save it back to database.
It seems that works right now, but as a java newbie, I am worrying there is potential problems. so before I go further, I want to prove my way will not lead me to a wrong place.
As a Chinese, my English is not good enough. if you have problem to understand what I am talking about, please post comment, I will try my best to edit this question.
thanks a lot!
There is something potentially wrong with that approach: two different objects may have the same hashCode value (the contract for hashcode is only that if a.equals(b) is true, then a.hashCode == b.hashCode, theoretically, all hashCodes could return 1 they would still be valid albeit inefficient)
So you need to come up with a cryptographic hash of yours that doesn't use hashcode, if you want to be absolutely certain it reflects your object change. I suggest using MD5 encryption, which (almost) uniquely identifies a string. It's not completely collision-resistant (means theoretically, there are multiple strings with the same output), but in practice, it's good enough.
http://en.wikipedia.org/wiki/MD5
It's quite easy to do in Java:
final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
final byte[] data = stringToConvert.getBytes();
messageDigest.update(data,0,data.length);
final BigInteger hash = new BigInteger(1,messageDigest.digest());
return String.format("%1$032X", hash);
That sounds like you're relying on "equal hash codes imply equal objects" which is not safe to rely on.
Assuming a proper implementation of hashCode, you should be able to rely on "different hash codes mean unequal objects" - but the reverse is not true.
In particular, an implementation of:
#Override public int hashCode() {
return 0;
}
is always valid. Sucky, but valid.
If you want to be sure that there is no change you have to compare the contents of the attributes rather than the hash code. For that you should implement the equals method. The problem with the hash code is that though unlikely it can be the same value for different property values.
This is not the way to override hashCode(). Joshua Bloch tells you the correct way to do it in chapter 3 of his "Effective Java".
It seems that works right now, but as a Java newbie, I am worrying there is potential problems.
It's not a safe approach: A change in an object, does not guarantee that the objects hash code changes.
Keep in mind that a hash code is simply an int. If your object have more than 232 states (as in your case) you are bound to have hash collisions.
A few more pointers regarding your code:
When overriding hashCode, you need to also override equals.
Your hashCode implementation is not very good (it doesn't provide a very good distribution)