4

Why when typing a new variable with an existing variable is typing all or nothing?

For example, say I have a variable data whose type is List<Map<String, ArrayList<String>>>, and I want to pass its value to tempData. Why when deciding tempData's type am I limited to List or List<Map<String, ArrayList<String>>>?

If I only want to interact with a certain "level" of data, say the Map level, how do I just jump to there? For example why can't I List<Map> tempData = data?

I have searched my textbook and this site, but I can't find anywhere that explains why this is. Is there something that could go wrong if we were allowed to "partially-type"?

I know I can just strongly type tempData to begin with, but I am curious as to why Java has an all or nothing approach.

FreakyDan
  • 559
  • 1
  • 7
  • 24
  • 2
    Because Java doesn't work that way. Also, those are [raw types](http://stackoverflow.com/q/2770321/2970947). Don't do that. – Elliott Frisch Aug 13 '14 at 17:50
  • 1
    `List>>` should be `List>>`. Code against the interface, not the implementation. – David Conrad Aug 13 '14 at 18:08
  • @ElliottFrisch Actually, Java does work that way, it just requires specific syntax (see below). :) – Markus A. Aug 13 '14 at 19:27
  • 1
    @DavidConrad Thank you for pointing that out, I hadn't thought about that, I never was using ArrayList specific methods and have since cleaned it up. Post relating to your comment for others interested: [Why are variables declared with their interface name in java](http://stackoverflow.com/questions/1484445/why-are-variables-declared-with-their-interface-name-in-java) – FreakyDan Aug 13 '14 at 21:54

2 Answers2

10

Actually, you can: The trick is to use ? and ? extends in your declarations. The following works and gets progressively more specific:

List<Map<String, ArrayList<String>>> data = null; // Replace null with content

Object temp1 = data;
List<?> temp2 = data;
List<? extends Map<?, ?>> temp3 = data;
List<? extends Map<String, ?>> temp4 = data;
List<? extends Map<String, ? extends ArrayList<?>>> temp5 = data;
List<Map<String, ArrayList<String>>> temp6 = data;
Markus A.
  • 12,349
  • 8
  • 52
  • 116
1

You can use java generics in order to replace types that you don't need full type information on. Similar to this

public static < K, V > List< Map< K, V > > test( List< Map< K, V > > list ) {
    return list;
}

This will let you work with both the list and map type fully without knowing what the key and value types are for the map, but you can not operate on the types contained within the map without more type information.

Smith_61
  • 2,078
  • 12
  • 12