aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Please explain me this! Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Please explain me this!" Watch "Please explain me this!" New topic
Author

Please explain me this!

Sonam Arya
Greenhorn

Joined: Sep 26, 2008
Posts: 4
Can you please tell me why this program is throwing ClassCastExcep


import java.util.*;
public class Car {
public int wheels = 0;
public Car(){}
public Car(int wheels) {
this.wheels = wheels;
}

public String toString() {
return new Integer(wheels).toString();
}
public static void main(String[] args) {
Car c1 = new Car(1);
Car c2 = new Car(2);
Car c3 = new Car(3);
TreeSet list = new TreeSet();
list.add(c3);
list.add(c1);
list.add(c2);
Iterator it = list.iterator();
while (it.hasNext())
System.out.print (it.next() + " ");
}
}
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61657
    
  67

"ScreenSunCert Desire", please check your private messages for an important administrative matter.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18996
    
  40

Can you please tell me why this program is throwing ClassCastExcep


A TreeSet either requires you to use a Comparator, or have Comparable objects in the set. Since you are *not* using a Comparator, it is assuming that the objects are Comparable. Since your objects are not, this will generate a class cast exception.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Sonam Arya
Greenhorn

Joined: Sep 26, 2008
Posts: 4
But if i implement comparator why does it print 1 2 3 since i added in 3 1 2 fashion, it should have printed in the same fashion

import java.util.*;
public class Car implements Comparator {
public int wheels = 0;
public Car(){}
public Car(int wheels) {
this.wheels = wheels;
}
public int compare(Object o1, Object o2) {
Car c1 = (Car)o1;
Car c2 = (Car)o2;
return new Integer(c1.wheels).compareTo(new Integer(c2.wheels));
}
public String toString() {
return new Integer(wheels).toString();
}
public static void main(String[] args) {
Car c1 = new Car(1);
Car c2 = new Car(2);
Car c3 = new Car(3);
TreeSet list = new TreeSet(new Car());
list.add(c3);
list.add(c1);
list.add(c2);
Iterator it = list.iterator();
while (it.hasNext())
System.out.print (it.next() + " ");
}
}
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18996
    
  40

But if i implement comparator why does it print 1 2 3 since i added in 3 1 2 fashion, it should have printed in the same fashion


A TreeSet sorts the set. And the sorted order is determined by the comparator (or comparables). You comparator does not sort by insertion order -- nor am I sure if it is possible to write one.

If you want insertion order, you might want to consider using the LinkedHashSet instead.

Henry
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Have you checked the API documentation?

In a TreeSet, "elements are ordered using their natural ordering, or by a Comparator provided at set creation time, depending on which constructor is used." A TreeSet's iterator is "over the elements in this set in ascending order."


"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
sscce.org
Manju Kavi
Ranch Hand

Joined: Sep 25, 2008
Posts: 33
Hi,
TreeSet is a sorted collection of elements. In order to put elements(objects) in set, the objects should be mutually comparable. And TreeSet uses Comparable(natural order) or Comparator(user defined) to sort the elements. Objects that we are trying to put in the sets should implement Comparable or Comparator and override compareTo() method. So while inserting objects, TreeSet makes use of this method to compare inserting element with each element in the set. Here is the updated program..
import java.util.*;
public class Car implements Comparable
{
public int wheels = 0;
public Car(){}
public Car(int wheels)
{
this.wheels = wheels;
}

public String toString()
{
return new Integer(wheels).toString();
}

public int compareTo(Object o)
{
Car c=(Car)o;
if(c.wheels>this.wheels)
return -1;
else if(c.wheels<this.wheels)
return 1;
else
return 0;

}

public static void main(String[] args)
{
Car c1 = new Car(1);
Car c2 = new Car(2);
Car c3 = new Car(3);
TreeSet list = new TreeSet();
list.add(c3);
list.add(c1);
list.add(c2);
Iterator it = list.iterator();
while (it.hasNext())
System.out.print (it.next() + " ");
}

}
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Aren't you supposed to use Casting with Iterator..?
i was pretty sure it would result in a Class Cast Exception

Then why didn't it cause any exception.

I thought ..only when you specify what type it is , then you dont require the casting ie
Iterator<Car> i= list.Iterator()


