How do I iterate over a hashmap in Freemarker. I am using the 2.3.23 version and I am unable to get the value from the hashmap. I am using the following:
<#list hashMap?keys as key>
${key} = ${hashMap.get(key)}
<#list>
I have even tried the following:
<#list hashMap?keys as key>
${key} = ${hashMap[key]}
<#list>
It says that the value is null. However, I checked the data and there is a value for every key. I cannot upgrade the freemarker version to 2.3.25
Could someone help me with this.
Usually, the problem is that your keys aren't String-s, but some Java objects other than mere numbers/dates/booleans. Such "miscellaneous" objects are usable as FTL strings, so that you can print them directly (and internally that calls obj.toString()). Thus hashMap[key] won't complain that key is not a FTL string (because it is), instead it basically does hashMap.get(key.toString()), and there you have your null.
Since you can't update to 2.3.25, where you could use <#list hashMap as key, value>, you have to use ?api (and I hope you can enable calling ?api in the configuration):
<#list hashMap?api.entrySet() as ent>
${ent.key} = ${ent.value}
</#list>
Related
I want to access any index of a HashMap to retrieve an Id through this code:
th:text="'Network Id: ' + ${poolHashrates[0].key.networkHashrate.id}"
poolHashrates is a HashMap,
networkHashrate is a separate variable in key variable
Basically, all the networkHashrates in key have the same Id, so I could actually access any element, no matter what the index is.
I've also tried:
th:text="'Network Id: ' + ${poolHashrates.get(key).networkHashrate.id}"
th:text="'Network Id: ' + ${poolHashrates['key'].networkHashrate.id}"
None of these works. I keep getting
Exception evaluating SpringEL expression: "poolHashrates['key'].networkHashrate.id"
or
SpelEvaluationException: EL1007E: Property or field 'networkHashrate' cannot be found on null
I was able to print the Id in Intellij console, so it apparently exsists.
So you want to get an element out of the HashMap without knowing any of the keys? I think that's kind of silly... but it is possible. Here is one such way:
<span th:text="${poolHashrates.get(poolHashrates.keySet().toArray()[0])}" />
That will get you an element of the poolHashrates HashMap. I'm still unclear why you keep talking about key, but never really define what you mean. Is key really a property (with a getKey() and setKey()) on whatever you are storing in your HashMap? If so, then your final expression would look like this:
<span th:text="${poolHashrates.get(poolHashrates.keySet().toArray()[0]).key.networkHashrate.id}" />
or maybe
<span th:text="${poolHashrates.get(poolHashrates.keySet().toArray()[0]).networkHashrate.id}" />
(Are you confusing .key with a variable you get when you iterate over a HashMap with th:each in Thymeleaf?)
I want to loop over the MultiMap in Freemarker template and access(display) the key and its distinct values(which are objects in this case):
Here TaskType is a String (dont misunderstand)
multiMap.put(TaskType.DHOLDING_TASK,Obj1);
multiMap.put(TaskType.BTRADE_TASK,Obj2);
multiMap.put(TaskType.ANONE,Obj3);
multiMap.put(TaskType.DHOLDING_TASK,Obj4);
multiMap.put(TaskType.CPRICE_TASK,Obj5);
multiMap.put(TaskType.BTRADE_TASK,Obj6);
multiMap.put(TaskType.ANONE,Obj7);
multiMap.put(TaskType.CPRICE_TASK,Obj8);
The output will look like this of teh MultiMap:
{CPRICE_TASK=[Obj5, Obj8], ANONE=[Obj3, Obj7], BTRADE_TASK=[Obj2, Obj6], DHOLDING_TASK=[Obj1, Obj4]}
My freeMarker code :
<#assign taskKeys = multiMap?keys >
<#list taskKeys as key>
${key} --It works fine till here :-)
`taskList[key] or taskList[key_values]---XXX both gives exception
How to display the multivalues associated with the key here in list???
I need to access the value part o fthe pair here(i.e. the RHS) : CPRICE_TASK=[Obj5, Obj8]
A help is much appreciated :)
Thanks ddekany for the reply.. :)
However, I could find the answer, It was mistake in freemarker code..I iterate over the keys as
<#list taskList?keys as taskType>
which is fine ..After that I should be iterating over the list associated with the key (i.e the multiple values)as it is a google multimap.Like:
<#assign values = taskList?values>
<#list values[taskType_index] as task>
I guess I was missing the assign tag in my code..while accessing the values of the keys.
Hope this will help some one.
I want to iterate a List nested in a Map, the data structure is like:
Map<Integer, List<Integer>> groups = new TreeMap<>()
// Some code else to put values into groups ...
Freemarker template:
<#list groups?keys as groupKey>
${groupKey} // It's OK here.
<#list groups[groupKey] as item> // Exception threw here, detail message is pasted below
${item}
</#list>
</#list>
Detail exception message:
FreeMarker template error:
For "...[...]" left-hand operand: Expected a sequence or string or something automatically convertible to string (number, date or boolean), but this evaluated to an extended_hash (wrapper: f.t.SimpleHash):
==> groups
So, what is the problem?
P.S.
I have tried groups.get(groupKey) instead of groups[groupKey], it throws a new Exception stack:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
java.lang.String.compareTo(String.java:108)
java.util.TreeMap.getEntry(TreeMap.java:346)
java.util.TreeMap.get(TreeMap.java:273)
freemarker.template.SimpleHash.get(SimpleHash.java:160)
freemarker.core.Dot._eval(Dot.java:40)
freemarker.core.Expression.eval(Expression.java:76)
The problem in the original question is that FTL's hash type is not like Map. It's a collection of "variables", that is, the keys must be String-s. (Even that ?keys works is a glitch in BeansWrapper... though now it comes handy.) Since the key is a number, FTL assumes that you want to get an item from a sequence (a List or array), or that you want to get a character from a string, hence the original error message.
The solution is using the Java API-s, like get in Dev-an's answer. (On the long term FTL meant to introduce the map type, so all this problems with non-string keys will end, but who knows when that will be...)
Update: Since 2.3.22 there's ?api to access the Java API of objects, like myMap?api.get(nonStringKey). However, it's by default not allowed (see the api_builtin_enabled configuration setting and more in the Manual: http://freemarker.org/docs/ref_builtins_expert.html#ref_buitin_api_and_has_api). Also note that as Java maps are particular about the numerical type, if the key is not an Integer coming from a Java, you have to use myMap?api.get(myNumericalKey?int).
Try the following:
<#list groups?keys as groupKey>
${groupKey}
<#list groups.get(groupKey) as item>
${item}
</#list>
</#list>
I'm trying to convert a large Map> to some JavaBean. The key of map corresponds to some property of JavaBean, and the value somehow is decoded to property value. So I decided to use some util for that, but don't know what will work. There are some requirements I have to this util (or framework):
all configuration must be in separate files
should be a possibility to map dynamic quantity of keys:
there is a map:
key | value
quan | n
key_1| value_1
key_2| value_2
........ | .............
key_n| value_n
where n - is any number
and the JavaBean has a List of some beans. They have a property. value_1, value_2, ... must be mapped in this property, and in the end there must be so much beans in list, as these keys and values in map.
3.. should be a possibility to set up custom decoder for property mapping, because in most cases the value in map is a List with 1 value, so I need to get the first item of list (if it's not empty).
4.. should be a possibility run some script to execute extraordinary mappings, for example:
there is a map, that is described in 2d point.
and the JavaBean has a property of type HashMap, where value_1 is mapped to Bean1 and some analogous value from input map is mapped to Bean2.
I've tried to use smooks, but when I've started, all these requirements were not clear yet and the smooks was something new, I haven't worked with it until now. So the smooks config doesn't contain the whole business-logic (because of second req.) and looks ugly, I don't like that. I can show the most ugliest fragment for 2d point:
<jb:bean beanId="javaBean" class="com.example.JavaBean" createOnElement="map">
<jb:wiring property="someBeans" beanIdRef="someBeanItems"/>
</jb:bean>
<jb:bean beanId="someBeanItems" class="java.util.ArrayList" createOnElement="map/entry">
<jb:wiring beanIdRef="someBeanItem"/>
</jb:bean>
<jb:bean beanId="someBeanItem" class="com.example.someBeanItem" createOnElement="map/entry">
<condition>map.quan[0]>0</condition>
<jb:expression property="property1">
index = map.quan[0]-1;
value = additionalProperties.property1_List[index];
map.quan[0] = map.quan[0] - 1;
return value;
</jb:expression>
</jb:bean>
Here "property1_List" is builded before executing smooks.
Now I look for something more nice and need your help: maybe you know how to make that better using smooks? Or what another frameworks for mapping can you recommend for my issue?
I have a plain hashmap with numeric values and would like to retrieve its content, ideally in a list (but that can be worked out).
Can it be done?
Try this:
library(rJava)
.jinit()
# create a hash map
hm<-.jnew("java/util/HashMap")
# using jrcall instead of jcall, since jrcall uses reflection to get types
.jrcall(hm,"put","one", "1")
.jrcall(hm,"put","two","2")
.jrcall(hm,"put","three", "3")
# convert to R list
keySet<-.jrcall(hm,"keySet")
an_iter<-.jrcall(keySet,"iterator")
aList <- list()
while(.jrcall(an_iter,"hasNext")){
key <- .jrcall(an_iter,"next");
aList[[key]] <- .jrcall(hm,"get",key)
}
Note that using .jrcall is less efficient than .jcall. But for the life of me I can not get the method signature right with .jcall. I wonder if it has something to do with the lack of generics.
I have never done this myself, but there is an example in the rJava documentation of creating and working with a HashMap using the with function:
HashMap <- J("java.util.HashMap")
with( HashMap, new( SimpleEntry, "key", "value" ) )
with( HashMap, SimpleEntry )