Generic List I've made holding Objects I've made must be cast?
I'm taking a Data Structures class and it is in Java. Right now I am working on making my own linked list. Everything seems to be working properly (no type warnings)
~Again, note that this is not the java.util List~
I have a List<E>, used in main:
Code:
List<Integer> myList = new List<Integer>();
for (int i = 0; i < 5; i++)
myList.push_back(i);
}
System.out.println("Welcome to my list: ");
//ListIterator I have made
for (ListIterator iter = myList.getIterator(); iter.exists(); iter.next())
System.out.println(iter.get());
This works as expected. However, when I use my own data type:
Code:
String str = "Hello World. Nice to meet you";
String[] splitStr = str.split(" ");
List<MyData> myList = new List<MyData>();
for (int i = 0; i < splitStr.length; i++)
myList.push_back(new MyData(splitStr[i], i));
}
System.out.println("Welcome to my list: ");
//ListIterator I have made
for (ListIterator iter = myList.getIterator(); iter.exists(); iter.next())
System.out.println(iter.get().number);
That last line gives me an error: incompatible types
I can fix the error like so:
Code:
for (ListIterator iter = myList.getIterator(); iter.exists(); iter.next())
{
MyData temp = (My Data) iter.get();
System.out.println(temp.number);
}
But I don't want to have to do that. When I just do:
Code:
for (ListIterator iter = myList.getIterator(); iter.exists(); iter.next())
{
System.out.println(iter.get());
}
I get MyData@memAddress printed on screen, so the program does know that it is a MyData already?
If it helps, my iter.get() function:
Code:
public E get()
{
return iter == null ? null : iter.data;
}
I guess I'm looking to find out where the disconnect is happening that I would need the cast.
Thanks for reading/helping :)
Re: Generic List I've made holding Objects I've made must be cast?
First off, you really shouldn't name your own classes the same as existing Java classes. It's really confusing and can lead to other problems.
But to answer your problem, you have to pass the generics data into your Iterator, as well. Right now you aren't supplying it, so it's defaulting to Object.
Re: Generic List I've made holding Objects I've made must be cast?
Aha, thank you very much.
The names are confusing. I will think about a new name.
Re: Generic List I've made holding Objects I've made must be cast?
Okay, so now I have another problem, sorting.
Since Objects can not use the comparisson operators, we must use the compareTo() method. I've made myself a List<Integer>, which I assume should work find (indeed Integer does implement Comparable). However, I'm getting the "can not find symbol error":
Code:
// my name is Carl
for (first = new CarlListIterator<E>(head); first.myNode.next != null; first.next())
{
for (second = new CarlListIterator<E>(first.myNode.next); second.exists(); second.next())
{
if ( first.myNode.data.compareTo(second.myNode.data) > 0)
{
swap(first.myNode, second.myNode);
CarlListIterator<E> temp = first;
first = second;
second = temp;
}
}
}
Which is fixable via:
Code:
for (first = new CarlListIterator<E>(head); first.myNode.next != null; first.next())
{
for (second = new CarlListIterator<E>(first.myNode.next); second.exists(); second.next())
{
if ( ((Integer)first.myNode.data).compareTo((Integer)second.myNode.data) > 0)
{
swap(first.myNode, second.myNode);
CarlListIterator<E> temp = first;
first = second;
second = temp;
}
}
}
I realize for any Object I make I will need to have some comparrison functions (actually, I hope to make my sort accept an interface). I'm wondering how I can get my list to work with Java's types?
Thanks again.
Edit: Maybe I've only described half the error message. The message reports that "first.myNode.data" and "second.myNode.data" are of different types: E#1 and E#2. Not quite sure about this.
Re: Generic List I've made holding Objects I've made must be cast?
That's a wonky use of a for loop- most people would use a while loop with an iterator, but hey whatever works.
Your CarlListIterator contains Objects of type E- but what does it know about E? Is E guaranteed to implement Comparable?
Re: Generic List I've made holding Objects I've made must be cast?
Quote:
Is E guaranteed to implement Comparable?
For now, let's just say yes.
I've cleaned things up a little, no longer getting an error that they are two different types. Making CarlList<Integer>:
Code:
public class CarlList<E>
{
//... Many other things
public void sort()
{
// Cases to abort
if (size < 2) return;
ListIterator<E> first;
ListIterator<E> second;
int i = 0;
for (first = new ListIterator<E>(head); first.myNode.next != null; first.getNext())
{
for (second = new ListIterator<E>(first.myNode.next); second.exists(); second.getNext())
{
if (first.get().compareTo(second.get()) > 0)
{
swap(first.myNode, second.myNode);
ListIterator<E> temp = new ListIterator<E>(first.myNode);
first = second;
second = temp;
}
}
}
}
}
I get the error: Can not find symbol compareTo() in method compareTo(E).
location: Class Object
where E is a type-variable: E extends Object declared in class CarlList
Which again, is solved:
Code:
if (((Integer)first.get()).compareTo((Integer)second.get()) > 0)
The get() returns an E, but we aren't quite seeing that E is an Integer?
Re: Generic List I've made holding Objects I've made must be cast?
What I mean is, you might know that E is going to be Comparable, but how does the compiler know? Recommended reading: Bounded Type Parameters (The Java™ Tutorials > Learning the Java Language > Generics (Updated))
Re: Generic List I've made holding Objects I've made must be cast?
Thanks for the link, now I have something like this:
Code:
public class CarlList <E extends Comparable<e>>
And things are working fine.
Quote:
Is E guaranteed to implement Comparable?
So the answer is now certainly yes. Which means MyData needs a "sorting mode" that will tell it how compareTo() should work. Not the most elegant solution, perhaps you can toss something out and I'll see how far over my head it goes?
Thanks a whole lot. :)