The future belongs to those who believe in the beauty of their dreams.Dream BIG!
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9313
    
  17

No, a cast is not needed for backward compatibility....


SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Can you please elaborate a little ..please!
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9313
    
  17

There is no need to say please man, anything for you guys...

suppose there is a class that was compiled with jdk1.4, it takes a untyped ArrayList as parameter in one of it's methods,

void method(ArrayList al)
{
::
}

now if you want to pass a typed ArrayList to this method, then what? you might say that we will call it as

ArrayList<String> al = ...;
method((ArrayList)al);

but the compiler can't disallow you to call it directly, as the code might actually work without the cast. This is because after type erasure, there is no difference between a typed array list and un-typed list. So the compiler allows this with a unchecked warning...
Manju Kavi
Ranch Hand

Joined: Sep 25, 2008
Posts: 33
Hi Nabila,
Yes you are right that we need a cast because iterator always returns element of type "Object". But here you never get that exception because we are not trying to assign the elements returned by the it.next() method to Car variable. Something like this..

while (it.hasNext())
{
Car c=it.next();
System.out.print (c+"");
}
In this case we get an error telling incompatible types.
Again when you use generics, casting is not necessary.
Manju Kavi
Ranch Hand

Joined: Sep 25, 2008
Posts: 33
Here we are directly trying to display the elements returned by next() method. I think you know that when we try to display the object, then its toString() method is called. So here we are actually calling the toString() mothod of "Object" class which is overridden in the Car(subclass). Polymorphism!
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9313
    
  17

Oops! I told a completely different thing
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Manju - Thanks alot..

That means if the toString() method is overridden, then even if dont cast it's ok and it will run.

But if you dont overrider it ,then casting is necessary - and in if casting is not done, then it would give ClassCastException and not a compile time error.

Right???

Correct me if i am wrong.

I have my exam in like 2 hrs and this was really bothering me...
So just logged in to make sure
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Originally posted by Manju:
Here we are directly trying to display the elements returned by next() method. I think you know that when we try to display the object, then its toString() method is called. So here we are actually calling the toString() mothod of "Object" class which is overridden in the Car(subclass). Polymorphism!



When you saidd displaying the object - it means using System.out.println() Right ...or something else..?
mukki pandey
Ranch Hand

Joined: Sep 22, 2008
Posts: 58
A TreeSet either requires you to use a Comparator, or have Comparable objects in the set. Since you are *not* using a Comparator, it is assuming that the objects are Comparable. Since your objects are not, this will generate a class cast exception.



Comparable objects in the sense.....i mean whats wrong with baove code

list.add(c1); this is calling construtor with interger values

can anyone please explain
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Originally posted by mukki pandey:
A TreeSet either requires you to use a Comparator, or have Comparable objects in the set. Since you are *not* using a Comparator, it is assuming that the objects are Comparable. Since your objects are not, this will generate a class cast exception.



Comparable objects in the sense.....i mean whats wrong with baove code

list.add(c1); this is calling construtor with interger values

can anyone please explain


Comparable means - you can compare them some how..
Like STring you can sorit it out in Alphabetical order
Number are sorted out in ascending order.

But in this case it does not know how sort the objects you are adding.
Because you havent specified any way .
And this specification is supposed to be give by implementing Comparator.
Rekha Srinath
Ranch Hand

Joined: Sep 13, 2008
Posts: 178
Nabila,

That means if the toString() method is overridden, then even if dont cast it's ok and it will run


Its not that if toString() is overridden, cast is not required. If you are going to assign the iterated value to some object, then the corresponding cast is required.

Say, for eg,
Animal a = (Animal) it.next(); // Cast required, because you are assigning it.next()'s return to an Animal reference

Object b = it.next (); // Cast not required, because it.next() returns an Object.

If we are just printing the iterated object contents using System.out.println, it means that we are using Object's toString() method and it has nothing to do with the casting that we are talking about here.
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Ohh ok..

i got the difference ..

Thanks.
Manju Kavi
Ranch Hand

Joined: Sep 25, 2008
Posts: 33
Nabila,
Rekha is absolutely right, toString() is no where related to casting. Sorry i counldn't reply you before time.
 
Don't get me started about those stupid light bulbs.
 
subject: Please explain me this!