Вычислите полную сумму всех чисел в c:forEach цикле

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

17
задан BalusC 1 July 2016 в 07:17
поделиться

5 ответов

Примечание: Я пытался комбинировать ответы для вхождения во всесторонний список. Я упомянул имена в соответствующих случаях для предоставления кредита, где это должно.

Существует много способов решить эту проблему с профессионалами/недостатками, связанными с каждым:

Чистое решение JSP

Как упомянутый выше ScArcher2, очень легкое и простое решение проблемы состоит в том, чтобы реализовать его непосредственно в JSP как так:

<c:set var="ageTotal" value="${0}" />
<c:forEach var="person" items="${personList}">
  <c:set var="ageTotal" value="${ageTotal + person.age}" />
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${ageTotal}

Проблема с этим решением состоит в том, что JSP становится сбивающим с толку до такой степени, когда, Вы, возможно, также представили scriplets. Если Вы ожидаете, что все смотрящие на страницу смогут следовать за элементарной логикой, существующей, это - прекрасный выбор.

Чистое решение EL

Если Вы уже находитесь на EL 3.0 (Java EE 7 / Сервлет 3.1), используйте новую поддержку потоков и лямбд:

<c:forEach var="person" items="${personList}">
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${personList.stream().map(person -> person.age).sum()}

JSP EL Functions

Другой способ произвести общее количество, не вводя scriplet код в Ваш JSP состоит в том, чтобы использовать функцию EL. Функции EL позволяют Вам называть общедоступный статический метод в общедоступном классе. Например, если требуется выполнить итерации по набору, и суммировать значения Вы могли бы определить общедоступный статический метод, названный суммой (Перечислите людей) в общедоступном классе, возможно, названном PersonUtils. В Вашем tld файле Вы поместили бы следующее объявление:

<function>
  <name>sum</name>
  <function-class>com.example.PersonUtils</function-class>
  <function-signature>int sum(java.util.List people)</function-signature>
</function> 

В Вашем JSP Вы записали бы:

<%@ taglib prefix="f" uri="/your-tld-uri"%>
...
<c:out value="${f:sum(personList)}"/>

JSP EL Functions обладает несколькими преимуществами. Они позволяют Вам использовать существующие методы Java без потребности кодировать к определенному UI (Пользовательские Библиотеки тегов). Они также компактны и не смутят ориентированную личность непрограммирования.

Пользовательский тег

Еще одна опция является к самокрутке пользовательским тегом. Эта опция включит большую часть установки, но даст Вам, что я думаю, что Вы по существу ищете, absolutly никакой scriptlets. Хорошее учебное руководство для использования простых пользовательских тегов может быть найдено по http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags5.html#74701

Включенные шаги включают разделение на подклассы TagSupport:

public PersonSumTag extends TagSupport {

   private List personList;

   public List getPersonList(){
      return personList;
   }

   public void setPersonList(List personList){
      this.personList = personList;
   }

   public int doStartTag() throws JspException {
      try {
        int sum = 0;
        for(Iterator it = personList.iterator(); it.hasNext()){
          Person p = (Person)it.next();
          sum+=p.getAge();
        } 
        pageContext.getOut().print(""+sum);
      } catch (Exception ex) {
         throw new JspTagException("SimpleTag: " + 
            ex.getMessage());
      }
      return SKIP_BODY;
   }
   public int doEndTag() {
      return EVAL_PAGE;
   }
}

Определите тег в tld файле:

<tag>
   <name>personSum</name>
   <tag-class>example.PersonSumTag</tag-class>
   <body-content>empty</body-content>
   ...
   <attribute>
      <name>personList</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.util.List</type>
   </attribute>
   ...
</tag>

Объявите taglib на вершине Вашего JSP:

<%@ taglib uri="/you-taglib-uri" prefix="p" %>

и использование тег:

<c:forEach var="person" items="${personList}">
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
<p:personSum personList="${personList}"/>

Тег дисплея

Как zmf упомянутый ранее, Вы могли также использовать тег дисплея, хотя необходимо будет включать соответствующие библиотеки:

http://displaytag.sourceforge.net/11/tut_basic.html

38
ответ дан 30 November 2019 в 10:59
поделиться

Вы пытаетесь сложить все возрасты?

Вы могли вычислить его в своем контроллере и только отобразить результат в jsp.

Можно записать пользовательский тег, чтобы сделать вычисление.

Можно вычислить его в jsp, использующем jstl как это.

<c:set var="ageTotal" value="${0}" />
<c:forEach var="person" items="${personList}">
  <c:set var="ageTotal" value="${ageTotal + person.age}" />
  <tr><td>${person.name}<td><td>${person.age}</td></tr>
</c:forEach>
${ageTotal}
4
ответ дан 30 November 2019 в 10:59
поделиться

ScArcher2 имеет самое простое решение . Если бы Вы хотели что-то максимально компактное, то Вы могли бы создать библиотеку тегов с функцией "суммы" в нем. Что-то как:

class MySum {
public double sum(List list) {...}
}

В Вашем TLD:

<function>
<name>sum</name>
<function-class>my.MySum</function-class>
<function-signature>double sum(List)</function-signature>
</function>

В Вашем JSP, у Вас было бы что-то как:

<%@ taglib uri="/myfunc" prefix="f" %>

${f:sum(personList)}
1
ответ дан 30 November 2019 в 10:59
поделиться

Тег дисплея выезда. http://displaytag.sourceforge.net/11/tut_basic.html

3
ответ дан 30 November 2019 в 10:59
поделиться

Это - немного hacky, но в Вашем коде контроллера Вы могли просто создать фиктивный объект Человека с общим количеством в нем!

, Как Вы получаете свои объекты? HTML позволяет Вам установить < TFOOT> элемент, который будет находиться у основания любых данных, которые Вы имеете, поэтому Вы могли просто установить общее количество отдельно от объектов Человека и произвести его на странице как есть без любого вычисления на странице JSP.

0
ответ дан 30 November 2019 в 10:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: