EL доступ к значению карты по целочисленному ключу


у меня есть карта с ключом целое. Используя EL, как я могу получить доступ к значению по его ключу?

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

Я думал, что это будет работать, но это не так (Где карта уже в атрибуты запроса):

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

дальнейшие действия: я нашел проблему. Видимо ${name[1]} выполняет поиск карты с номером как Long. Я понял это, когда я изменил HashMap до TreeMap и получил ошибку:

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]} возвращает "один". Что это такое? Почему же <c:out> рассматривайте число как длинное. Мне кажется нелогичным (поскольку int чаще используется, чем long).

Итак, мой новый вопрос: есть ли обозначение EL для доступа к карте с помощью Integer значение?

5 84

5 ответов:

первоначальный ответ (EL 2.1, май 2009)

как говорится в эта тема форума java:

в основном autoboxing помещает целочисленный объект в карту. т. е.:

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

EL (языки выражений) оценивает 0 как длинный и, таким образом, ищет длинный как ключ на карте. т. е. он оценивает:

map.get(new Long(0))

как Long не равен

просто еще один полезный совет в дополнение к приведенному выше замечанию, что будет, когда у вас есть строковое значение, содержащееся в переменной, такой как параметр запроса. В этом случае передача этого также приведет к тому, что JSTL будет использовать значение say "1" как sting и как таковое не будет найдено в хэш-карте карты.

один из способов обойти это, чтобы сделать что-то подобное.

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

теперь это будет рассматриваться как длинный объект, а затем имеет шанс соответствовать объекту, когда он содержится в пределах карты карты или что-то еще.

затем продолжайте, как обычно, что-то вроде

${map[longKey]}

вы можете использовать все функции из Long, если вы поместите число в " (")". Таким образом, вы можете бросить Long в int:

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

основываясь на приведенном выше сообщении, я попробовал это, и это сработало отлично Я хотел использовать значение карты B в качестве ключей для карты 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>

если у вас просто есть Map С Integer ключи вы не можете изменить, вы могли бы написать пользовательские функции EL преобразование Long до Integer. Это позволит вам сделать что-то вроде:

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