85 votes

EL accéder à une valeur de carte par clé Integer

J'ai une Carte assortie en Entier. À l'aide de EL, comment puis-je accéder à une valeur par sa clé?

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

J'ai pensé que cela pourrait fonctionner, mais il n'a pas (d'où la carte est déjà dans la demande attributs):

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

Suivi: j'ai traqué le problème. Apparemment ${name[1]} t une carte de recherche avec le numéro de la Long. J'ai compris quand j'ai changé de HashMap de TreeMap et reçu le message d'erreur:

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

Si je change ma carte:

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

ensuite, ${name[1]} retours "Un". Qu'est-ce que? Pourquoi est - <c:out> traiter un certain nombre comme une longue. Semble contre-intuitif pour moi (en tant que int est plus couramment utilisé que long).

Donc ma nouvelle question est, est-il un EL notation pour accéder à une carte par un Integer de la valeur?

114voto

VonC Points 414372

Comme mentionné dans ce java thread du forum:

Fondamentalement, l'autoboxing met un objet Integer dans la Carte. c'est à dire:

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

EL (Expressions Langues) évalue 0 comme une Longue et donc va à la recherche pour une Longue comme la clé dans la carte. ie il évalue:

map.get(new Long(0))

Comme un Long n'est jamais égal à un nombre Entier d'objet, il ne trouve pas l'entrée dans la carte. C'est en un mot.

EL utilise l'encapsulation:

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

Page JSP de le démontrer:

 <%@ 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>

11voto

Dave Points 101

Juste un autre truc utile, en plus du commentaire ci-dessus lorsque vous avez une chaîne de valeur contenue dans une variable comme paramètre de la requête. Dans ce cas, le passage de cette en aura aussi pour conséquence de JSTL incrustation de la valeur de "1" comme un aiguillon et en tant que tel aucune correspondance n'étant trouvé dans une Carte hashmap.

Un moyen de contourner cela est de faire quelque chose comme cela.

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

Ce sera désormais traitée comme un objet assez Long, et ensuite on a une chance de correspondre à un objet lorsqu'il est contenu dans la carte ou quoi que ce soit.

Ensuite, continuer comme d'habitude avec quelque chose comme

${map[longKey]}

3voto

Dhanashri Points 31

Basé sur le post ci-dessus j’ai essayé ceci et ce bien fonctionné, que j’ai voulu utiliser la valeur de la carte B comme clés pour carte A:

2voto

Jasper de Vries Points 3043

S’il vous arrive juste à avoir un avec clés, vous ne pouvez pas modifier, vous pouvez écrire une fonction personnalisée de EL pour convertir un à . Cela vous permettrait de faire quelque chose comme :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X