Generics, damned if you do, damned if you don't

Discussion in 'Java' started by Roedy Green, Jul 2, 2007.

  1. Roedy Green

    Roedy Green Guest

    Consider this code snippet:

    // create a new HashMap
    HashMap<String, Integer> h = new HashMap<String, Integer>(149, .75f);
    ....

    // extract key/value pair entries into an array
    Set<Map.Entry<String, String>> justEntries = h.entrySet();
    Map.Entry<String, String>[] keyValuePairs =
    justEntries.toArray ( new Map.Entry[justEntries.size()] );

    This generates an "unchecked conversion" warning.

    If put in the type like this:

    // extract key/value pair entries into an array
    Set<Map.Entry<String, String>> justEntries = h.entrySet();
    Map.Entry<String, String>[] keyValuePairs =
    justEntries.toArray ( new
    Map.Entry<String,String>[justEntries.size()] );

    I get an "generic array conversion error"

    How are you supposed to code that.

    Map.Entry is an interface and HashMap.Entry is not public. However
    the problem appears to be general -- even creating arrays af HashMaps.
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Jul 2, 2007
    #1
    1. Advertising

  2. On Mon, 02 Jul 2007 21:01:05 +0000, Roedy Green wrote:

    > Consider this code snippet:
    >
    > // create a new HashMap
    > HashMap<String, Integer> h = new HashMap<String, Integer>(149, .75f);
    > ...
    >
    > // extract key/value pair entries into an array
    > Set<Map.Entry<String, String>> justEntries = h.entrySet();

    Don't you mean Map.Entry<String, Integer> ?
    > Map.Entry<String, String>[] keyValuePairs = justEntries.toArray
    > ( new Map.Entry[justEntries.size()] );
    >
    > This generates an "unchecked conversion" warning.
    > How are you supposed to code that.


    Go with the first one, bite the bullet, and add a @SuppressWarnings
    ("unchecked") in. Arrays + generics don't mix. In the Sun generics FAQ,
    there's a part about why there are such problems with generic arrays
    (simple answer: type erasure).
     
    Joshua Cranmer, Jul 2, 2007
    #2
    1. Advertising

  3. Roedy Green

    Eric Sosman Guest

    Roedy Green wrote On 07/02/07 17:01,:
    > Consider this code snippet:
    >
    > // create a new HashMap
    > HashMap<String, Integer> h = new HashMap<String, Integer>(149, .75f);
    > ...
    >
    > // extract key/value pair entries into an array
    > Set<Map.Entry<String, String>> justEntries = h.entrySet();
    > Map.Entry<String, String>[] keyValuePairs =
    > justEntries.toArray ( new Map.Entry[justEntries.size()] );
    >
    > This generates an "unchecked conversion" warning.
    >
    > If put in the type like this:
    >
    > // extract key/value pair entries into an array
    > Set<Map.Entry<String, String>> justEntries = h.entrySet();
    > Map.Entry<String, String>[] keyValuePairs =
    > justEntries.toArray ( new
    > Map.Entry<String,String>[justEntries.size()] );
    >
    > I get an "generic array conversion error"
    >
    > How are you supposed to code that.
    >
    > Map.Entry is an interface and HashMap.Entry is not public. However
    > the problem appears to be general -- even creating arrays af HashMaps.


    You may find

    http://www.angelikalanger.com/Gener...ncrete instantiation of a parameterized type?

    and

    http://www.angelikalanger.com/Gener...w do I generically create objects and arrays?

    helpful.

    --
     
    Eric Sosman, Jul 2, 2007
    #3
  4. Roedy Green

    Bart Guest

    > ...
    > I get an "generic array conversion error"
    >
    > How are you supposed to code that.
    > ...


    AFAIK, there's no "generics" way to do this, suppressing it is the
    only way unfrtunatelly, I guess.


    > ...
    > even creating arrays af HashMaps.
    > ...


    You mean like this?

    HashMap<String, Integer> h = new HashMap<String, Integer>();
    String[] keys = h.keySet().toArray(new String[]{});
    Integer[] values = h.values().toArray(new Integer[]{});

    which gives no compiler errors/warnings (with Eclpise's compiler, that
    is).

    Regards,
    Bart.
     
    Bart, Jul 2, 2007
    #4
  5. Roedy Green

    Tom Hawtin Guest

    Roedy Green wrote:
    >
    > // create a new HashMap
    > HashMap<String, Integer> h = new HashMap<String, Integer>(149, .75f);
    > ...
    >
    > // extract key/value pair entries into an array
    > Set<Map.Entry<String, String>> justEntries = h.entrySet();
    > Map.Entry<String, String>[] keyValuePairs =
    > justEntries.toArray ( new Map.Entry[justEntries.size()] );


    > Map.Entry is an interface and HashMap.Entry is not public. However
    > the problem appears to be general -- even creating arrays af HashMaps.



    Avoid arrays of reference types. We now have the much nicer generic List.

    So the code becomes:

    List<Map.Entry<String,String>> entries =
    new java.util.ArrayList<Map.Entry<String,String>>(
    map.entrySet();
    );

    Tom Hawtin
     
    Tom Hawtin, Jul 2, 2007
    #5
  6. Roedy Green

    Roedy Green Guest

    Roedy Green, Jul 2, 2007
    #6
  7. Roedy Green

    Roedy Green Guest

    On Mon, 02 Jul 2007 21:37:11 -0000, Bart <> wrote,
    quoted or indirectly quoted someone who said :

    >
    >You mean like this?
    >
    > HashMap<String, Integer> h = new HashMap<String, Integer>();
    > String[] keys = h.keySet().toArray(new String[]{});
    > Integer[] values = h.values().toArray(new Integer[]{});
    >
    >which gives no compiler errors/warnings (with Eclpise's compiler, that
    >is).

    no. You don't allocate any arrays of generics there. See
    http://mindprod.com/jgloss/hashmap.html
    for sample code.
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Jul 3, 2007
    #7
  8. Roedy Green

    Bart Guest

    > > ...
    > > HashMap<String, Integer> h = new HashMap<String, Integer>();
    > > String[] keys = h.keySet().toArray(new String[]{});
    > > Integer[] values = h.values().toArray(new Integer[]{});

    >
    > > which gives no compiler errors/warnings (with Eclpise's compiler, that
    > > is).

    >
    > no. You don't allocate any arrays of generics there.


    I don't get your point. What IS it that I do then?


    > See http://mindprod.com/jgloss/hashmap.html for sample code.
    > ...


    >From you webpage:


    // extract the keys into an array
    Set<String> justKeys = h.keySet();
    // Use toArray that takes an empty array,
    // otherwise we end up with a useless Object[] instead of a
    String[].
    String[] keys = justKeys.toArray( new
    String[justKeys.size()] );

    How is the above different than the code I posted?

    Regards,
    Bart.
     
    Bart, Jul 3, 2007
    #8
  9. Roedy Green

    Bart Guest

    > ...
    > How is the above different than the code I posted?
    > ...


    Besides the fact that you explicitly say how many elements the newly
    created array should have, whereas I leave that responsibility to
    Arrays' toString() method, of course.
     
    Bart, Jul 3, 2007
    #9
  10. Roedy Green

    Roedy Green Guest

    On Tue, 03 Jul 2007 16:26:05 -0000, Bart <> wrote,
    quoted or indirectly quoted someone who said :

    >>From you webpage:

    >
    > // extract the keys into an array
    > Set<String> justKeys = h.keySet();
    > // Use toArray that takes an empty array,
    > // otherwise we end up with a useless Object[] instead of a
    >String[].
    > String[] keys = justKeys.toArray( new
    >String[justKeys.size()] );
    >
    >How is the above different than the code I posted?


    It is not different. It just not the problem we were talking about,
    arrays of generics. Look in the code sample about autoboxing.
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Jul 3, 2007
    #10
  11. Roedy Green

    Roedy Green Guest

    On Tue, 03 Jul 2007 20:20:03 GMT, Roedy Green
    <> wrote, quoted or indirectly quoted
    someone who said :

    >It is not different. It just not the problem we were talking about,
    >arrays of generics. Look in the code sample about autoboxing.


    The code you quoted is an array of ordinary Strings, not an array of
    generics. The problem comes here when you try to allocate an array of
    generics:

    // extract key/value pair entries into an array
    Set<Map.Entry<String, Integer>> justEntries =
    h.entrySet();
    // Infuriatingly, this generates an unchecked conversion
    warning message.
    Map.Entry<String, Integer>[] keyValuePairs =
    justEntries.toArray( new
    Map.Entry[justEntries.size()] );
    // Type erasure won't let us say:
    // Map.Entry<String, Integer>[] keyValuePairs =
    // justEntries.toArray ( new
    // Map.Entry<String,Integer>[justEntries.size()] );

    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Jul 3, 2007
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nicolas

    Damned Container....

    Nicolas, Aug 3, 2003, in forum: Java
    Replies:
    2
    Views:
    435
    Wayne
    Aug 4, 2003
  2. Luke Webber

    Too damned many jar files

    Luke Webber, Jun 7, 2006, in forum: Java
    Replies:
    9
    Views:
    497
    Dale King
    Jun 10, 2006
  3. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    802
    Malcolm
    Jun 24, 2006
  4. Jason
    Replies:
    0
    Views:
    219
    Jason
    Jul 6, 2004
  5. Bob Martin
    Replies:
    0
    Views:
    96
    Bob Martin
    Jan 10, 2014
Loading...

Share This Page