Converting ColdFusion Arrays to Java Iterators
I have been working with Reactor for several months now and have grown fond of using iterators as collections of children objects. I never looked at the voodoo magic under the covers that makes that happen in the Reactor core files, but with a little playing around and testing today I realized it might not be so magic afterall. I created a CFC that accepted an array as an argument, then returned that array’s iterator() method. It is plainly obvious by looking at the code, but I just never knew you could do this. For anyone interested, here is the source of my test:
IteratorTest.cfc
<cffunction name=”init”>
<cfreturn this />
</cffunction>
<cffunction name=”returnIterator” returntype=”any”>
<cfargument name=”MyArray” type=”array” required=”true” />
<cfreturn arguments.MyArray.iterator() />
</cffunction>
</cfcomponent>
IteratorTest.cfm
<cfscript>
IteratorTest = CreateObject(“component”,”IteratorTest”).init();
MyArray = ArrayNew(1);
MyArray[1] = “one”;
MyArray[2] = “two”;
MyArray[3] = “three”;
</cfscript>
<cfdump var=#MyArray# />
<cfset MyIterator = IteratorTest.returnIterator(MyArray) />
<cfdump var=#MyIterator# />
<cfloop condition=#MyIterator.hasNext()#>
<cfset thisItem = MyIterator.next() />
<cfoutput>#thisItem#<br /></cfoutput>
</cfloop>
EDIT: useful comment from Mark Mandel on the matter:
I like this way of looping around arrays, but you can also do the same thing with Structs, but it just takes a little bit more work:
iterator = myStruct.values().iterator();
It should be noted that iterators for both Structs (Hashtables) and Arrays (Vectors) are ‘fail-fast’ – which means if someone removes and object from the array/struct not through that iterator, an exception will be thrown.
It may be worth making a top level copy of the array before returning the iterator to avoid collisions like these.
