【问题标题】:JSTL - Using forEach to iterate over a user-defined class [duplicate]JSTL - 使用 forEach 迭代用户定义的类 [重复]
【发布时间】:2011-02-28 01:02:21
【问题描述】:

我需要向自定义 Java 类添加哪些方法,以便可以迭代其中一个成员中的项目?我找不到任何关于 JSTL forEach 标记实际工作方式的规范,所以我不确定如何实现。

例如,如果我创建了一个通用的“ProjectSet”类并且我想在 JSP 视图中使用以下标记:

<c:forEach items="${projectset}" var="project">
...
</c:forEach>

基本类文件:

public class ProjectSet {
    private ArrayList<Project> projects;
    public ProjectSet() {
        this.projects = new ArrayList<Project>();
    }
    // .. iteration methods ??
}

我是否必须实现任何接口,如 PHP 的 ArrayAccessIterator 才能使其工作?

编辑:不直接访问 ArrayList 本身,因为我可能会使用某种使用泛型的 Set 类,并且 JSP 视图不必知道该类的内部工作原理。

【问题讨论】:

    标签: java jsp jstl iteration jsp-tags


    【解决方案1】:

    Iterable 接口提供了这个功能:

    public class ProjectSet implements Iterable<Project> {
        private ArrayList<Project> projects;
        public ProjectSet() {
            this.projects = new ArrayList<Project>();
        }
    
        // .. iteration methods ??
       @Override
       public Iterator<Project> iterator() {
           return projects.iterator();
       }
    }
    

    您可以根据需要交换迭代器逻辑。

    【讨论】:

    • 需要注意的是,JSTL forEach 不支持可迭代(非常烦人)作为 forEach 类型。所以你需要做 ${projectSet.iterator()}
    • 其实 .iterator() 只能在最新的 Servlet Container 上工作(甚至最新的 JSTL 仍然不支持可迭代)。您需要为迭代器 ( getIterator() ) 创建一个 getter。
    【解决方案2】:

    是的,你应该实现java.util.Iterable

    【讨论】:

      【解决方案3】:

      很遗憾,forEach 标签不支持将Iterable 作为项目来源。它确实支持:

      • 数组
      • Collection
      • Iterator
      • Enumeration
      • Map
      • String 中给出的以逗号分隔的值列表

      (相关源码:ForEachSupport

      其中,当您希望从自己的类中获取项目时,最好使用Iterator 作为forEach 源。

      【讨论】: