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 / First Aid / September 2005

Tip: Looking for answers? Try searching our database.

convert HashMap to ArrayList

Thread view: 
Wizumwalt@gmail.com - 07 Sep 2005 20:00 GMT
I'm trying to get faster performance in looping through my HashMap so
I'm converting this HashMap to an ArrayList, but I've got something
wrong on the line 'toArray' that I don't understand. What's the correct
way to do this?

Any help much appreciated.

--

HashMap elements; // holds type 'Element' objects
...

Iterator iter = elements.keySet().iterator();
ArrayList myArray = elements.toArray(new Element[elements.size()]);

while(eKeyIter.hasNext()) {
   Element elem = (Element) elemArray.get(eKeyIter.next());
   elem.doStuff();    
}
Stefan Schulz - 07 Sep 2005 20:13 GMT
> I'm trying to get faster performance in looping through my HashMap so
> I'm converting this HashMap to an ArrayList, but I've got something
> wrong on the line 'toArray' that I don't understand. What's the correct
> way to do this?
>
> Any help much appreciated.

the map interface does not declare a toArray method (which would make
little sense, since it stores pairs of values). You probably mean

elements.values().toArray()

Signature

You can't run away forever,
But there's nothing wrong with getting a good head start.
          --- Jim Steinman, "Rock and Roll Dreams Come Through"
         

Wizumwalt@gmail.com - 07 Sep 2005 20:24 GMT
I did that, and it tells me that it found java.lang.Object[] and
required java.util.ArrayList. I thought by adding the
Element[elements.size()] as the arg to toArray(), it would pick up the
right toArrary, but this doesn't seem to do it.

incompatible types
[javac] found   : java.lang.Object[]
[javac] required: java.util.ArrayList
[javac] ArrayList elemArray = elements.values().toArray(new
Element[elements.size()]);
[javac] ^

//
ArrayList elemArray = elements.values().toArray(new
Element[elements.size()]);
Stefan Schulz - 08 Sep 2005 09:30 GMT
> I did that, and it tells me that it found java.lang.Object[] and
> required java.util.ArrayList. I thought by adding the
[quoted text clipped - 11 lines]
> ArrayList elemArray = elements.values().toArray(new
> Element[elements.size()]);

Well, lets have a look at that. Your code is equivalent to

Object [] foo = elements.values().toArray(new Element[elements.size]);
ArrayList elemArray = foo;

Notice anything? ;) While an ArrayList uses an Object [] internally, it
hardly is one.

Signature

You can't run away forever,
But there's nothing wrong with getting a good head start.
          --- Jim Steinman, "Rock and Roll Dreams Come Through"
         

Thomas Hawtin - 07 Sep 2005 20:17 GMT
> I'm trying to get faster performance in looping through my HashMap so
> I'm converting this HashMap to an ArrayList, but I've got something
> wrong on the line 'toArray' that I don't understand. What's the correct
> way to do this?

If you are only looping through it once, then converting to an ArrayList
or array isn't going to help.

> HashMap elements; // holds type 'Element' objects

You mean that the value is of type Element. How about the key?

> Iterator iter = elements.keySet().iterator();
> ArrayList myArray = elements.toArray(new Element[elements.size()]);
[quoted text clipped - 3 lines]
>     elem.doStuff();    
> }

I can't quite see what you are trying to do. But here's some options.

Loop through each key:

for (
    Iterator/*<Key>*/ iter = map.keySet();
    iter.hasNext();
) {
    Key key = (Key)iter.next();
    // ... do stuff with key ...
}

Loop through each value:

for (
    Iterator/*<Value>*/ iter = map.values();
    iter.hasNext();
) {
    Value value = (Value)iter.next();
    // ... do stuff with value ...
}

Loop through each (key, value) pair:

for (
    Iterator/*<Map.Entry<Key,Value>>*/ iter = map.entrySet();
    iter.hasNext();
) {
    Map.Entry<Key,Value> entry = (Map.Entry)iter.next();
    Key key = (Key)entry.getKey();
    Value value = (Value)entry.getValue();
    // ... do stuff with key and value ...
}

