问题描述
我有一个以整数为键的地图.使用 EL,如何通过键访问值?
I have a Map keyed by Integer. 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");
我认为这会起作用,但它不起作用(其中 map 已经在请求的属性中):
I thought this would work but it doesn't (where map is already in the request's attributes):
<c:out value="${map[1]}"/>
跟进:我找到了问题所在.显然 ${name[1]}
使用 Long
编号进行地图查找.当我将 HashMap
更改为 TreeMap
并收到错误时,我发现了这一点:
Follow up: I tracked down the problem. Apparently ${name[1]}
does a map lookup with the number as a Long
. I figured this out when I changed HashMap
to TreeMap
and received the error:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
如果我将地图更改为:
Map<Long, String> map = new HashMap<Long, String>();
map.put(1L, "One");
然后 ${name[1]}
返回一".那是怎么回事?为什么 将数字视为长整数.对我来说似乎违反直觉(因为 int 比 long 更常用).
then ${name[1]}
returns "One". What's with that? Why does <c:out>
treat a number as a long. Seems counterintuitive to me (as int is more commonly used than long).
所以我的新问题是,是否有 EL 表示法可以通过 Integer
值访问地图?
So my new question is, is there a EL notation to access a map by an Integer
value?
推荐答案
初始答案(EL 2.1,2009 年 5 月)
Initial answer (EL 2.1, May 2009)
如这个java论坛主题所述:
基本上自动装箱将一个 Integer 对象放入 Map 中.即:
map.put(new Integer(0), "myValue")
EL (Expressions Languages) 将 0 计算为 Long,因此会寻找 Long 作为映射中的键.即它评估:
EL (Expressions Languages) evaluates 0 as a Long and thus goes looking for a Long as the key in the map.ie it evaluates:
map.get(new Long(0))
由于 Long
永远不等于 Integer
对象,因此它不会在地图中找到条目.
一言以蔽之.
As a Long
is never equal to an Integer
object, it does not find the entry in the map.
That's it in a nutshell.
2009 年 12 月推出了带有 JSP 2.2/Java EE 6 的 EL 2.2,带有 与 EL 2.1 相比几乎没有区别.
似乎(EL 表达式解析整数一样长"):
你可以在 EL 2.2 内的 Long
对象上调用 intValue
方法:
<c:out value="${map[(1).intValue()]}"/>
这可能是一个很好的解决方法(也在下面 Tobias Liefke 的 答案)
That could be a good workaround here (also mentioned below in Tobias Liefke's answer)
原答案:
EL 使用以下包装器:
EL uses the following wrappers:
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 页面:
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>
这篇关于EL 通过整数键访问映射值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!