Generics and casting question
Hi everybody,
I thought I knew my stuff when it comes to generics, but I'm getting some compiler warnings that I cannot figure out, referring to type safety and unchecked conversion. I have a feeling it comes from a gap in my knowledge about generics, so I'd like to post up my code with the warnings and see if anybody can help me out.
The code and warnings are:
// Type safety: cast is checking against erased type List
while( iterator.hasNext() ){
Map.Entry current = (Map.Entry)iterator.next();
List<Integer> values = (List<Integer>)current.getValue();
}
// Type safety: TreeMap needs unchecked conversion
// getPhrasesBySize accesses a TreeMap[] (non-parameterized array of TreeMaps because it wouldn't let me parameterize the array)
TreeMap<String, ArrayList><Integer>> phrases = Database.getPhrasesBySize()[length-3];
// and in that same vein:
// The method put belongs to type TreeMap, reference should be parameterized
phrasesBySize[i-2].put( phrase, value );
Thanks for looking!
Jezzica85
[1366 byte] By [
jezzica85a] at [2007-11-27 9:56:53]

could you post a SSCCE? http://homepage1.nifty.com/algafield/sscce.html
The "fine print" part of Sun's Tutorial might help: http://java.sun.com/docs/books/tutorial/extra/generics/fineprint.html
I don't know if I can post a SSCCE without annoying everybody--it needs a text file input so there's no way for it to be self-contained, and one of the warnings is on the last line of the program, which is about 150 lines, so a lot of code. If you'd still like me to, OK, but I don't want to without knowing if it'll throw everybody off.
I tried that "fine print" tutorial, and I'm not sure how it applies to my problems; it didn't say anything about maps. Am I missing something? I tried wildcard parameterized maps like this:
TreeMap<?,?> map = new TreeMap<?,?>();
but then it gave me errors in the "put" method. I'm really confused about this.
Thanks,
Jezzica85
Message was edited by:
jezzica85
With respect to the iterator warning:import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class MapEg {
static Map<String,List<Integer>> map;
public static void main(String args[]) {
map = new HashMap<String,List<Integer>>();
Iterator<Map.Entry<String,List<Integer>>> iterator = map.entrySet().iterator();
while( iterator.hasNext() ) {
// The following lines give "the cast from Object to List<Integer>"
// warning when values is initialised.
//Map.Entry current = (Map.Entry)iterator.next();
//List<Integer> values = (List<Integer>)current.getValue();
// The following lines compile OK
Map.Entry<String,List<Integer>> current = iterator.next();
List<Integer> values = current.getValue();
System.out.println(values);
}
}
}
The point is that if current is declared as a plain Map.Entry you get a warning about the potentially unsafe cast that's needed to obtain its value as a List<Integer>. The other version declares it as a suitably generified Map.Entry and you can obtain values without the cast.
I don't know if this is the actual problem you face with the first of the warnings: I'm mostly just trying to show that you can illustrate the problem without having to post hundreds of lines of code. The (difficult) task of reducing the problem to its essential features is a large part of solving it!
Thanks pbrockway2,
Actually, that first line that you said compiles OK doesn't on my machine. It gives me an error talking about a cast from Object to the Map Entry. I have Java 1.6, could there be something a little different I have to do there?
I'll try to pare down my program here and see if I can get a SSCCE out of it.
Jezzica85
> Actually, that first line that you said compiles OK doesn't on my machine. It gives
> me an error talking about a cast from Object to the Map Entry. I have Java 1.6,
> could there be something a little different I have to do there?
Just as current has to be declared as a generified Map.Entry, so iterator has to be declared as a Iterator<Map.Entry<String,List<Integer>>>.
OK, here's my SSCCE, I think it basically covers all the problems I'm having. Thanks for illustrating how to pare it down--for some reason I thought I needed to preserve the entire program's functionality, silly me!
EDIT: Once I understood what that iterator stuff meant I got the iterators working, thank you! It's the type safety warnings with the TreeMaps that are still throwing me off.
Jezzica85
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class Test {
public static void main( String args[] ) {
try {
TreeMap[] phrasesBySize = new TreeMap[8];
TreeMap<String, List><Integer>> phraseList = new TreeMap<String, List><Integer>>();
for( int i = 0; i < 8; i++ ) {
TreeMap<String, List><Integer>> map = new TreeMap<String, List><Integer>>();
phrasesBySize[i] = map;
}
Iterator splitIterator = phraseList.entrySet().iterator();
while( splitIterator.hasNext() ) {
Map.Entry current = (Map.Entry)splitIterator.next();
// Type safety warning here
ArrayList<Integer> value = (ArrayList<Integer>)current.getValue();
}
// Type safety warning here
TreeMap<String, ArrayList><Integer>> phrases = phrasesBySize[0];
ArrayList<Integer> test = new ArrayList<Integer>();
test.add( 1 );
// Type safety warning here
phrasesBySize[0].put( "testString", test );
} catch(Exception e){
e.printStackTrace();
System.exit(-1);
}
}
}
Message was edited by:
jezzica85
Never mind, I found something else on the forum that I missed before that solved my map problem. Thank you again for your help!Jezzica85
> I found something else on the forum that I missed before that solved my map
> problem.
Do you have a link? - I've been playing around with what the "fine print" page says about arrays where you want the component type to be paramarised, but have come unstuck with Map.Entry. I suppose I could go looking myself... ;)