Loop through each value lots of times:

Collection valuesCollection = map.values();
int num = valuesCollection.size();
Value[] values = new Value[num];
valuesCollection.toArray(values);

for (...) {
    for (int ct=0; ct<num; ++ct) {
        Value value = values[ct];
        // ... do stuff with value ...
    }
}

I've put the generics in comments. I highly recommend using JDK 5.0.
Generics makes things much clearer. Whether you like them or not you'd
better get used to them.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Wizumwalt@gmail.com - 07 Sep 2005 20:41 GMT
When I tried this, I got this error below which seems correct. How is
this supposed to work if the HashMap elements.values() returns a
Collection, but requires an Iterator?

MyProg.java:102: incompatible types
   [javac] found   : java.util.Collection
   [javac] required: java.util.Iterator
   [javac] for (Iterator/*<Element>*/ iter = elements.values();
iter.hasNext();) {
   [javac] ^

---- example given ---
Loop through each value:

for (Iterator/*<Value>*/ iter = map.values(); iter.hasNext(); ) {
    Value value = (Value)iter.next();
    // ... do stuff with value ...
}
Wizumwalt@gmail.com - 07 Sep 2005 20:50 GMT
Never mind, I think it was a typo, I just add values().iterator() onto
the end of it.
Thomas Hawtin - 07 Sep 2005 22:08 GMT
> Never mind, I think it was a typo, I just add values().iterator() onto
> the end of it.

Yup, sorry. Usual disclaimer #1: code typed straight into Thunderbird.

Just to be confusing, Hashtable returns Enumerations for equivalent
operations.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Thomas G. Marshall - 09 Sep 2005 16:16 GMT
Thomas Hawtin coughed up:
>> I'm trying to get faster performance in looping through my HashMap so
>> I'm converting this HashMap to an ArrayList, but I've got something
[quoted text clipped - 3 lines]
> If you are only looping through it once, then converting to an
> ArrayList or array isn't going to help.

This depends entirely upon what he is attempting.  He may be trying to save
a cache copy around for a moment where he *really* needs to read it quickly.

Obvious issues, mostly hit upon already:

1. A HashMap is a bunch of object pairs.  This does not map well to
ordinalities.
2. He needs to better define if what he needs is an arraylist at all.
2b. He may actually need an array.
2c. He may actually not be understanding his requirements and need none of
this.
3. (as above) he may need this as a means of executing something quickly at
a particular moment in time.

Signature

"I don't want FOP, God dammit!  I'm a DAPPER DAN MAN!"

Roedy Green - 10 Sep 2005 07:23 GMT
On Fri, 09 Sep 2005 15:16:46 GMT, "Thomas G. Marshall"
<tgm2tothe10thpower@replacetextwithnumber.hotmail.com> wrote or quoted

>2c. He may actually not be understanding his requirements and need none of
>this.

I think this is closest to the actuality. He wants his program to go
faster, and heard that ArrayLists are faster than HashMaps and naively
hoped that an export would help.

If we saw some real code we could figure out what the bottleneck
really is and suggest some things to fix it.

Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Wizumwalt@gmail.com - 12 Sep 2005 18:53 GMT
Well, I haven't posted any code yet till I run it through a profiler
which was a great suggestion from a recent post. So I'm going to do
that first, and if that doesn't show me anything, I'll certainly bring
up the code.

Turns out, just trying to make my project a valid eclipse java project
is the biggest challenge of my app so far. Then once that's done, I can
add free profiler into eclipse and check it out.

Thanks though.
Thomas G. Marshall - 13 Sep 2005 00:26 GMT
Wizumwalt@gmail.com coughed up:

...[rip]...

> Turns out, just trying to make my project a valid eclipse java project
> is the biggest challenge of my app so far.

Not entirely sure of what you mean by "valid", but eclipse-confusion has
been discussed here an awful lot.  There are a great many people who just
cannot get that ide to behave.  I'm still one of them I think, though lately
I've managed to figure out enough of its counter-intuitive quirks to develop
ok.

...[rip]...

Signature

"Well, ain't this place a geographical oddity!
Two weeks from everywhere!"

Oliver Wong - 07 Sep 2005 20:26 GMT
> I'm trying to get faster performance in looping through my HashMap so
> I'm converting this HashMap to an ArrayList, but I've got something
> wrong on the line 'toArray' that I don't understand. What's the correct
> way to do this?

   1) toArray() returns an array, not an ArrayList.
   2) Why not just get an iterator from the HashMap?

   - Oliver
