java 8 Stream 详解

2018-02-27 11:54:26来源:oschina作者:木九天人点击

分享

1.jdk8 的主要新特性是 主要四个:Lambda,Stream,Date,注解 今天将前两个,这两个也是一起用的,主要用于集合中。


一、Lambda


主要用于匿名内部类中的一个升级版本,通常我们如果筛选一个集合的实体类的情况下,比如筛选全班星座为天秤座的学生。首先这下面是一个公共类Student


import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class Student {
private String name;
private String sex;
private intsalary;
private intage;
private String star; //星座
public Student(){}
public Student(String name,String sex,int salary,int age,String star){
this.name = name;
this.sex= sex;
this.salary = salary;
this.age= age;
this.star = star;
}
}

第一种方法:我们一般都是将这个集合遍历,然后依次的判断,这是最为普通的一种方式。

@Test
public void test1(){
//首先创建一个
List list = Arrays.asList(
new Student("九天","男",5000,18,"天秤座"),
new Student("十夜","男",4000,16,"双鱼座"),
new Student("十一郎","男",3000,24,"水瓶座")
);
List result = new ArrayList<>();
for (Student student:list){
if ("天秤座".equals(student.getStar())){
result.add(student);
}
}
System.out.println(result);
}

第二种方法:通过匿名内部类的方法,在内部类中添加判断条件进行筛选。


首先创建一个公共接口:


public interface FilterProcess {
boolean process(T t);
}


接下来通过一个公共函数,对集合以及筛选条件做一个共同方法,筛选到班级里星座是天秤星座的学生


public List filterStudent(List students, FilterProcess mp){
List list = new ArrayList<>();
for (Student student : students) {
if(mp.process(student)){
list.add(student);
}
}
return list;
}

最后是通过匿名内部类和该方法得到结果:


@Test
public void test2(){
List students = Arrays.asList(
new Student("九天","男",5000,18,"天秤座"),
new Student("十夜","男",4000,16,"双鱼座"),
new Student("十一郎","男",3000,24,"水瓶座")
);
List list = filterStudent(students, new FilterProcess() {
@Override
public boolean process(Student student) {
return student.getStar().equals("天秤座");
}
});
for (Student student : list) {
System.out.println(student);
}
}

结果如图:



但是通过这两种代码都是很多,所以java8在这一点上提供了对集合筛选最大程度的删减代码,就是第三种方法。第三种方法:通过Lambda直接判断,一步到位,不需要在写其他的方法。

@Test
public void test3(){
List list = Arrays.asList(
new Student("九天","男",5000,18,"天秤座"),
new Student("十夜","男",4000,16,"双鱼座"),
new Student("十一郎","男",3000,24,"水瓶座")
);
List result = filterStudent(list,(e)->e.getStar().equals("天秤座"));
System.out.println(result);
}

测试结果:


[Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)]


但是现在又会有人会问这个问题,我的那个方法中是这样子的


filterStudent(List students, FilterProcess mp)

为什么我的代码参数却是这样子的呢


filterStudent(list,(e)->e.getStar().equals("天秤座")

来,这个跟大家好好解释,其实 -> 这个是一个连接符,左边代表参数,而右边代表 函数体(也就是我们说的条件),这个e就是代表 FilterProcess mp 这个参数的,只不过我们得java8 中lambda可以给这个参数附加上了条件,这些条件筛选都是封装到jdk8中内部类中自己实现的,所以我们只要附加条件就可以了,那个(e)就代表传了参数

总结:lambda主要是针对集合中条件的筛选,包括数组登登。接下来我们介绍Stream API ,这个和Lambda息息相关,论重要性,lambda只是基础,Stream API 才是真正的升级版


Stream API 详解:

1、功能:对集合高级别的筛选,相当于sql语句中的高级查询一样,包括分页,模糊匹配登登,这是对java8 添加了 函数式编程等多功能,代码简洁,告别for循环。。。


2、BasicStream 是父类子类:Stream IntStream LongStream DoubleStream 不同的数据类型对应不同的接口,可以提高性能,而Stream对应的则是剩余的所有类型


3、Stream 包含两个类型,中间操作(intermediate operations)和结束操作(terminal operations)


4、Intermediate,一个Stream可以调用0到多个Intermediate类型操作,每次调用会对Stream做一定的处理,返回一个新的Stream,这类操作都是惰性化的(lazy),就是说,并没有真正开始流的遍历。 常用操作:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel


Terminal,一个Stream只能执行一次terminal 操作,而且只能是最后一个操作,执行terminal操作之后,Stream就被消费掉了,并且产生一个结果。 常用操作:forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny


说下Stream,他是一个流,那什么是流呢,流是Java8引入的全新概念,它用来处理集合中的数据,暂且可以把它理解为一种高级集合。


众所周知,集合操作非常麻烦,若要对集合进行筛选、投影,需要写大量的代码,而流是以声明的形式操作集合,它就像SQL语句,我们只需告诉流需要对集合进行什么操作,它就会自动进行操作,并将执行结果交给你,无需我们自己手写代码。


因此,流的集合操作对我们来说是透明的,我们只需向流下达命令,它就会自动把我们想要的结果给我们。由于操作过程完全由Java处理,因此它可以根据当前硬件环境选择最优的方法处理,我们也无需编写复杂又容易出错的多线程代码了。


5、Stream 的特点

只能遍历一次 我们可以把流想象成一条流水线,流水线的源头是我们的数据源(一个集合),数据源中的元素依次被输送到流水线上,我们可以在流水线上对元素进行各种操作。一旦元素走到了流水线的另一头,那么这些元素就被“消费掉了”,我们无法再对这个流进行操作。当然,我们可以从数据源那里再获得一个新的流重新遍历一遍。


采用内部迭代方式 若要对集合进行处理,则需我们手写处理代码,这就叫做外部迭代。而要对流进行处理,我们只需告诉流我们需要什么结果,处理过程由流自行完成,这就称为内部迭代


6、流的过程

准备一个数据源
执行中间操作 中间操作可以有多个,它们可以串连起来形成流水线。
执行终端操作 执行终端操作后本次流结束,你将获得一个执行结果。

7、用流来解决班级学生星座为天秤座

@Test
public void test5(){
List list = Arrays.asList(
new Student("九天","男",5000,18,"天秤座"),
new Student("十夜","男",4000,16,"双鱼座"),
new Student("十一郎","男",3000,24,"水瓶座")
);list.stream()
.filter((e)->e.getStar().equals("天秤座"))
.forEach(System.out::println);}

这样就可以解决,当然还有很多,这只是一个条件过滤,相当于mysql 中的 where 关键词

java8以及9的另一个讲解


http://blog.csdn.net/yalishadaa/article/details/78152717

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台