Java Forum / First Aid / September 2005
convert HashMap to ArrayList
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 MagazinesGet 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 ...
|
|
|