How to iterate HashMap?

classic Classic list List threaded Threaded
22 messages Options
12
Reply | Threaded
Open this post in threaded view
|

How to iterate HashMap?

Pinocchio
Hello, maybe I have stupid question but I cannot iterate HashMap... How can I do it?

When I try do this that <li th:each="user : {$activeUsers}"> I get error:

org.thymeleaf.exceptions.ExpressionParsingException: Could not parse as each: "user : {$activeUsers}"
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

danielfernandez
Administrator
Hi,

You're misplacing your $. It should be:

<li th:each="user : ${activeUsers}">

Each "user" will have a "key" and a "value".

Regards,
Daniel
kp
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

kp
I have tried the below code:

<div th:each="userEnrty: ${userMap}">
<p th:text="${userEntry.key}">No Id!</p>
<p th:text="${userEntry.value}">No Name!</p>
</div>

and I get the following exception:

Exception evaluating OGNL expression: "entry.value"
.
.
.
<full stack trace ommited>
Caused by: ognl.OgnlException: key [java.lang.IllegalAccessException: Method [public final java.lang.Object java.util.HashMap$Entry.getKey()] cannot be accessed.]

am I doing something wrong here?

ThymeLeaf version: 2.0.4
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

Martin
Hi,

If you did not already spot the typo...

Your iterator is using:
<code>
...each="userEnrty...
</code>

But your iterations refer to:
<code>
...userEntry...
</code>

hth
.m
vg
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

   
The map configdata.parameters contains 2 entry's. What is strange is that when this page is rendered, I see a table with 2 rows both with the same MapEntry.

So it seems to be iterating through the map however the configparam is not being updated on each iteration. The underlying Map implementation in this case is EnumMap.

Is there something I'm doing wrong?
vg
In reply to this post by danielfernandez
I am struggling a bit with HashMap iteration. I have the following in my template:

vg
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

vg
I just changed the underlying map to a standard HashMap and seems to work ok so possibly related to EnumMap.
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?


Zemi
Administrator
In reply to this post by vg
Hi,

your code is OK provided the bean "configdata.parameters" has type Set<Map.EntrySet>

If the bean is a Map, try the following code:

   
vg
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

vg
I still see the same result even when I append .entrySet(). The only way I can get it to work is to use a standard HashMap.

EnumMap doesn't appear to work correctly.
kp
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

kp
In reply to this post by Martin
Thanks Martin, for finding out the typo..
But even after i corrected the typos, still I get the same error.

By looking closely at the excetion message, it says:
"Caused by: ognl.OgnlException: key [java.lang.IllegalAccessException: Method [public final java.lang.Object java.util.HashMap$Entry.getKey()] cannot be accessed.]
"
Notice that, it uses java.utli.HashMap$Entry.getKey().

My point is, Entry is an static inner class of Map Interface. It can be accessed only by Map interface as it is static. Implementing class can't be used to access the Entry inner class.

Is this the problem? or am getting the whole theory wrong??
kp
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

