[jakarta-ee] How to select the first element of a set with JSTL?

I managed to do it with the next code but there must be an easier way.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>


<c:if test="${fn:length(attachments) > 0}">
    <c:forEach var="attachment" items="${attachments}" varStatus="loopCount">
        <c:if test="${loopCount.count eq 1}">
         attachment.id
        </c:if>
    </c:forEach>
</c:if>

This question is related to jakarta-ee jstl

The answer is


Look here for a description of the statusVar variable. You can do something like below, where the "status" variable contains the current status of the iteration. This is very useful if you need special annotations for the first and last iteraton. In the case below I want to ommit the comma behind the last tag. Of course you can replace status.last with status.first to do something special on the first itteration:

<td>
    <c:forEach var="tag" items="${idea.tags}" varStatus="status">
        <span>${tag.name not status.last ? ', ' : ''}</span>
    </c:forEach>
</td>

Possible options are: current, index, count, first, last, begin, step, and end


Sets have no order, but if you still want to get the first element you can use the following:

<c:forEach var="attachment" items="${attachments}" end="0">
     <c:out value="${attachment.id} />
</c:forEach>

Since i have have just one element in my Set the order is not important So I can access to the first element like this :

${ attachments.iterator().next().id }

If you only want the first element of a set (and you are certain there is at least one element) you can do the following:

<c:choose>
    <c:when test="${dealership.administeredBy.size() == 1}">
        Hello ${dealership.administeredBy.iterator().next().firstName},<br/>
    </c:when>
    <c:when test="${dealership.administeredBy.size() > 1}">
        Hello Administrators,<br/>
    </c:when>
    <c:otherwise>
    </c:otherwise>
</c:choose>

Work for arrays and lists only, not for set.


Using ${mySet.toArray[0]} does not work.

I do not think it is possible without having forEach loop at least one iteration.


You can use the EL 3.0 Stream API.

<div>${attachments.stream().findFirst().get()}</div>

Be careful! The EL 3.0 Stream API was finalized before the Java 8 Stream API and it is different than that. They can't sunc both apis because it will break the backward compatibility.


Using begin and end seemed to work for me to select a range of elements. This gives me three separate lists. The first list with items 1-9, second list with items 10-18, and the last list with items 11-25.

                    <ul>
                        <c:forEach items="${actionBean.top25Teams}" begin="0" end="8" var="team" varStatus="counter">
                            <li>${team.name}</li>                               
                        </c:forEach> 
                    </ul>

                    <ul>
                        <c:forEach items="${actionBean.top25Teams}" begin="9" end="17" var="team" varStatus="counter">
                            <li>${team.name}</li>                               
                        </c:forEach> 
                    </ul>

                    <ul>
                        <c:forEach items="${actionBean.top25Teams}" begin="18" end="25" var="team" varStatus="counter">
                            <li>${team.name}</li>                               
                        </c:forEach> 
                    </ul>