Lambda表达式-聚合操作

文章参考自博客:https://www.cnblogs.com/franson-2016/p/5593080.html

以及学习网站:how2java.cn

1.传统方式和聚合操作遍历数据的不同

传统遍历List的方式如下:

for(Hero h:list){
if(h.getAge()>50 && h.getId()<400)
System.out.println(h.getName());
}

而使用了聚合操作的方式如下:

list
.stream()
.filter( h-> h.getAge()>50 && h.getId()<400)
.forEach(h-> System.out.println(h.getName()));

2.Stream(流)是什么?

Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。 同样,Stream使用懒运算,他们并不会真正地读取所有数据,遇到像getFirst() 这样的方法就会结束链式语法。

Stream和Collection结构化的数据不同,Stream有一系列的元素

管道指的是一系列的聚合操作的总和

管道由三部分组成:管道源中间操作结束操作

(1)管道源: 其可以是一个集合,一个数组,一个生成器函数或一个I / O通道

//管道源是一个集合
list
.stream()
.forEach(h-> System.out.println(h.getName())); //管道源是一个数组
Hero array[] = list.toArray(new Hero[list.size()]); Arrays.stream(array)
.forEach(h-> System.out.println(h.getName()));

(2)零个或多个中间操作:  每个中间操作会返回一个流,如filter,中间操作时懒操作,不会真正遍历

中间操作有很多种,主要分为两种:

1.对元素进行筛选:filter(匹配),distinct(去除重复),sorted(自然排序)

sorted(Comparator)(指定排序),limit(保留),skip(忽略)

2.转为其他形式的流:mapToDouble(转为double的流), map(转换为任意类型的流)

(3)结束操作:  例如forEach,会返回非流结果,例如基本类型的值(int,float,double)、对象或者集合,或者在终端操作为forEach的情况下没有返回值。

结束操作时才真正进行遍历行为,前面的中间操作也在这个时候真正的执行。

常见的结束操作如下:

forEach()(遍历每个元素),toArray()(转换为数组),min(Comparator)(取最小的元素)

max(Comparator)(取最大的元素),count()(总数),findFirst()(第一个元素)

3.具体用例

首先创建一个100个元素的表,用随机数填充其年龄和ID

Random r = new Random(System.currentTimeMillis());
List<Hero> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(new Hero("hero-"+i,r.nextInt(500),r.nextInt(100)));
}

然后执行各种中间操作:

        //用filter筛选满足条件的对象,并进行操作
list
.stream()
.filter(h-> h.getId()<300 && h.getAge()>50)
.forEach(h-> System.out.println(h)); //用distinct去除重复元素
list
.stream()
.distinct()
.forEach(h-> System.out.print(h)); //用sorted进行排序
list
.stream()
.sorted((h1,h2) -> h1.getAge()>h2.getAge() ? 1:-1)
.forEach(h-> System.out.println(h)); //用limit保留三个元素
list
.stream()
.limit(3)
.forEach(h-> System.out.println(h)); //用skip忽略前三个元素
list
.stream()
.skip(3)
.forEach(h-> System.out.println(h)); //用mapToDouble转换为Double的Stream
list
.stream()
.mapToDouble(Hero::getAge)
.forEach(h-> System.out.println(h)); //转换为任意类型的Stream
list
.stream()
.map((h)-> h.getName()+"-"+h.getAge()+"-"+h.getId())
.forEach(h-> System.out.println(h));

终端操作(结束操作)的用例如下:

        //用forEach遍历集合
list
.stream()
.forEach(h-> System.out.println(h)); //用toArray将表变为数组
Object[] arrays = list
.stream()
.toArray(); //用min得到最小值
Hero h1 = list
.stream()
.min((hf,hs)->hf.getAge()-hs.getAge())
.get(); //用max得到最大值
Hero h2 =list
.stream()
.max((hf,hs) -> hf.getAge()-hs.getAge())
.get(); //用count计算流中的数据总数
long count = list
.stream()
.count(); //用findFirst得到第一个元素
Hero h3 = list
.stream()
.findFirst()
.get();

测试用例:

 Hero h = list
.stream()
.sorted((h1,h2)-> h1.getAge()>h2.getAge() ? -1:1)
.skip(2)
.findFirst()
.get();
上一篇:jquery自定义函数


下一篇:How Many Tables--hdu1213(并查集)