Standard Deviation: An Illustration of Expression Language 3.0 in Servlet Environment
Expression Language (EL) was first introduced as part of JSTL 1.0, was then moved JSP 2.0 and was unified with JSF 1.2 in JSP 2.1. In Java EE 7, EL is a new separate JSR, JSR 341. Many new features are introduced in EL 3.0.
This blog shows how to use new following new features of EL 3.0:
- Standalone environment
- Lambda expression (section 1.20 of EL 3.0 spec)
- The new operator
;
to separate statements - Retrieval of a
Stream
from aCollection
(section 2.3.1 of EL 3.0 spec) - The use of a static field and method, for instance,
Math.sqrt
This blog also shows how to use new operations to calculate a standard deviation in the following different ways:
- Using
count
,sum
andmap
- Using
forEach
- Using
reduce
(see section 2.3.17 of EL 3.0 spec)
I would like to thank Kinman Chung, the EL specification lead, for useful discussion.
The following example shows some of the new EL features.
public class ELTestServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
List list = new ArrayList<>();
list.add(Double.valueOf(1.0));
list.add(Double.valueOf(2.0));
list.add(Double.valueOf(3.0));
ELProcessor elp = new ELProcessor();
elp.defineBean("data", list);
Object message = (Double)elp.eval(
"n = data.stream().count(); s = data.stream().sum(); sq = data.stream().map(i -> i*i).sum(); Math.sqrt(sq/n - Math.pow(s/n, 2))");
res.getWriter().println(message);
message = (Double)elp.eval(
"n = 0; s = 0; sq = 0; data.stream().forEach(d -> (n = n + 1; s = s + d; sq = sq + d*d)); Math.sqrt(sq/n - Math.pow(s/n, 2))");
res.getWriter().println(message);
message = (Double)elp.eval(
"n = 0; s = 0; sq = data.stream().reduce(0, (a, i) -> (n = n + 1; s = s + i; a + i*i)); Math.sqrt(sq/n - Math.pow(s/n, 2))");
res.getWriter().println(message);
}
}
We will use EL in a servlet as a standalone environment. In this case, an ELProcessor
is created and beans are defined as follows:
ELProcessor elp = new ELProcessor();
elp.defineBean("data", list);
An EL can be evaluated by using elp.eval(...)
.
EL Example 1: Using count, sum and map
n = data.stream().count();
s = data.stream().sum();
sq = data.stream().map(i -> i*i).sum();
Math.sqrt(sq/n - Math.pow(s/n, 2))
For a given collection,
stream()
allows access to the corresponding Stream
.
Then count()
and sum()
can be called on the Stream
to count the number of elements and compute the sum of elements in the associated collection.
For data.stream().map(i -> i*i)
, a Lambda expression is used. In this case, the expression changes each value in the Stream
to its square.
EL Example 2: Using forEach
n = 0; s = 0; sq = 0;
data.stream().forEach(d -> (n = n + 1; s = s + d; sq = sq + d*d));
Math.sqrt(sq/n - Math.pow(s/n, 2))
This EL uses
forEach
for a stream
. The count, sum and sum of squares are computed at the same time. Note that the variables n
, s
and sq
are defined in EL Example 1. We need to reset them to initial values in the given ELProcessor
.
EL Example 3: Using reduce
n = 0; s = 0;
sq = data.stream().reduce(0, (a, i) -> (n = n + 1; s = s + i; a + i*i));
Math.sqrt(sq/n - Math.pow(s/n, 2))
In this example,
reduce
is used to compute the count, sum and sum of squares. In the second line, the first argument of reduce
is the initial value of the seed
variable a
. The result of the expression is assigned back to the variable sq
for subsequent computation.
We can learn more about EL 3.0 by looking at the specification in JSR 341. EL 3.0 is available at java.net and is part of GlassFish 4.0.
- Login or register to post comments
- Printer-friendly version
- swchan2's blog
- 3186 reads