Converting a HashMap<String, Thing> into a sorted array

Discussion in 'Java' started by qu0ll, Oct 21, 2006.

  1. qu0ll

    qu0ll Guest

    I would like to code a method to convert a particular HashMap into a sorted
    array. This is what I came up with:

    public convert(final HashMap<String, Thing> things)
    {
    Thing[] tArray = new Thing[things.size()];
    Collection<Thing> tCollection = things.values();
    int i = 0;
    for (Thing t : tCollection)
    {
    tArray[i++] = t;
    }
    Arrays.sort(tArray);
    return tArray;
    }

    Well it works but is there a more efficient/elegant way of doing this?
    Also, it would be nice to write it in such a way that it would convert any
    HashMap not just those using Thing. Can anyone assist?

    --
    And loving it,

    qu0ll
    ______________________________________________

    (Replace the "SixFour" with numbers to email)
     
    qu0ll, Oct 21, 2006
    #1
    1. Advertising

  2. qu0ll

    Guest

    qu0ll,

    There are lots of ways to do this depending on your actual goal.

    As a HashMap has keys and values, is your end goal to have an array of
    {something} in the order that the keys are sorted or based on how the
    {something}'s should be ordered on their own?

    If its the later, you probably want to create a Comparator for each
    {something} you want to sort.

    Here is a simple example - not sure if its exactly what you want but
    hopefully it helps.

    /* Begin qu0ll.java */
    import java.util.*;

    public class qu0ll {
    public static void main(String args[]) {
    qu0llSomethingComparator c = new qu0llSomethingComparator();
    qu0llSomething[] myArray = new qu0llSomething[args.length];

    for (int i = 0; i < args.length; i ++) {
    myArray = new qu0llSomething(args);
    }

    Arrays.sort(myArray, c);

    for (qu0llSomething q : myArray) {
    System.out.println(q);
    }
    }
    }
    /* Begin qu0llSomethingComparator.java */
    import java.util.*;

    public class qu0llSomethingComparator implements
    Comparator<qu0llSomething> {
    public int compare(qu0llSomething q1, qu0llSomething q2) {
    // Specialized rules for ordering go here

    if (q1.getLength() < q2.getLength()) {
    return -1;
    }
    else if (q1.getLength() == q2.getLength()) {
    if (q1.hashCode() < q2.hashCode()) {
    return -1;
    }
    else if (q1.hashCode() > q2.hashCode()) {
    return 1;
    }
    else {
    return 0;
    }
    }
    else {
    return 1;
    }
    }

    public boolean equals(Object o) {
    return (o == this);
    }
    }
    /* Begin qu0llSomething.java */
    public class qu0llSomething {
    private String value;

    public qu0llSomething(String value) {
    this.value = value;
    }

    // Will throw NullPointerException if value is null
    public int getLength() {
    return value.length();
    }

    public String getValue() {
    return value;
    }

    public String toString() {
    return getValue();
    }
    }

    --

    Let me know if I can assist further.


    -kavaj

    qu0ll wrote:
    > I would like to code a method to convert a particular HashMap into a sorted
    > array. This is what I came up with:
    >
    > public convert(final HashMap<String, Thing> things)
    > {
    > Thing[] tArray = new Thing[things.size()];
    > Collection<Thing> tCollection = things.values();
    > int i = 0;
    > for (Thing t : tCollection)
    > {
    > tArray[i++] = t;
    > }
    > Arrays.sort(tArray);
    > return tArray;
    > }
    >
    > Well it works but is there a more efficient/elegant way of doing this?
    > Also, it would be nice to write it in such a way that it would convert any
    > HashMap not just those using Thing. Can anyone assist?
    >
    > --
    > And loving it,
    >
    > qu0ll
    > ______________________________________________
    >
    > (Replace the "SixFour" with numbers to email)
     
    , Oct 21, 2006
    #2
    1. Advertising

  3. qu0ll

    Daniel Dyer Guest

    On Sat, 21 Oct 2006 16:25:18 +0100, qu0ll <> wrote:

    > I would like to code a method to convert a particular HashMap into a
    > sorted
    > array. This is what I came up with:
    >
    > public convert(final HashMap<String, Thing> things)
    > {
    > Thing[] tArray = new Thing[things.size()];
    > Collection<Thing> tCollection = things.values();
    > int i = 0;
    > for (Thing t : tCollection)
    > {
    > tArray[i++] = t;
    > }
    > Arrays.sort(tArray);
    > return tArray;
    > }
    >
    > Well it works but is there a more efficient/elegant way of doing this?
    > Also, it would be nice to write it in such a way that it would convert
    > any
    > HashMap not just those using Thing. Can anyone assist?


    There's a more concise way:

    public Thing[] convert(HashMap<String, Thing> things)
    {
    Thing[] tArray = things.values().toArray(new Thing[things.size()]);
    Arrays.sort(tArray);
    return tArray;
    }

    You could use generics to write a version that will work with any Map (not
    just HashMap). The signature would look like this:

    public <T extends Comparable> T[] convert(Map<?, T> things)

    However, generics and arrays don't mix very well so the implementation
    might be a little bit ugly. It's just about impossible to derive the
    correct type of T at runtime in this instance, so this might have to
    weakened to this:

    public Object[] convert(Map<?, ? extends Comparable> things)

    Consider using Lists instead of arrays.

    Dan.

    --
    Daniel Dyer
    http://www.uncommons.org
     
    Daniel Dyer, Oct 21, 2006
    #3
  4. qu0ll

    Guest

    qu0ll,

    There are lots of ways to do this depending on your actual goal.

    As a HashMap has keys and values, is your end goal to have an array of
    {something} in the order that the keys are sorted or based on how the
    {something}'s should be ordered on their own?

    If its the later, you probably want to create a Comparator for each
    {something} you want to sort.

    Here is a simple example - not sure if its exactly what you want but
    hopefully it helps.

    /* Begin qu0ll.java */
    import java.util.*;

    public class qu0ll {
    public static void main(String args[]) {
    qu0llSomethingComparator c = new qu0llSomethingComparator();
    qu0llSomething[] myArray = new qu0llSomething[args.length];

    for (int i = 0; i < args.length; i ++) {
    myArray = new qu0llSomething(args);
    }

    Arrays.sort(myArray, c);

    for (qu0llSomething q : myArray) {
    System.out.println(q);
    }
    }
    }
    /* Begin qu0llSomethingComparator.java */
    import java.util.*;

    public class qu0llSomethingComparator implements
    Comparator<qu0llSomething> {
    public int compare(qu0llSomething q1, qu0llSomething q2) {
    // Specialized rules for ordering go here

    if (q1.getLength() < q2.getLength()) {
    return -1;
    }
    else if (q1.getLength() == q2.getLength()) {
    if (q1.hashCode() < q2.hashCode()) {
    return -1;
    }
    else if (q1.hashCode() > q2.hashCode()) {
    return 1;
    }
    else {
    return 0;
    }
    }
    else {
    return 1;
    }
    }

    public boolean equals(Object o) {
    return (o == this);
    }
    }
    /* Begin qu0llSomething.java */
    public class qu0llSomething {
    private String value;

    public qu0llSomething(String value) {
    this.value = value;
    }

    // Will throw NullPointerException if value is null
    public int getLength() {
    return value.length();
    }

    public String getValue() {
    return value;
    }

    public String toString() {
    return getValue();
    }
    }

    --

    Let me know if I can assist further.


    -kavaj

    qu0ll wrote:
    > I would like to code a method to convert a particular HashMap into a sorted
    > array. This is what I came up with:
    >
    > public convert(final HashMap<String, Thing> things)
    > {
    > Thing[] tArray = new Thing[things.size()];
    > Collection<Thing> tCollection = things.values();
    > int i = 0;
    > for (Thing t : tCollection)
    > {
    > tArray[i++] = t;
    > }
    > Arrays.sort(tArray);
    > return tArray;
    > }
    >
    > Well it works but is there a more efficient/elegant way of doing this?
    > Also, it would be nice to write it in such a way that it would convert any
    > HashMap not just those using Thing. Can anyone assist?
    >
    > --
    > And loving it,
    >
    > qu0ll
    > ______________________________________________
    >
    > (Replace the "SixFour" with numbers to email)
     
    , Oct 21, 2006
    #4
  5. qu0ll

    Lew Guest

    Daniel Dyer wrote:
    > There's a more concise way:
    >
    > public Thing[] convert(HashMap<String, Thing> things)
    > {
    > Thing[] tArray = things.values().toArray(new Thing[things.size()]);
    > Arrays.sort(tArray);
    > return tArray;
    > }


    Another way to express the toArray() call is
    Thing [] tArray = things.values().toArray( new Thing [0] );

    If this is called often, you can create a static final:
    private static final Thing [] ARRAY_TEMPLATE = new Thing [0];

    that is used in the call:
    Thing [] tArray = things.values().toArray( ARRAY_TEMPLATE );

    Whether this provides any benefit is questionable in the particular example,
    but it's good to know your alternatives.

    - Lew
     
    Lew, Oct 22, 2006
    #5
  6. qu0ll

    Daniel Dyer Guest

    On Sun, 22 Oct 2006 00:51:59 +0100, Lew <> wrote:

    > Daniel Dyer wrote:
    >> There's a more concise way:
    >> public Thing[] convert(HashMap<String, Thing> things)
    >> {
    >> Thing[] tArray = things.values().toArray(new
    >> Thing[things.size()]);
    >> Arrays.sort(tArray);
    >> return tArray;
    >> }

    >
    > Another way to express the toArray() call is
    > Thing [] tArray = things.values().toArray( new Thing [0] );
    >
    > If this is called often, you can create a static final:
    > private static final Thing [] ARRAY_TEMPLATE = new Thing [0];
    >
    > that is used in the call:
    > Thing [] tArray = things.values().toArray( ARRAY_TEMPLATE );
    >
    > Whether this provides any benefit is questionable in the particular
    > example, but it's good to know your alternatives.


    The version I posted will copy the contents into the array that is passed
    in. With your version, a new array will be created since the argument
    array is not big enough (unless the map happens to be empty).

    http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html#toArray(T[])

    "If the collection fits in the specified array, it is returned therein.
    Otherwise, a new array is allocated with the runtime type of the specified
    array and the size of this collection."

    This is not the neatest method in the API.

    Dan.

    --
    Daniel Dyer
    http://www.uncommons.org
     
    Daniel Dyer, Oct 22, 2006
    #6
  7. qu0ll

    Lew Guest

    >> Daniel Dyer wrote:
    >>> There's a more concise way:
    >>> public Thing[] convert(HashMap<String, Thing> things)
    >>> {
    >>> Thing[] tArray = things.values().toArray(new Thing[things.size()]);
    >>> Arrays.sort(tArray);
    >>> return tArray;
    >>> }


    > On Sun, 22 Oct 2006 00:51:59 +0100, Lew <> wrote:
    >> Another way to express the toArray() call is
    >> Thing [] tArray = things.values().toArray( new Thing [0] );
    >>


    Daniel Dyer wrote:
    > The version I posted will copy the contents into the array that is
    > passed in. With your version, a new array will be created since the
    > argument array is not big enough (unless the map happens to be empty).
    >
    > http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html#toArray(T[])
    >
    >
    > "If the collection fits in the specified array, it is returned therein.
    > Otherwise, a new array is allocated with the runtime type of the
    > specified array and the size of this collection."
    >
    > Dan.
    >
    > --Daniel Dyer
    > http://www.uncommons.org


    That's exactly right.

    In
    Thing[] tArray = things.values().toArray(new Thing[things.size()]);

    the "new" of the returned array is explicit and done by the client code.

    In
    public static final Thing [] ARRAY_TEMPLATE = new Thing [0];
    ...
    Thing [] tArray = things.values().toArray( ARRAY_TEMPLATE );

    the "new" of the returned array is hidden in the toArray() call.

    > This is not the neatest method in the API.


    I guess the reason for the second idiom is convenience for the programmer.

    - Lew
     
    Lew, Oct 22, 2006
    #7
  8. qu0ll

    Guest

    There has a complete example at following link

    http://www.developerzone.biz/index.php?option=com_content&task=view&id=90&Itemid=36

    Hope it helps
    qu0ll wrote:
    > I would like to code a method to convert a particular HashMap into a sorted
    > array. This is what I came up with:
    >
    > public convert(final HashMap<String, Thing> things)
    > {
    > Thing[] tArray = new Thing[things.size()];
    > Collection<Thing> tCollection = things.values();
    > int i = 0;
    > for (Thing t : tCollection)
    > {
    > tArray[i++] = t;
    > }
    > Arrays.sort(tArray);
    > return tArray;
    > }
    >
    > Well it works but is there a more efficient/elegant way of doing this?
    > Also, it would be nice to write it in such a way that it would convert any
    > HashMap not just those using Thing. Can anyone assist?
    >
    > --
    > And loving it,
    >
    > qu0ll
    > ______________________________________________
    >
    > (Replace the "SixFour" with numbers to email)
     
    , Oct 22, 2006
    #8
  9. Lew wrote:
    ....
    > In
    > Thing[] tArray = things.values().toArray(new Thing[things.size()]);
    >
    > the "new" of the returned array is explicit and done by the client code.
    >
    > In
    > public static final Thing [] ARRAY_TEMPLATE = new Thing [0];
    > ...
    > Thing [] tArray = things.values().toArray( ARRAY_TEMPLATE );
    >
    > the "new" of the returned array is hidden in the toArray() call.
    >
    > > This is not the neatest method in the API.

    >
    > I guess the reason for the second idiom is convenience for the programmer.
    >
    > - Lew


    I think the second idiom also has an advantage when depending on a
    synchronized list for your synchronization. Even if the list is
    shrinking, there is no way to end up with a larger array than is needed.

    Patricia
     
    Patricia Shanahan, Oct 22, 2006
    #9
    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. Miguel Angel
    Replies:
    9
    Views:
    13,881
    Christian Kaufhold
    Apr 15, 2004
  2. Vince Darley
    Replies:
    4
    Views:
    4,437
    emilchacko
    Mar 2, 2010
  3. MackS
    Replies:
    5
    Views:
    2,276
    Bengt Richter
    May 15, 2005
  4. Rakesh
    Replies:
    10
    Views:
    12,185
    Mike Schilling
    Apr 8, 2008
  5. Zam
    Replies:
    1
    Views:
    244
    Mark Schupp
    Mar 14, 2005
Loading...

Share This Page