Converting A Java Array To A ColdFusion Array

Posted June 7, 2007 at 9:33 AM by Ben Nadel

Tags: ColdFusion

A while back, I discovered that splitting a string into an array using the Java String::Split() method produced what appeared to be a ColdFusion array, but what was, in fact, a read-only Java array (at least from the ColdFusion perspective). Under the hood, ColdFusion arrays are really collection objects, not true arrays. Because of this, ColdFusion does not inherently resize or set values into Java arrays.

I have always knowm that to get around this, you could create a ColdFusion array, then loop over the Java array and copy the values:

  • <!---
  • Create a string and then split it into an array using
  • the String::Split() method. This will give us an array,
  • but NOT a traditional ColdFusion array. This is a read-
  • only array (well, from CF's perspective).
  • --->
  • <cfset arrGirls = ToString(
  • "Maria Bello,Christina Cox,Meg Ryan"
  • ).Split( "," )
  • />
  •  
  • <!--- Create a ColdFuion array. --->
  • <cfset arrCFGirls = ArrayNew( 1 ) />
  •  
  • <!--- Loop over array to copy values. --->
  • <cfloop
  • index="intGirl"
  • from="1"
  • to="#ArrayLen( arrGirls )#"
  • step="1">
  •  
  • <!--- Copy value. --->
  • <cfset arrCFGirls[ intGirl ] = arrGirls[ intGirl ] />
  •  
  • </cfloop>

But this always seems like such a ganky way of doing it. I had hoped there was a more elegant solution, but never really look the time to look it up. Well, finally motivated by Rob Marchetti's comment on my previous post on the subject matter, I figured I would finally look into it.

Just to recap, when you split a string using the String::Split() method, you get what looks like an array:

  • <!---
  • Create a string and then split it into an array using
  • the String::Split() method. This will give us an array,
  • but NOT a traditional ColdFusion array. This is a read-
  • only array (well, from CF's perspective).
  • --->
  • <cfset arrGirls = ToString(
  • "Maria Bello,Christina Cox,Meg Ryan"
  • ).Split( "," )
  • />
  •  
  • <!---
  • Dump out the array. You will see that it looks like a
  • standard ColdFusion array (but it is not).
  • --->
  • <cfdump
  • var="#arrGirls#"
  • label="Array via Split()"
  • />

When we CFDump that out, we get:


 
 
 

 
Java Array To ColdFusion Array  
 
 
 

Looks good, right? Sure, but then, when we try to go and alter it, as we could any other ColdFusion array:

  • <!--- Try to add a girl to this array. --->
  • <cfset ArrayAppend(
  • arrGirls,
  • "Madonna"
  • ) />

... we get the following ColdFusion error:

The Coldfusion function [ArrayAppend] is not supported on this object. The Coldfusion function [ArrayAppend] is not supported on an object of type [coldfusion.runtime.Cast$1]. <br>For Example: XML objects can be operated on by a subset of the Struct and Array functions but not all.

So our goal now becomes to convert this string array into a ColdFusion collection "array." As it turns out, this can be done in a two part process - converting the array into a list, which supports the Java Collection interface, and then add that list to an existing ColdFusion array.

Let's take a look at how to convert the Java array into a List. Using the Java Array utility class, we can use ColdFusion to manipulate Java arrays. In this case, we are going to use the AsList() method to convert the Java array to a List object:

  • <!---
  • Using the Java array, we can use the Array utility
  • class to convert this array to a fixed size list.
  • --->
  • <cfset arrGirlList = CreateObject(
  • "java",
  • "java.util.Arrays"
  • ).AsList(
  • arrGirls
  • ) />
  •  
  • <!---
  • Dump out the list object. You will see that it looks
  • like a standard ColdFusion array (but it is not).
  • --->
  • <cfdump
  • var="#arrGirlList#"
  • label="Array via AsList()"
  • />

When we CFDump that List object out, we get:


 
 
 

 
Java Array To ColdFusion Array  
 
 
 

Be careful! Again, this object looks like a ColdFusion array, but it is not. If we tried to modify it:

  • <!--- Try to add a girl to this list. --->
  • <cfset ArrayAppend(
  • arrGirlList,
  • "Frances McDormand"
  • ) />

... we get the following ColdFusion error:

The Coldfusion function [ArrayAppend] is not supported on this object. The Coldfusion function [ArrayAppend] is not supported on an object of type [java.util.Arrays$ArrayList]. <br>For Example: XML objects can be operated on by a subset of the Struct and Array functions but not all.

Don't worry, we are almost there. The List object that we have now created supports the Java Collection interface. If you have messed around with any of the underlying Java method of ColdFusion objects, you might know that the ColdFusion Array (collection) has a method called AddAll(). AddAll() takes a Collection-interfaced object and adds all of its items to the ColdFusion array:

  • <!--- Create an empty ColdFusion array. --->
  • <cfset arrGirls = ArrayNew( 1 ) />
  •  
  • <!---
  • Add all the elements of the list to the new
  • ColdFusion array. Since the List impliments the
  • Collections interface, this will work quite nicely.
  • --->
  • <cfset arrGirls.AddAll(
  • arrGirlList
  • ) />
  •  
  • <!--- Add a new girl to the array. --->
  • <cfset ArrayAppend(
  • arrGirls,
  • "Madonna"
  • ) />
  •  
  • <!--- Dump out the true ColdFusion array. --->
  • <cfdump
  • var="#arrGirls#"
  • label="Array via AddAll( LIST )"
  • />

When we run the above code, we get no ColdFusion errors and our resultant array looks like this:


 
 
 

 
Java Array To ColdFusion Array  
 
 
 

Ok, so that's a bit of a process with a few steps. However, we can "simplify" and by that I mean condense the code into something that might be considered a little more manageable:

  • <!---
  • To make the code more condense, you could do
  • something like this. Not nearly as readable, but
  • at least you end up with a ColdFusion array.
  • --->
  • <cfset arrGirls = ArrayNew( 1 ) />
  •  
  • <!---
  • Split the girl string into a Java array but store
  • it in the girls array.
  • --->
  • <cfset arrGirls.AddAll(
  • CreateObject(
  • "java",
  • "java.util.Arrays"
  • ).AsList(
  • ToString(
  • "Maria Bello,Christina Cox,Meg Ryan"
  • ).Split( "," )
  • )
  • ) />

That's not the easiest thing to read, but to me, it is still a little more elegant that looping over the array and copying over each item (as we did at the beginning of this post). I think the best solution would be for ColdFusion to update their Array wrapper and allow the AddAll() method to accept an array. But for now, this will work.




Reader Comments

Jun 7, 2007 at 10:06 AM // reply »
92 Comments

Ben...

You should submit this to Adobe. Maybe we'll get lucky and they can get it into the final release of Scorpio.


Jun 7, 2007 at 10:40 AM // reply »
1 Comments

Why wouldn't you just use listtoarray("foo bar","baz qux") instead?


Jun 7, 2007 at 12:21 PM // reply »
25 Comments

@Lars: because listToArray() ignores empty list elements. using the split() method works around this... to a degree. ben is addressing the fact that the resulting array is readonly.

the other issue to address is that split() still ignores empty list elements at the end of the list. rupesh kumar addressed that in his blog post here: http://coldfused.blogspot.com/2007/06/listtoarray-with-empty-elements-part-ii.html


Jun 7, 2007 at 12:59 PM // reply »
1 Comments

if you use split( ",", -1) this should catch any trailing empty lists at the end... i think... i haven't tested this though. :)


Jun 7, 2007 at 1:32 PM // reply »
11,238 Comments

Guys, let's not forget there are many ways to get a Java array. Using the Split() method is just one of them. Many of the Java objects and interfaces have methods that return stuff as arrays. The focus here was on getting those into ColdFusion "array" form... the focus was not meant to be on Split(). That's just happens to be an easy one to use, but I could have just as easily when with String::ToCharArray().

@Andy,

I will do that, I think this is something that could be cool and mostly likely is very easy to implement.


Jul 19, 2007 at 4:24 PM // reply »
25 Comments

@Ben and Andy,
We heard it and included it in CF8 :-) I blogged about it a little while back.

http://coldfused.blogspot.com/2007/07/listtoarray-in-coldfusion-8.html


Jul 19, 2007 at 4:28 PM // reply »
11,238 Comments

@Rupesh,

Very cool! I think the ability to keep empty list elements is going to make people very happy :)


Tim
Jul 25, 2007 at 12:09 AM // reply »
10 Comments

Ben--

This was a life saver. Again, your blog helps the common programmer solve a problem. I really appreciate it.

Tim


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 20, 2013 at 10:21 AM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
Is there any error logging and handling framework in angularjs, if not then in what way I can do this. ... read »
May 19, 2013 at 2:31 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
It's funny really just how well that image describes the way I would imagine most people that go with angular for some project is. I have had a similar roller-coaster ride with it as well, but not qu ... read »
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools