ईएल पूर्णांक कुंजी द्वारा एक मानचित्र मूल्य का उपयोग करते हैं


85

मेरे पास इंटेगर का एक नक्शा है। ईएल का उपयोग करना, मैं इसकी कुंजी द्वारा एक मूल्य का उपयोग कैसे कर सकता हूं?

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>एक नंबर को लंबे समय तक क्यों माना जाता है। मेरे लिए काउंटरिंटिटिव लगता है (चूंकि इंट लंबे समय से अधिक आमतौर पर उपयोग किया जाता है)।

तो मेरा नया सवाल यह है कि क्या किसी मैप को किसी Integerमान द्वारा एक्सेस करने के लिए EL नोटेशन है ?

जवाबों:


117

प्रारंभिक उत्तर (ईएल 2.1, मई 2009)

जैसा कि इस जावा फोरम थ्रेड में बताया गया है :

मूल रूप से ऑटोबॉक्सिंग मैप में एक इंटेगर ऑब्जेक्ट डालता है। अर्थात:

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

ईएल (एक्सप्रेशंस लैंग्वेजेज) 0 का मूल्यांकन लॉन्ग के रूप में करता है और इस तरह मैप में कुंजी के रूप में लॉन्ग ढूंढता है। इसका मूल्यांकन करता है:

map.get(new Long(0))

जैसा कि एक वस्तु के Longबराबर कभी नहीं होता है Integer, यह नक्शे में प्रविष्टि नहीं पाता है।
यह संक्षेप में है।


मई 2009 से अद्यतन (ईएल 2.2)

दिसंबर 2009 JSP 2.2 / जावा ईई 6 के साथ ईएल 2.2 का इस्तेमाल किया गया एक साथ, ईएल 2.1 की तुलना में कुछ अंतर
ऐसा लगता है (" लंबे समय के लिए एल एक्सप्रेशन पार्सिंग पूर्णांक "):

आप EL 2.2 के अंदर ऑब्जेक्ट को स्वयं intValueपर विधि कह सकते हैंLong :

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

यहाँ एक अच्छा वर्कअराउंड हो सकता है ( टोबियास लाइपके के उत्तर में भी नीचे उल्लेख किया गया है )


मूल उत्तर:

ईएल निम्न आवरणों का उपयोग करता है:

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 पृष्ठ यह प्रदर्शित करता है:

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

तो क्या कोई तरीका नहीं है कि ईएल को एक नंबर के रूप में विस्तार करने के लिए ईएल प्राप्त करें?
स्टीव कू

1
@Steve: वास्तव में, ईएल उस का समर्थन नहीं करता है।
वॉनसी

मुझे Google खोज से यह प्रश्न और उत्तर मिला। इतना ज़रूर है, जैसे ही मैंने मैप <Integer, String> से Map <Long, String> पर स्विच किया, मैं अपने JSP पेज में मौजूद EL के उपयोग से इसे खींचने में सक्षम था। धन्यवाद!!
जॉन मुन्सच

@Steve: यह संभव है - मेरा उत्तर देखें
टोबियास लाइपके

@SteveKuo यह वास्तव में संभव होना चाहिए। मुझे अब एहसास हुआ कि यह 6 साल पुराना उत्तर लिखा गया था जब ईएल 2.2 अभी तक जारी नहीं हुआ था। मैंने उक्त उत्तर को संपादित और अद्यतन किया है।
वॉनक

11

उपरोक्त टिप्पणी के अलावा बस एक और सहायक संकेत तब होगा जब आपके पास कुछ चर जैसे अनुरोध पैरामीटर के रूप में एक स्ट्रिंग मान निहित हो। इस स्थिति में, इसे पारित करने से JSTL को स्टिंग के रूप में "1" कहने का मान होगा और जैसा कि मैप हैशमैप में कोई मिलान नहीं हो रहा है।

इसके आसपास जाने का एक तरीका कुछ ऐसा करना है।

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

यह अब एक लंबी वस्तु के रूप में माना जाएगा और तब एक वस्तु से मेल खाने का मौका होगा जब यह नक्शा मानचित्र या जो कुछ भी शामिल हो।

फिर, हमेशा की तरह कुछ के साथ जारी रखें

${map[longKey]}

10

यदि आप संख्या को "(" ")" में रखते हैं तो आप लॉन्ग से सभी कार्यों का उपयोग कर सकते हैं। इस तरह आप लंबे समय तक एक इंट कास्ट कर सकते हैं:

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

मैंने तुरंत आपका जवाब नहीं देखा। +1। मैंने अधिक दृश्यता के लिए अपने उत्तर में उस संभावना को शामिल और दस्तावेजित किया है।
वॉनक

3

उपरोक्त पोस्ट के आधार पर मैंने यह कोशिश की और यह ठीक काम किया मैं मैप ए के लिए मैप बी के मूल्य को कुंजी के रूप में उपयोग करना चाहता था:

<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

तुम सिर्फ करने के लिए एक हो तो Mapसाथ Integerचाबियाँ आप बदल नहीं सकते, तो आप एक लिख सकता कस्टम ईएल समारोह एक कन्वर्ट करने के Longलिए Integer। यह आपको कुछ ऐसा करने की अनुमति देगा:

<c:out value="${map[myLib:longToInteger(1)]}"/>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.