Java for Web学习笔记(二四):EL(4)流(Stream)
2016-06-22 22:28
507 查看
这个假期,几家在装修,很吵,说是不准节假日装修,谁理。我觉得中国房子的质量除了90年代的比较差外,很大程度都是装修给搞坏的,这家抡大锤,那家掀地板。就是个碉堡,也有毁坏的日子。
例子一:test0()和test1()是一样的,采用了Lambda表达方式写:
例子二:提供一个元素类型比较复杂的例子
sorted()
排序。对于数字,可以直接使用sorted进行排序,对于一些复制的元素,可以如同 java.util.Comparator<E>进行排序,例如我们已经将request.setAttribute("books", books);在EL如下操作:
limit()和substream()
取部分元素,limit是前多少个,substream()是从多少到多少。numbers是[0, 1, 2, 3, 4, 5, 6],EL如下:
map()
map可以将Stream<A>转换为Stream<B>,例如
假设books中含有(Title A, AuthorA)和(Title B,Author B)两本书,则输出:
我们还可以转成其他的类。
可以使用toArray和toList返回,返回String[]和List<String>,不过在html中直接输出Object[]会显示一个对象地址,要显示,需要指定具体那个元素。List具有toString(),可以直接显示内容,在之前的例子可以看到。
可以使用iterator获取一个java.util.Iterator。
使用Aggregate函数
count()可以获取元素的个数,sum()可以求和,可以直接输出结果。
average()要求元素是数,min()和max()要求元素可比较,它们返回都是org.apache.el.stream.Optional的对象Optional<E>,不能直接输出(给出的是地址),需要通过get()获取object的内容。Optional<E>表明可以为null。
返回Frist Value
findFirst()返回Optional<E>,第一个元素。
相关链接:
我的Professional Java for Web Applications相关文章
什么是流
对于Collection提供stream,也就是包括List(例如Vector,ArrayList,LinkedList),Set(如HashSet,LinkedHashSet,TreeSet)。流的处理一般如下:Java 8中的流
在看EL如何支持流,我们先看看Java8中的Stream。例子一:test0()和test1()是一样的,采用了Lambda表达方式写:
public void test0(){ List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Stream<Integer> stream = numbers.stream(); stream.filter((x) -> { return x % 2 == 0; }).map((x) -> { return x * x; }).forEach(System.out::println); } public void test1(){ List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Stream<Integer> stream = numbers.stream(); stream.filter(x -> x % 2 == 0 ) .map(x -> x * x) .forEach(System.out::println); }
例子二:提供一个元素类型比较复杂的例子
public class Book{ private String title; private String author; …… getter & setter…… public String toString(){ return "Title("+title+"):Author("+author+")"; } } private void testStream(){ Collection<Book> db = new Vector<>(); … 加入元素,从略 … // 测试1:进行过滤(title中含有A的),然后将过滤后的打印出来 db.stream().filter(x->x.getTitle().contains("A")) .forEach(System.out::println); // 测试2:进行过滤(title中含有A的),然后将过滤后的提取某些部分(类型变成String) // 对于stream进行intermediate操作时,会改变stream,但不会改变原来的数据,即不会改变db,因此我们再次进行db.stream()即可。 db.stream().filter(x->x. getTitle().contains("A")) .map(x->x.getAuthor()) //相当于 (x)->{return x.getAuthor();} .forEach(System.out::println); // 测试3:进行过滤(title中含有A的),然后将过滤后进行重新处理map,将结果输出为Array // 此处如果采用String[] authors,进行类型转换,会出现错误ClassCastException,应在元素时作转换 Object[] authors = (Object[]) db.stream().filter(x->x. getTitle().contains("A")) .map(x->x.getAuthor()) .toArray(); for(Object obj :authors){ System.out.println((String)obj); } }
EL中的Stream
Intermediate操作
EL3.0支持Stream,但EL 3.0是运行在Java 7中的,因此采用了EL自己实现的Stream API。下面是一个例子:books.stream().filter(b->b.title == 'Professional Java for Web Applications') .map(b->{ 'title':b.title, 'author':b.author }) .toList();
filter()
流化后得到Stream<E>,E为元素类型,filter进行过滤,采用Lambda表达式,有一个预设的参数Predicate<E>,返回boolean的判断,只有返回为true的元素才被留在stream中。distinct()
去除相同的元素。${[1, 2, 3, 3, 4, 5, 5, 5, 5, 6].stream().distinct().toList()}
forEach()
对每个元素进行操控,不返回值。下面是一个java例子,打印每个元素的平方。public void test3(){ List<Integer> numbers = Arrays.asList(1, 2, 3, 3, 5, 5, 5, 5, 5, 10); Stream<Integer> stream = numbers.stream(); stream.distinct() .forEach(x->System.out.println(x*x)); }
sorted()
排序。对于数字,可以直接使用sorted进行排序,对于一些复制的元素,可以如同 java.util.Comparator<E>进行排序,例如我们已经将request.setAttribute("books", books);在EL如下操作:
${[8, 3, 19, 5, 7, -2, 0].stream().sorted()} <br/> ${books.stream().sorted((b1,b2) -> b1.title.compareTo(b2.title)).toList()}
limit()和substream()
取部分元素,limit是前多少个,substream()是从多少到多少。numbers是[0, 1, 2, 3, 4, 5, 6],EL如下:
${numbers.stream().sorted().limit(3).toList()} <br/> <!-- 显示[0, 1, 2] --> ${numbers.stream().sorted().substream(2,5).toList()} <!-- 显示[2, 3, 4] -->
map()
map可以将Stream<A>转换为Stream<B>,例如
<!-- 1、map将Stream<Book>转换为Stream<String> --> ${books.stream().map(b -> b.title).toList()} <!-- 2、map将Stream<Book>转换为Stream<List<Object>> --> ${books.stream().map(b -> [b.title, b.author]).toList()} <!-- 3、map转为Stream<Map<Object,Object> --> ${books.stream().map(b -> {"title":b.title, "author":b.author}).toList()}
假设books中含有(Title A, AuthorA)和(Title B,Author B)两本书,则输出:
[Title A, Title B] [[Title A, Author A], [Title B, Author B]] [{author=Author A, title=Title A}, {author=Author B, title=Title B}]
我们还可以转成其他的类。
Terminal操作
返回Collection可以使用toArray和toList返回,返回String[]和List<String>,不过在html中直接输出Object[]会显示一个对象地址,要显示,需要指定具体那个元素。List具有toString(),可以直接显示内容,在之前的例子可以看到。
${books.stream().map(b -> b.title).toArray()} 显示 [Ljava.lang.Object;@d8cd02 ${books.stream().map(b -> b.title).toArray()[0]} 显示Title A
可以使用iterator获取一个java.util.Iterator。
使用Aggregate函数
count()可以获取元素的个数,sum()可以求和,可以直接输出结果。
average()要求元素是数,min()和max()要求元素可比较,它们返回都是org.apache.el.stream.Optional的对象Optional<E>,不能直接输出(给出的是地址),需要通过get()获取object的内容。Optional<E>表明可以为null。
${cartItems.stream().map(i -> i.price() * i.quantity()).sum()} ${books.stream().map(b->b.price).min().get()} ${numbers.stream().average().get()}
返回Frist Value
findFirst()返回Optional<E>,第一个元素。
例子
我们以使用前面User类,设置里面元素并request.setAttribute("users", users),具体从略。下面看看jsp的代码。先过滤只剩名字含有“1”的,然后按名字排序,重新组成新的流,返回List,利用List里面的System.out输出结果。…… <body> ${users.stream().filter(u->fn:contains(u.username,'1')) .sorted((u1,u2)->(x = u1.lastName.compareTo(u2.lastName); x == 0 ? u1.firstName.compareTo(u2.firstName):x)) .map(u->{'username':u.username,'first':u.firstName,'last':u.lastName}) .toList()}<br/> </body> </html>
相关链接:
我的Professional Java for Web Applications相关文章
相关文章推荐
- 08.Java 集合 - HashSet
- java位运算
- Spring中Bean的生命周期
- 第一章 分布式系统介绍
- Java的接口和抽象类
- Eclipse console 中文乱码解决
- Java之IO
- Spring IOC容器实现
- java实现了简单的Echo服务程序分服务器和客户端
- Spring设计目标以及架构
- 《Thinkinginjava》第7章-复用类
- java参数传递(超经典)
- java死锁代码示例
- 07.Java 集合 - HashTable
- 1.spring-mvc 源代码(.jar)
- spring集合类型的setter注入的一个简单例子
- spring单例和多例详解。如何在单例中调用多例对象
- java动态代理
- java 基础知识问题集
- Eclipse项目导入Android Studio,.9图片报错解决办法