【问题标题】:Iterating HashMap that has a non-string key-pair and ArrayList as a value迭代具有非字符串键对和 ArrayList 作为值的 HashMap
【发布时间】:2017-06-08 10:52:59
【问题描述】:

我通过 Controller 传递以下内容:

HashMap<SomeClassA, ArrayList<SomeClassB>>

SomeClassA 和 SomeClassB 不是原语,由我编写。它们的吸气剂要么是字符串,要么是长整数。让我们将 HashMap 变量称为map123

我想做的是有这样的代码:

<#list map123?keys as key> 
    ${key} = ${map123[key]} 
</#list> 

但是,我得到的是 map123[key] 是 NULL ! 这意味着我无法迭代 ArrayList。

我做错了什么(或者我应该怎么做)?

【问题讨论】:

    标签: arraylist hashmap iterator iteration freemarker


    【解决方案1】:

    这很容易成为 FreeMarker 2 中最有问题的遗留问题,但它有解决方法。 [] 运算符不支持非字符串键。这将是一个错误,但由于与另一个遗留系统的不幸合作,通常会发生查找是使用对象的toString() 静默完成的,因此您根本找不到该项目。

    解决方法:如果您只需要迭代,只需使用至少版本2.3.25-incubating(这是一个稳定的最终版本)并编写:

    <#list map123 as key, value> 
        ${key} = ${value} 
    </#list> 
    

    如果您必须通过键获取值,那么您可以回退到Map 的Java API:map123?api.get(key)。 (请注意,?api 必须在 FreeMarker 配置中显式启用,但错误消息会说明这一点。)

    【讨论】:

    • 我使用的 FreeMarker 版本集成在一个 FrameWork 中,所以除非框架更新,否则我无法更改版本。因此,我必须使用的解决方法是通过仅将 SomeClassA 和 SomeClassB 中我需要的值加入单个 SomeClassC 并将其作为列表传递来即兴发挥。
    • 如果你不能用更高的版本覆盖那个版本(因为框架不仅仅是一个 Maven 依赖项)那么也许最干净的解决方案是公开(或通过?new 引入)一些实用程序TemplateMethodModelEx 实现通过WrapperTemplateModel.getWrappedObject() 将Java Map 从其参数中取出,然后构造所需的结果列表。那么你可以使用&lt;#list mapEntries(map123) as kvp&gt;${kvp.key} = ${kvp.value}之类的东西。
    • 另请注意,?api 是在 FreeMarker 2.3.22 中引入的,这并不是全新的。如果您至少有?api,那么您可以使用&lt;#list map123?api.entrySet() as kvp&gt;${kvp.key} = ${kvp.value}
    • 谢谢,我想昨天只是“一天的结束”,我懒得尝试了。它比 Maven 依赖更复杂,但我认为我的版本足够高。
    【解决方案2】:

    如果您不能使用键值对(自 2.3.25 起)

    <#list map123 as key, value> 
        ${key} = ${value} 
    </#list> 
    

    你可以试试

    <#list map123.entrySet() as entry >
        ${entry.key} = ${entry.value}
    </#list>
    

    您可以使用?exists 指令或仅使用${entry.value!"default"} 轻松检查null

    【讨论】:

      猜你喜欢
      • 2014-10-13
      • 2014-02-26
      • 1970-01-01
      • 2015-01-20
      • 1970-01-01
      • 2013-04-21
      • 2017-06-12
      • 1970-01-01
      • 2012-03-07
      相关资源
      最近更新 更多