Freemarker遍历Set集合

本文针对版本2.3.26-incubating中遇到的Set遍历问题提供了解决方案。通常推荐使用iterator()方法遍历Set集合,但在该版本中采用与List相同的遍历方式,即使用<#listdataSetasdata> ${data}

目前使用版本 2.3.26-incubating

最近遇到Set遍历的问题,网上找到的方案是使用iterator()遍历Set集合。然而在这个版本中,遍历Set的方法与List一样,都是使用

<#list dataSet as data>
    ${data}
</#list>
<think>我们讨论的是FreeMarker模板引擎中如何解析和遍历集合(List、Set、数组等)的语法。 在FreeMarker模板文件(.ftl)中,处理集合通常使用<#list>指令。 基本语法: <#list sequence as item> ...处理每个item... </#list> 其中: sequence:要遍历集合表达式(如:listVar) item:循环变量名,代表当前遍历到的元素 此外,还可以使用一些内置变量: item_index:当前遍历的索引(从0开始) item?index:同上,索引(0-based) item?counter:从1开始的计数(1-based) item?has_next:布尔值,表示当前项是否是集合中的最后一项 示例代码: 假设在Java中,我们向模板传递了一个名为"users"的List<String>: List<String> users = Arrays.asList("Alice", "Bob", "Charlie"); 在ftl中遍历: 同时,FreeMarker还支持遍历时使用else分支,当集合为空时执行: <#list users as user> ${user?counter}. ${user} <#else> 没有用户! </#list> 另外,对于Map集合遍历方式略有不同,可以遍历键值对: <#list map?keys as key> 键:${key},值:${map[key]} </#list> 或者直接遍历值: <#list map?values as value> 值:${value} </#list> 或者同时获取键和值: <#list map as key, value> 键:${key},值:${value} </#list> (注意:这种写法在FreeMarker 2.3.25之后被废弃,推荐使用map?keys或map?values) 实际上,在FreeMarker 2.3.25版本之后,推荐使用以下方式遍历Map: <#list map as key, value> 键:${key},值:${value} </#list> (但官方文档中说明,在2.3.25版本开始,这种语法已被废弃,并建议使用新的语法:) 新的语法是: <#list map> 使用键值对: <#items as key, value> ${key} = ${value} </#items> </#list> 或者更常用的是直接使用: <#list map?keys as key> ${key} = ${map[key]} </#list> 但是注意:在最新版本中,遍历Map的推荐方式是使用?keys或?values,或者使用entries方法(返回键值对的集合): <#list map?entries as entry> 键:${entry.key},值:${entry.value} </#list> 总结一下,集合遍历主要使用<#list>指令,对于不同的集合类型(List、Set、数组、Map)都可以使用,但Map需要特殊处理。 下面是一个完整的示例,展示如何在ftl中解析不同类型的集合: 1. 遍历List(或数组、Set): <#list users as user> ${user} </#list> 2. 遍历Map(推荐方式): <#list userMap?entries as entry> 用户名:${entry.key}, 邮箱:${entry.value} </#list> 3. 遍历时使用索引: <#list users as user> 第${user?index + 1}个用户:${user} </#list> 4. 遍历集合的else分支: <#list users as user> ${user} <#else> No users found. </#list> 5. 遍历并判断是否是最后一项: <#list users as user> ${user}<#if !user?has_next>,</#if> </#list> 注意:在FreeMarker中,集合的索引从0开始,?counter从1开始。 在Java代码中,我们需要将数据模型传递给模板: Map<String, Object> root = new HashMap<>(); root.put("users", Arrays.asList("Alice", "Bob", "Charlie")); root.put("userMap", Collections.singletonMap("alice", "alice@example.com")); // 然后使用模板引擎处理 Configuration cfg = ... // 配置FreeMarker Template template = cfg.getTemplate("template.ftl"); try (StringWriter writer = new StringWriter()) { template.process(root, writer); System.out.println(writer.toString()); } 以上就是在FreeMarker中解析集合的基本语法。</think>### FreeMarker 集合解析语法详解 在 FreeMarker 模板(.ftl 文件)中,解析和遍历集合(List、Set、数组等)主要使用 `list` 指令。以下是核心语法和用法: #### 1. 基础遍历语法 ```ftl <#list animals as animal> ${animal?index + 1}. ${animal} </#list> ``` - `animals`:数据模型中的集合变量 - `animal`:临时迭代变量名 - `?index`:获取当前元素的索引(从 0 开始) #### 2. 完整语法结构 ```ftl <#list sequence as item> ...处理每个item... <#else> ...当集合为空时显示... </#list> ``` - `sequence`:要遍历集合表达式 - `item`:循环变量名 - `else`:集合为空时的备用内容 #### 3. 内置循环变量 | 变量 | 说明 | 示例 | |------------------|-----------------------------------|--------------------------| | `item?index` | 从 0 开始的索引 | `${user?index}` → 0,1,2 | | `item?counter` | 从 1 开始的计数 | `${user?counter}` → 1,2,3 | | `item?has_next` | 是否有下一个元素(布尔值) | `<#if user?has_next>,</#if>` | | `item?is_first` | 是否是第一个元素 | `<#if user?is_first>★</#if>` | | `item?is_last` | 是否是最后一个元素 | `<#if user?is_last>※</#if>` | #### 4. 实际应用示例 ```ftl <#-- 遍历用户列表 --> <#list users as user> <div class="user-card ${user?is_first?then('first', '')}"> <span class="rank">${user?counter}.</span> ${user.name} (${user.age}) <#if user?has_next><hr></#if> </div> <#else> <p>暂无用户数据</p> </#list> <#-- 遍历Map集合 --> <#list userMap?keys as key> 键: ${key}, 值: ${userMap[key]} </#list> <#-- 使用 entries 遍历Map --> <#list userMap?entries as entry> ${entry.key} = ${entry.value} </#list> ``` #### 5. 集合操作函数 ```ftl <#-- 获取集合大小 --> 总用户数: ${users?size} <#-- 集合排序 --> <#list users?sort_by("age") as user> ${user.name} (${user.age}) </#list> <#-- 集合过滤 --> <#list users?filter(user -> user.age > 18) as adult> ${adult.name} </#list> <#-- 分块处理 --> <#list users?chunk(3) as row> <div class="row"> <#list row as user>${user.name}</#list> </div> </#list> ``` #### 6. 复杂对象遍历 ```ftl <#-- 遍历订单及嵌套商品 --> <#list orders as order> <h3>订单 ${order.id}</h3> <ul> <#list order.items as item> <li>${item.name} × ${item.quantity}</li> </#list> </ul> </#list> ``` #### 注意事项: 1. **空值处理**:使用 `!` 防止空指针 ```ftl ${user.address.city!} <#-- 为空时输出空字符串 --> ${user.address.city!"未知"} <#-- 为空时输出默认值 --> ``` 2. **日期格式化**: ```ftl ${order.createTime?string("yyyy-MM-dd HH:mm")} ``` 3. **数值格式化**: ```ftl ${product.price?string.currency} <#-- 货币格式: ¥99.99 --> ${product.rating?string["0.0"]} <#-- 保留一位小数: 4.5 --> ``` 4. **转义HTML**: ```ftl ${unsafeContent?html} <#-- 转义HTML特殊字符 --> ``` > ⚠️ 重要:在 Java 代码中传递集合时,确保对象实现 `TemplateModel` 接口或使用 FreeMarker 的包装器: > ```java > Map<String, Object> data = new HashMap<>(); > data.put("users", Arrays.asList( > new User("Alice", 25), > new User("Bob", 30) > )); > > Configuration cfg = new Configuration(Configuration.VERSION_2_3_31); > cfg.setDirectoryForTemplateLoading(new File("/templates")); > Template template = cfg.getTemplate("user_list.ftl"); > > try (Writer out = new FileWriter("output.html")) { > template.process(data, out); > } > ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newcih

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值