Emanuel
Administrator
Entry may be a static interface of Map, but every inner-class/interface or property of an interface is public static, and every method is public abstract, even if you don't declare it as such (it's a compile error to try force it otherwise).  If it does give you HashMap.Entry instead, and HashMap.Entry implements the Map.Entry interface, then the getKey() and getValue() methods should be visible too (it's a compiler error to reduce the visibility of inherited methods).

So this should all work, but obviously something is amiss :|

I tried your example (with the spelling mistake fixed of course) and was able to get it to work just fine, so I'm not really sure why you're getting an error.  I'm using Oracle's Java 7 and Thymeleaf 2.0.8 (saw you were still on 2.0.4 in your other post) if that makes a difference?

I tried another simple example and got that working too, but it looks almost exactly like what you've already posted:

HashMap<String,String> test = new HashMap<>();
test.put("Key1", "Value1");
test.put("Key2", "Value2");
context.setVariable("test", test);

On my HTML page:

<p th:each="entry: ${test}">
  <span th:text="'Key: ' + ${entry.key} + ', Value: ' + ${entry.value}"></span>
</p>

Resulting in:

<p>
  <span>Key: Key2, Value: Value2</span>
</p>
<p>
  <span>Key: Key1, Value: Value1</span>
</p>

---
To the person who was trying to use EnumMap, I was able to get the same example above working with EnumMap by changing the HashMap to EnumMap and giving it Enum values for the key instead:

private static enum TestEnum { // This test enum was an inner-class just for this test
  ENUM1, ENUM2;
}

...

EnumMap<TestEnum,String> test = new EnumMap<>(TestEnum.class);
test.put(TestEnum.ENUM1, "Value1");
test.put(TestEnum.ENUM2, "Value2");
context.setVariable("test", test);

Once again, using Oracle Java 7 and Thymeleaf 2.0.8.
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

rajnish
Not Sure for some reason, with same java code as yours (Emanual), i get this ourput:

<p>
  Key: Key2, Value: [Ljava.lang.String;@28e2b4c2
</p>
<p>
  Key: Key1, Value: [Ljava.lang.String;@3bc94186
</p>

Can you help?

I've posted a query at http://forum.thymeleaf.org/Can-not-access-HashMap-in-the-form-input-tag-td4025324.html
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

Emanuel
Administrator
I can only see 1 difference in the code you posted to the other thread, and it's that the value1 and value2 put into the map aren't surrounded by double-quotes so they aren't strings.  Would that change anything?  Are value1 and value2 strings already?
Nim
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

Nim
Is it possible to access object properties if they are a key or a value?

For example:
Map newMap;
newMap.put(new Object, int count);[/code]

Could I do this?
<tr th:each="mapEntry:${newMap}">
    <td th:text="${mapEntry.key.date} + ' is this record's date'">1/1/13 is this record's date</td>
</tr>

Notice the key.date, as in date is a property of the object acting as the key.

Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

Zemi
Administrator
Assuming that "new Object" is a fake example, yes, it is possible.

Does it not work for you?

Nim
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

Nim
I was just reading about Hashmaps and that came to mind and I wasn't near a server/ide to test it. Thank you though!
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

sunil0791
I also was facing a similar problem where it was showing like below:
  Key: Key1, Value: [Ljava.lang.String;@3bc94186

looks like  VariableExpression.parseVariable (final String input) always string only when expression starts with "{" and ends with "}"
So, i added extra brackets in variable expression. something like below and it worked:
<span th:text="'Key: ' + ${entry.key} + ', Value: ' + ${{entry.value}}"></span>

I was using thymeleaf version 2.1.3.RELEASE
Spring version 4.0.5.RELEASE

Hope it helps.. :)

And the map that i was iterating is request.getParameterMap(). I was thinking may be we can provide a better solution for this but not sure how..
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

kindara
Hello every body,

I think i am facing a similar problem too

I have a form with th:object="formBean"

This object contains an attribute called "carMap = HashMap<Bobo, Integer>"
I try to create input with the value of this map, but it does not work.

When a iterate in my <form>, i do this :
<form th:object="${formBean}" ....>

...
     <tr th:each="car,carStat : *{carMap}">
        <td th:text="${carStat.count}">1</td>
        <td th:text="${car.key.otherObject}">name</td>
        <td>
            <input type="text" th:field="*{carMap[__${carStat.index}__].value}" /> -->
        </td>
    </tr>

...
</form>

But i obtains this kind of error :
Caused by: org.springframework.beans.InvalidPropertyException: Invalid property 'carMap[0]' of bean class [com.mypackage.FormBean]: Invalid index in property path 'carMap[0]'; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'com.mypackage.Bobo' for property 'null'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.mypackage.Bobo]: no matching editors or conversion strategy found
	at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:840)
	at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:716)
	at org.springframework.validation.AbstractPropertyBindingResult.getActualFieldValue(AbstractPropertyBindingResult.java:99)
	at org.springframework.validation.AbstractBindingResult.getFieldValue(AbstractBindingResult.java:229)
	at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:120)
	at org.thymeleaf.spring4.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:348)
	at org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:288)
	at org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:260)
	at org.thymeleaf.spring4.processor.attr.AbstractSpringFieldAttrProcessor.processAttribute(AbstractSpringFieldAttrProcessor.java:97)
	at org.thymeleaf.processor.attr.AbstractAttrProcessor.doProcess(AbstractAttrProcessor.java:87)
	at org.thymeleaf.processor.AbstractProcessor.process(AbstractProcessor.java:212)
	... 79 common frames omitted
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'com.mypackage.Bobo' for property 'null'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.mypackage.Bobo]: no matching editors or conversion strategy found
	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:474)
	at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:818)
	... 89 common frames omitted
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.mypackage.Bobo]: no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:459)
	... 90 common frames omitted

2014-08-29 01:04:21.776 ERROR 15872 [http-nio-8080-exec-5] --- o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (messages/stock)] with root cause

java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.mypackage.Bobo]: no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:459)
	at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:818)
	at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:716)
   
I will appreciate if someone have got a solution for this problem.
Thanks in advance.





Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

kindara
Nobody have an idea for this problem ?
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

dsotoAT4
In reply to this post by Emanuel
Hi Emanuel,

Sorry in advance because I am not sure if this is the right way and place to ask my question.

I am new using Thymeleaf and I have a similar problem.. Could you  help me please?

I have a java class in which I have this HashMap:

"private Map<String, TraduccionMenu> traducciones = new HashMap<String, TraduccionMenu>();"

and I use this method to acces to it from thymeleaf:

"public Map<String, TraduccionMenu> getTraducciones() {

                return traducciones;
}"

where "TraduccionMenu" is another class where I have method:

 "public String getNombre() {
 return nombre;
 }"

that I need to get the value of the variable/property "private String nombre;"

I use this code in thymeleaf to get the value of property "nombre":

"<div th:each="instance : ${traducciones}">
        keyvalue
        valueValue
</div>"

But the result is:

"<div>
        7734
                               
</div>"


I don't know why I can't get the "nombre" value of the database... but it seems I am doing something wrong...

Thank you in advance.

Dani Soto
Reply | Threaded
Open this post in threaded view
|

Re: How to iterate HashMap?

antoniosarco
In reply to this post by Pinocchio
 try use Map Entry

Iterator<Map.Entry<Integer, String>> it = days.entrySet().iterator();
while (it.hasNext()) {
  Map.Entry<Integer, String> pair = it.next();
  System.out.println( pair.getKey() + "   "  + pair.getValue());
}

More about....HashMap

Anto
12