Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2006

Tip: Looking for answers? Try searching our database.

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

Thread view: 
qu0ll - 21 Oct 2006 16:25 GMT
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?

Signature

And loving it,

qu0ll
______________________________________________
qu0llSixFour@gmail.com
(Replace the "SixFour" with numbers to email)

java@starflag.net - 21 Oct 2006 17:15 GMT
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[i] = new qu0llSomething(args[i]);
   }

   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

> I would like to code a method to convert a particular HashMap into a sorted
> array.  This is what I came up with:
[quoted text clipped - 23 lines]
> qu0llSixFour@gmail.com
> (Replace the "SixFour" with numbers to email)
Daniel Dyer - 21 Oct 2006 17:33 GMT
> I would like to code a method to convert a particular HashMap into a  
> sorted
[quoted text clipped - 17 lines]
> 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.

Signature

Daniel Dyer
http://www.uncommons.org

Lew - 22 Oct 2006 00:51 GMT
> There's a more concise way:
>
[quoted text clipped - 4 lines]
>         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
Daniel Dyer - 22 Oct 2006 01:15 GMT
>> There's a more concise way:
>>      public Thing[] convert(HashMap<String, Thing> things)
[quoted text clipped - 16 lines]
> 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.

Signature

Daniel Dyer
http://www.uncommons.org

Lew - 22 Oct 2006 01:47 GMT
>>> There's a more concise way:
>>>      public Thing[] convert(HashMap<String, Thing> things)
[quoted text clipped - 3 lines]
>>>         return tArray;
>>>     }

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

> 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
[quoted text clipped - 10 lines]
> --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
Patricia Shanahan - 22 Oct 2006 14:46 GMT
...
> In
>   Thing[] tArray = things.values().toArray(new Thing[things.size()]);
[quoted text clipped - 13 lines]
>
> - 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
java@starflag.net - 21 Oct 2006 17:38 GMT
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[i] = new qu0llSomething(args[i]);
   }

   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

> I would like to code a method to convert a particular HashMap into a sorted
> array.  This is what I came up with:
[quoted text clipped - 23 lines]
> qu0llSixFour@gmail.com
> (Replace the "SixFour" with numbers to email)
jvsoft.org@gmail.com - 22 Oct 2006 10:01 GMT
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
> I would like to code a method to convert a particular HashMap into a sorted
> array.  This is what I came up with:
[quoted text clipped - 23 lines]
> qu0llSixFour@gmail.com
> (Replace the "SixFour" with numbers to email)


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.