Question

I need to efficiently search ranges of integers in ColdFusion. These ranges have different lengths and they can have "holes" (they are not continuous).

I thought that a Java TreeMap called from ColdFusion would be a efficient solution. However, I sadly discovered that the TreeMap is alphabetically ordered and I need numeric order. I tried to apply the JavaCast function to the key of the map but it didn't work. Apparently, ColdFusion was expecting the key to be a String and not an Int.

Here is the sample code (without the JavaCast attempt) to illustrate my situation:

<!--- Create the TreeMap --->
<cfset map = createObject("java", "java.util.TreeMap").init()>

<!--- Add Ranges to it --->
<!--- From 1 to 3 return "Range 1". --->
<cfset t = StructNew()>
<cfset t.finish = JavaCast("int", 3)>
<cfset t.value = "Range 1">
<cfset map.put(1, t)><!--- This 1 is the one I tried to JavaCast --->

<!--- From 4 to 10 return "Range 2". --->
<cfset t = StructNew()>
<cfset t.finish = JavaCast("int", 10)>
<cfset t.value = "Range 2">
<cfset map.put(4, t)>

<!--- From 20 to 50 return "Range 3". --->
<cfset t = StructNew()>
<cfset t.finish = JavaCast("int", 50)>
<cfset t.value = "Range 3">
<cfset map.put(20, t)>

<!--- From 75 to 80 return "Range 4". --->
<cfset t = StructNew()>
<cfset t.finish = JavaCast("int", 80)>
<cfset t.value = "Range 4">
<cfset map.put(75, t)>

<!--- Debug. Output the Map content --->
<cfoutput>Debug - Ordered map: #map.toString()#</cfoutput><br />

<!--- Search number --->
<cfset key = 9>
<cfset entry = map.floorEntry(key)>

<!--- Debug. Output entry found --->
<cfoutput>Debug - Entry found: #entry#</cfoutput><br />

<!--- Debug. Output result --->
<cfif isNull(entry)>
    <cfoutput>Too small</cfoutput>
<cfelseif key lte entry.getValue().finish>
    <cfoutput>Debug - Result: #entry.getValue().value#</cfoutput>
<cfelse>
    <cfoutput>Too large</cfoutput>
</cfif>

And this is the output generated by the code above:

Debug - Ordered map: {1={FINISH={3},VALUE={Range 1}}, 20={FINISH={50},VALUE={Range 3}}, 4={FINISH={10},VALUE={Range 2}}, 75={FINISH={80},VALUE={Range 4}}}
Debug - Entry found: 75={FINISH={80},VALUE={Range 4}}
Debug - Result: Range 4

When I was expecting it to be:

Debug - Ordered map: {1={FINISH={3},VALUE={Range 1}}, 4={FINISH={10},VALUE={Range 2}}, 20={FINISH={50},VALUE={Range 3}}, 75={FINISH={80},VALUE={Range 4}}}
Debug - Entry found: 4={FINISH={10},VALUE={Range 2}}
Debug - Result: Range 2

So my question here is, what do I have to do to get the TreeMap working as I want, which is, with numeric order?

By the way, I'm using ColdFusion 9.

Thank you very much!

Was it helpful?

Solution

(From comments)

Very first thing that comes to mind is you are not casting all of the key values as integers, so they are treated as strings when the TreeMap performs its comparisons. That would explain why floorEntry returns the wrong results. It is comparing strings, not integers. Try casting all of the keys as integers, and it should work as expected.

 <cfset map.put( javacast("int", 1), t)>
 ...
 <cfset map.put( javacast("int", 75), t)>
 <cfset key = 9>
 <cfset entry = map.floorEntry( javacast("int", key) )>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top