EL access to map value using Integer key

I have a card with an Integer key. Using EL, how can I access a value by its key?

Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); 

I thought this would work, but it is not (where the map is already in the request attributes):

 <c:out value="${map[1]}"/> 

Follow-up: I detected a problem. Apparently, ${name[1]} searches for a card with a number like Long . I realized this when I changed the HashMap to TreeMap and got an error:

 java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long 

If I change my card as follows:

 Map<Long, String> map = new HashMap<Long, String>(); map.put(1L, "One"); 

then ${name[1]} returns "One". What's up with that? Why does <c:out> treat the number as long. Seems to contradict me (since int is used more often than long).

So, my new question is: is there an EL designation for accessing the map using the Integer value?

+81
java jsp el jstl
May 29 '09 at 4:58 a.m.
source share
5 answers

Initial Answer (EL 2.1, May 2009)

As mentioned in this thread of the java forum :

Basically autoboxing places an Integer object in a Map. i.e:

 map.put(new Integer(0), "myValue") 

EL (Expression Languages) evaluates 0 to be long and therefore searches for the long key in the map. those. he estimates:

 map.get(new Long(0)) 

Since a Long never matches an Integer object, it does not find the record on the map.
What is this in a nutshell.




May 2009 Update (EL 2.2)

In December 2009, EL 2.2 was introduced with JSP 2.2 / Java EE 6 , with several differences compared to EL 2.1 .
It seems (" EL Expression parsing integers ") which:

you can call the intValue method on a Long object inside EL 2.2 :

 <c:out value="${map[(1).intValue()]}"/> 

This might be a good workaround here (also mentioned below in Tobias Lifke answer )




Original answer:

EL uses the following shells:

 Terms Description Type null null value. - 123 int value. java.lang.Long 123.00 real value. java.lang.Double "string" ou 'string' string. java.lang.String true or false boolean. java.lang.Boolean 

JSP page demonstrating this:

  <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ page import="java.util.*" %> <h2> Server Info</h2> Server info = <%= application.getServerInfo() %> <br> Servlet engine version = <%= application.getMajorVersion() %>.<%= application.getMinorVersion() %><br> Java version = <%= System.getProperty("java.vm.version") %><br> <% Map map = new LinkedHashMap(); map.put("2", "String(2)"); map.put(new Integer(2), "Integer(2)"); map.put(new Long(2), "Long(2)"); map.put(42, "AutoBoxedNumber"); pageContext.setAttribute("myMap", map); Integer lifeInteger = new Integer(42); Long lifeLong = new Long(42); %> <h3>Looking up map in JSTL - integer vs long </h3> This page demonstrates how JSTL maps interact with different types used for keys in a map. Specifically the issue relates to autoboxing by java using map.put(1, "MyValue") and attempting to display it as ${myMap[1]} The map "myMap" consists of four entries with different keys: A String, an Integer, a Long and an entry put there by AutoBoxing Java 5 feature. <table border="1"> <tr><th>Key</th><th>value</th><th>Key Class</th></tr> <c:forEach var="entry" items="${myMap}" varStatus="status"> <tr> <td>${entry.key}</td> <td>${entry.value}</td> <td>${entry.key.class}</td> </tr> </c:forEach> </table> <h4> Accessing the map</h4> Evaluating: ${"${myMap['2']}"} = <c:out value="${myMap['2']}"/><br> Evaluating: ${"${myMap[2]}"} = <c:out value="${myMap[2]}"/><br> Evaluating: ${"${myMap[42]}"} = <c:out value="${myMap[42]}"/><br> <p> As you can see, the EL Expression for the literal number retrieves the value against the java.lang.Long entry in the map. Attempting to access the entry created by autoboxing fails because a Long is never equal to an Integer <p> lifeInteger = <%= lifeInteger %><br/> lifeLong = <%= lifeLong %><br/> lifeInteger.equals(lifeLong) : <%= lifeInteger.equals(lifeLong) %> <br> 
+110
May 29 '09 at 5:44
source share

Another useful hint in addition to the above comment will be that you have a string value contained in some variable, such as a query parameter. In this case, passing this value will also cause the JSTL to indicate the value “1” as a bite and, as such, does not appear in the Map hash map.

One way around this is to do something like this.

 <c:set var="longKey" value="${param.selectedIndex + 0}"/> 

Now it will be considered as a Long object, and then it has the ability to map the object when it is contained with a map card or any other.

Then continue as usual with something like

 ${map[longKey]} 
+11
Mar 29 2018-11-21T00:
source share

You can use all the functions from Long if you put the number in "(" ")". That way you can use long for int:

 <c:out value="${map[(1).intValue()]}"/> 
+6
Dec 17 '14 at 19:34
source share

Based on the above record, I tried this and it worked perfectly. I wanted to use the value of map B as keys for map A:

 <c:if test="${not empty activityCodeMap and not empty activityDescMap}"> <c:forEach var="valueMap" items="${auditMap}"> <tr> <td class="activity_white"><c:out value="${activityCodeMap[valueMap.value.activityCode]}"/></td> <td class="activity_white"><c:out value="${activityDescMap[valueMap.value.activityDescCode]}"/></td> <td class="activity_white">${valueMap.value.dateTime}</td> </tr> </c:forEach> </c:if> 
+3
Jan 24 2018-12-12T00:
source share

If you have Map keys with Integer that you cannot change, you can write a custom EL function to convert Long to Integer . This will allow you to do something like:

 <c:out value="${map[myLib:longToInteger(1)]}"/> 
+2
Sep 28 '12 at 8:27
source share



All Articles