Stream简介
jdk8中新增 stream API,需要注意的是stream跟之前学习的IO流没有关系,这个stream主要是用于处理集合数据的,可以 将其看做是一个 高级迭代器。在Collection接口中新增了费抽象的stream方法来获取集合的流,使用
stream后可以写出更简洁的代码来处理集合中的数据。
定义一个Student类:
package Test;
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
定义测试类:
ArrayList<Student> arr = new ArrayList<>();
arr.add(new Student("zhangsan",10));
arr.add(new Student("李四",30));
arr.add(new Student("王五",50));
arr.add(new Student("赵六",60));
arr.add(new Student("秦琪",90));
List<Student> result = new ArrayList<>();
//遍历集合获取分数大于30分以上的学生并存放到新的 List中
//以前的写法代码较多,每个操作都需要遍历集合
/*ArrayList<Student> result = new ArrayList<>();
for(Student s:arr) {
if(s.getAge()>30) {
result.add(s);
}
}
System.out.println(result);*/
/*
* 使用Stream的写法
* 1、获取集合的stream对象
* 2、使用filter方法完成过滤
* 3、使用sort方法完成排序
* 4、使用collect方法将处理好的stream对象转换为集合对象
*/
result=arr.stream() //获取集合的Stream对象
.filter(s->s.getAge()>30) //使用filter方法
.sorted((s1,s2)->{return Integer.compare(s2.getAge(), s1.getAge());})
.collect(Collectors.toList()); //使用collect方法将处理好的stream方法
for(Student s:result) {
System.out.println(s);
}
map和reduce
- map用来归类,结果一般是 一组数据,比如可以将list中的学生分数 映射到一个新的 stream中
- reduce用来计算值,结果是一个值,比如计算最高分
ArrayList<Student> arr = new ArrayList<>();
arr.add(new Student("zhangsan",10));
arr.add(new Student("李四",30));
arr.add(new Student("王五",50));
arr.add(new Student("赵六",60));
arr.add(new Student("秦琪",90));
//获取 年龄 单独抽取 map
List<Integer> result = new ArrayList<>();
result =arr.stream() //转换成流
.map(s->{return s.getAge();}) //使用map方法,抽取其中的 age
.collect(Collectors.toList()); //将流转换成 List
System.out.println(result);
//获取list数据中的name长度
List len = new ArrayList<>();
len =arr.stream()
.map(s->{return s.getName();})
.map(s->{return s.length();})
.collect(Collectors.toList());
len.forEach(t->System.out.println(t));
//将每人分数-10
List<Integer> score = new ArrayList<>();
score = arr.stream()
.map(s->{return s.getAge()-10;})
.collect(Collectors.toList());
score.forEach(System.out::println);
//计算学生总分
int total =arr.stream()
.map(Student::getAge)
.reduce(0,(a,b)->{return a+b;});
System.out.println("学生的总分为"+total);
//计算学生总分,返回Optional类型的数据,该类型是Java8中新增的,主要用来避免空指针异常
Optional<Integer> total1 = arr.stream()
.map(Student::getAge)
.reduce((a,b)->{return a+b;});
System.out.println("学生的总分"+total1.get());
//计算最高分和最低分
Optional<Integer> max= arr.stream()
.map(Student::getAge)
.max((a,b)->{return Integer.compare(a, b);});
System.out.println("学生的最高分为"+max.get());
//计算学生的最低分
Optional<Integer> min = arr.stream()
.map(Student::getAge)
.min((a,b)->{return Integer.compare(a, b);});
System.out.println("学生的最低分为"+min.get());
数值流
在java8中新增了 IntStream、DoubleStream、LongStream类解决数学计算的问题。
arr.add(new Student("zhangsan",10));
arr.add(new Student("李四",30));
arr.add(new Student("王五",50));
arr.add(new Student("赵六",60));
arr.add(new Student("秦琪",90));
//计算总分
int sum =arr.stream() //转换为 Stream流
.mapToInt(s->{return s.getAge();}) //将Stream流 转换为 IntStream 流
.sum();
System.out.println("总分为"+sum);
//计算平均分
OptionalDouble av = arr.stream()
.mapToInt(s->{return s.getAge();})
.average();
System.out.println("平均分为:"+av.getAsDouble());
//生成1~100之间的数字
IntStream a =IntStream.rangeClosed(0, 100);
a.forEach(s->{System.out.println(s);}); //打印 使用 Lambda表达式
//计算1-100之间偶数的个数
long num = IntStream.rangeClosed(0, 100).filter((s)->{return s % 2==0;})
.count();
System.out.println("1-100之间偶数的个数为:"+num);
空指针异常是在学习和开发中最常见的问题之一,为了解决这个问题,在java8中新增了Optional类。这个类在java.util包下,使用这个类可以更好的支持函数式编程,并且可以简化以前对null的判断。