EL dostęp do wartości mapy przez klucz Integer
Mam mapę oznaczoną liczbą całkowitą. Używając EL, jak Mogę uzyskać dostęp do wartości za pomocą jej klucza?
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
Myślałem, że to zadziała, ale nie działa (gdzie mapa jest już w atrybutach żądania):
<c:out value="${map[1]}"/>
Kontynuacja: namierzyłem problem. Wygląda na to, że ${name[1]}
przeszukuje mapę z numerem jako Long
. Domyśliłem się tego, kiedy zmieniłem HashMap
na TreeMap
i otrzymałem błąd:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
Jeśli zmienię mapę na:
Map<Long, String> map = new HashMap<Long, String>();
map.put(1L, "One");
Then ${name[1]}
returns "Jeden". O co chodzi? Dlaczego <c:out>
traktuje liczbę jako długą. Wydaje mi się sprzeczne z intuicją(ponieważ int jest częściej używany niż long).
Więc moje nowe pytanie brzmi, czy istnieje zapis EL, aby uzyskać dostęp do mapy przez wartość Integer
?
5 answers
Odpowiedź początkowa (EL 2.1, maj 2009)
Jak wspomniano w ten wątek java forum :
W zasadzie autoboxing umieszcza obiekt całkowity na mapie. ie:
map.put(new Integer(0), "myValue")
EL (języki wyrażeń) ocenia 0 jako długą i w ten sposób szuka długiej jako klucza na mapie. ie ocenia:
map.get(new Long(0))
Ponieważ Long
nigdy nie jest równy obiektowi Integer
, nie znajduje wpisu na mapie.
To jest to w nutshell.
Aktualizacja od maja 2009 (EL 2.2)
W grudniu 2009 wprowadzono EL 2.2 z JSP 2.2 / Java EE 6, z kilkoma różnicami w porównaniu do EL 2.1.
Wydaje się (" El Expression parsing integer as long "), że:
Możesz wywołać metodę
intValue
na obiekcieLong
wewnątrz EL 2.2:
<c:out value="${map[(1).intValue()]}"/>
To może być dobre obejście tutaj (również wymienione poniżej w Tobias Liefke'S odpowiedz)
Oryginalna odpowiedź:
EL używa następujących owijarek:
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
Strona JSP:
<%@ 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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:21
Kolejna pomocna podpowiedź oprócz powyższego komentarza będzie, gdy masz wartość ciągu zawartego w jakiejś zmiennej, takiej jak parametr request. W takim przypadku podanie tej wartości spowoduje również, że JSTL wykreśli wartość say " 1 " jako żądło i jako takie nie znajdzie dopasowania w hashmapie na mapie.
Jednym ze sposobów na obejście tego jest zrobienie czegoś takiego.<c:set var="longKey" value="${param.selectedIndex + 0}"/>
To będzie teraz traktowane jako długi obiekt, a następnie ma szansę dopasować Obiekt, gdy jest zawarty / align = "left" /
Następnie kontynuuj jak zwykle coś w rodzaju
${map[longKey]}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-29 14:49:11
Możesz używać wszystkich funkcji Z Long, jeśli umieścisz liczbę w" ("")". W ten sposób można wrzucić long do int:
<c:out value="${map[(1).intValue()]}"/>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-17 19:34:06
W oparciu o powyższy post próbowałem tego i to działało dobrze Chciałem użyć wartości Mapy B jako kluczy dla mapy 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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-24 00:53:31
Jeśli po prostu masz Map
z Integer
kluczami, których nie możesz zmienić, możesz napisać niestandardową funkcję EL, Aby przekonwertować Long
na Integer
. To pozwoli Ci zrobić coś takiego:
<c:out value="${map[myLib:longToInteger(1)]}"/>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:34