I have this method to transform a List
to a Map
using one of the properties of the elements of the list:
For short it looks like this:
private Map<String, List<Diagnostic<? extends JavaFileObject>>> toMap( List<Diagnostic<? extends JavaFileObject>> diagnostics ) {
Map<String, List<Diagnostic<? extends JavaFileObject>>> result = new HashMap<String, List<Diagnostic<? extends JavaFileObject>>>();
for ( Diagnostic<? extends JavaFileObject> d : diagnostics ) {
List<Diagnostic<? extends JavaFileObject>> list = null;
if ( !result.containsKey( d.getCode() ) ) {
list = new ArrayList<Diagnostic<? extends JavaFileObject>>();
result.put( d.getCode(), list );
} else {
list = result.get( d.getCode() );
}
assert list != null;
list.add( d );
}
return result;
}
Yiack!..
I like genercis a lot, I use java prior to them and I don't want to go back to the cast everything era, but when a generic contains as element a generic element it self, things go messy.
I know in Java1.7 we will be able to use the "diamond" operator, but there should be another way.
This is what it would look like in a non-generic version:
private Map toMap( List diagnostics ) {
Map result = new HashMap();
for( Object o : diagnostics ) {
Diagnostic d = ( Diagnostic ) o;
List list = null;
if( !result.containsKey( d.getCode() ) ) {
list = new ArrayList();
result.put( d.getCode() , list );
} else {
list = result.get( d.getCode() );
}
assert list != null;
list.add( d );
}
return result;
}
Approximately, I didn't try to compile it.
How other languages handle this? C# for instance?, Scala? I liked a lot the way SML or Haskell do handle, but something I think too much magic may hurt ( but this is subjective of course )
Is there a workaround for this?
You define one type parameter named T
. Then you can use T
within your generic like this:
private <T extends JavaFileObject> Map<String, List<Diagnostic<T>> toMap(List<Diagnostic<T> diagnostics) {
Map<String, List<Diagnostic<T>> result = new HashMap<String, List<Diagnostic<T>>();
for (Diagnostic<T> d : diagnostics ) {
List<Diagnostic<T>> list = null;
if ( !result.containsKey(d.getCode())) {
list = new ArrayList<Diagnostic<T>>();
result.put( d.getCode(), list );
} else {
list = result.get( d.getCode() );
}
assert list != null;
list.add( d );
}
return result;
}
Above you will see the type parameter defined as <T extends JavaFileObject>
and you reuse T everywhere you need to. This will make it a bit cleaner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With