Java Explanation?...

Started by
8 comments, last by Zahlman 17 years, 9 months ago
Hi all, im learning the java language and want to properly understand it.(this is the reason i am posting here today)While reading my book on the language, i came acrossa subject that was rather hard to grasp, so i decided to come here and ask for help.My problem is the Object class, to be more specific the hashCode method(actually the whole hashCode concept), the equals method and the toString method. Anyway, if anyone could provide some help on this subject i would be quite grateful and be able to move forward more confidently and with a better understanding through the path of learning the java language. Thanks to all who respond, Francis...
Advertisement
Have you already had a look at the documentation? The Java-API is quite good documented: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html
Quote:Original post by Jockel
Have you already had a look at the documentation? The Java-API is quite good documented: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html


yes i looked at the api but i would like a more in depth explanation, the api is to generic i want something specific that will actually explain these things to meso i can have a good understanding of them.
hashCode: Two objects with equal data should have the same hashcode. Basically, you have to come up with a mathematical formula based on Object data to give each object a unique hash of some sort. If hashCode() is called on any object twice, it must give the same hash code value. Normally it is used for hashmaps and that sort of thing. Those will probably be further down the road for you. You probably don't have to have too great an understanding of this concept yet.

equals: Because objects (not primitives) in Java are references, saying aObject == bObject does not compare their data (deep compare), but rather compares where they point to in computer memory (shallow compare). Calling aObject.equals(bObject) performs a deep compare, using the data of the objects instead of where they point to in memory.

Think of it this way:

aObject-----> | 0x10: 'b' |
bObject-----> | 0x11: 'b' |

if you did aObject == bObject, you are comparing 0x10 to 0x11, which are not equal. However, aObject.equals(bObject) compares 'b' against 'b', which is equal. You must implement your own equals method for any of your own classes, otherwise java has no idea what data to compare.

toString: Basically converts your class to a human readable form instead a bunch of bits. This allows you to easily pipe it to any sort of stream (most likely, for you, console output: System.out). Again, another method you override in your own classes.

Remember, the Java API will become your best friend.

[Edited by - visage on July 24, 2006 10:45:14 AM]
Some OOP languages have a single root class, so that any and all classes (w/o the root class itself, of course) are derived directly or indirectly from it. By this concept the language can guarantee a minimum set of features for all classes. In Java this class is Object. C++, on the other hand, doesn't know such a root class.

Hashing is in general a method to compute a simple value from a complex one (e.g. composed of many single values, like the fields of an object), where it is tried that a single change in the complex value results in a (very) different hash value. Because a complex value could store many more states than the simpler hash value, there must be an information loss. I.e. in fact several complex values may result in the same hash value.

The sense of a hash value is most often its use as a (non unique) key for speed up purposes. E.g. an equality comparison of two instances of the complex value can be performed by 1st looking for identical hash values, and only if both are the same the complex values has to be compared part by part. So hashing is used e.g. by containers/collections for key generation (e.g. HashSet).

The toString() method is simply for returning a string representation of the (binary) object. For the String class this is obviously simple, and for Number classes simple the string converted numbers are returned. However, most classes have no implementation of toString(), e.g. because they have no suitable string representation. For such classes Object implements a basic conversion that returns the class name and object address.

And equals(Object), well, is simple a comparison routine as the name suggests. In opposite to a hash value for comparison, equals(Object) has to be exact. Java has defined a set of rules how equals(Object) has to be implemented to work well.
In Java you have primitive types and reference types. Primitive types are byte, short, int, long, char, float, double. Reference types basically are pointers (internally) referring to objects on that heap. Every object (also called class instance) has a type which is part of a class hierarchy. Classes may derived from one super-class and may implement any number of interfaces. The class Object is special, because it is the root of the class hierarchy. Object has no super-class.

The class String is a subclass of Object. An instance of String represents an unchangeable sequence of characters. If such a character sequence is modified (i.e. all 'a' replaced by 'b'), a new instance of String is created. In Java Strings are treated specially. For instance the string concatenation operator allows to add two strings or a string and a number. The class Object contains a method toString (and so do all other classes), which allows to convert the contents of a class to a readable representation. The default behavoir of toString() is to return the hash-value of the object converted to a character sequence (a String). Other class may implement something different.

Hashing is used to map a set of many input values to a much smaller set of output values. There exist many algorithms to create hash-values. CRCs are used to check data integrity (i.e. to detect bit errors) and cryptographic hash-functions (like MD5) are used to create hashes that are hard to invert (also called one-way function). Because the class Object contains such a hash-function, any instance of a class may be put into a Hashtable or HashSet for instance (all subclasses derived the hash-function). Depending on the contents of the instance data, other classes may want to provide another hash-function.

The equals function allows to check if two instances of a class are the same. Consider the a class Vector2D, which contains two members x and y. Two instances a and b of Vector2D are the same according to the equals method if a.x == b.x and a.y == b.y. Then you also need to provide a hash-function that is based on that assumption. If both instances are equal, their hash-values should be the same. This allows to put instances of Vector2D into a HashSet for instance.

Hope that helped.
So if i understand correctly, the toSrting() method is to print data of a class(probably used alot for logging), the hash Code is used for storing data locations and the equals() method is like calling the test:
if (x==y) //exept x and y are non-primitive values.

Quote:Original post by 14 year old
So if i understand correctly, the toSrting() method is to print data of a class(probably used alot for logging), the hash Code is used for storing data locations and the equals() method is like calling the test:
if (x==y) //exept x and y are non-primitive values.


Sort of. In Java, objects of a given class are by default not "ordered" (which is to say, you can check if x and y are equal, but if they're not, you can't meaningfully say which is "lesser"), and variables of object type are only considered to be "equal" if they refer to the same actual object. The default hashCode() is a unique identifier for objects, so '==' simply compares default-hashCode() values (even if you override hashCode for your class).

The .equals() method is provided because Java doesn't do operator overloading, in order to give a standard name for a function that compares two objects for equality. Of course, you could write a function with any name that did that, but by having it be a .equals() implementation, you get the benefit that standard library stuff that compares your objects to each other (like Map containers, Comparator objects etc.) will work properly (because they are looking for your .equals()). In order to get consistent results, though, when you implement .equals(), you also need to implement hashCode(), in such a way that the 'invariant' is preserved: If x.equals(y), then x.hashCode() == y.hashCode(). That consistency is required for various other things to work right. It might seem a little tricky at first, but it's much, much easier (and an all-around better idea) than re-making things like HashMap yourself.

The .toString() is similar: because of how the Java I/O libraries and string concatenation work, you need to be able to convert general objects into Strings in order to output them. In .toString(), you write code that yields a string representation of the object. Normally you want this to include the values of important data members (you can use their .toString()s in turn) and a bit of formatting. Again, you could make any method that did that and call it yourself, but by using toString(), you get the benefit that it will automatically work with things like System.out.println().
Wow, things seem quite clearer now. Of course I dont fuly understand(but I do alot more than i did before), but the only way to accomplish that is by practice and study. I thank you all, for you have been a helpful asset to my learning experience, and i am glad to have a reliable place to come with my problems.

Once again, Thank you,

Francis...

You should probably also read this.

This topic is closed to new replies.

Advertisement