Wizumwalt@gmail.com - 07 Sep 2005 20:44 GMT
Initially I thought I would be going through the Map several times and
wanting to set my "pointer" or current value to different places in the
map.

I'm really just trying to find ways to speed this up anyways I can,
I've got to cut off a lot of time from this data processing which I
know isn't in my looping throught the list, but ... just looking for
anything I can to speed it up.
Oliver Wong - 07 Sep 2005 20:52 GMT
> Initially I thought I would be going through the Map several times and
> wanting to set my "pointer" or current value to different places in the
> map.

   Okay, but did you understand the first point that toArray returns an
array and not an ArrayList? i.e. this code is not valid:

<code>
ArrayList myArrayList = someMap.toArray();
</code>

   Why don't you store the results of toArray in an array instead of in an
ArrayList?

> I'm really just trying to find ways to speed this up anyways I can,
> I've got to cut off a lot of time from this data processing which I
> know isn't in my looping throught the list, but ... just looking for
> anything I can to speed it up.

   As for speeding this up, why? Does it take more than 2 hours to run, and
you want it to run in under 1 hour? Do you know for sure that this is the
source of the slow down?

   The point I'm getting at is that it's generally a bad idea to optimize
prematurely, so I want to make sure you have a good reason for starting to
optimize before helping you to actually optimize the code.

   - Oliver
Wizumwalt@gmail.com - 07 Sep 2005 21:26 GMT
>     Okay, but did you understand the first point that toArray returns an
> array and not an ArrayList? i.e. this code is not valid:

Yeah, I think I now understand that.

> > I'm really just trying to find ways to speed this up anyways I can,
> > I've got to cut off a lot of time from this data processing which I
[quoted text clipped - 4 lines]
> you want it to run in under 1 hour? Do you know for sure that this is the
> source of the slow down?

I've posted my optimization problem in this post here since I couldn't
find a way to cut down on the time. I think it's elsewhere and not my
loop, possibly my allocates.

http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/918c2
5da799889ec/1df6b3d42674a5f5#1df6b3d42674a5f5

Roedy Green - 09 Sep 2005 05:42 GMT
>I've posted my optimization problem in this post here since I couldn't
>find a way to cut down on the time. I think it's elsewhere and not my
>loop, possibly my allocates.

To track more precisely where the time is going see
http://mindprod.com/jgloss/profiler.html
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Roedy Green - 07 Sep 2005 23:36 GMT
>but I've got something
>wrong on the line 'toArray'

A  compile error?  An exception? an unexpected result?

This is like  an assembly line medical clinic.  You need to be more
specific than saying "I don't feel well".  Where does it hurt, when?
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Roedy Green - 07 Sep 2005 23:38 GMT
>'Element'
Is this your own class?  Are you using it as key or data for your
HashMap?
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Roedy Green - 09 Sep 2005 04:09 GMT
>I'm trying to get faster performance in looping through my HashMap so
>I'm converting this HashMap to an ArrayList, but I've got something
>wrong on the line 'toArray' that I don't understand. What's the correct
>way to do this?

a HashMap Iterator is going to be pretty quick.  All it does it loop
through the internal HashMap array chasing the chains and avoiding the
empty slots. It is not doing a keyed lookup of each element, computing
HashCodes or the like.

If you don't need the lookup, create an ArrayList in the first place.

If you need to iterate repeatedly, with no changes to the data, export
an array.

If you only iterate a few times it won't pay for the overhead where
"few" is determined by experiment.

If you make changes to the HashMap after you export, you now have the
problem your array/ArrayList is out of date.  You would either have to
change it too or regenerate it.

Element[] elts = hashMap.values().toArray( new Element[ hashMap.size()
] );
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.



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.