目录
Stream Api 特点
一、 Stream 实例化 三种方式
二 、中间操作
1. 筛选与切片
2.映射
3.排序
三、终止操作
1.匹配与查找
2.归约
3.收集
四、Optional
1.Optional描述
2.常用方法
Stream Api 特点
* 使用 Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。 * 也可以使用Strem API 来并行执行操作。 * Stream API 提供一种高效且易于使用的处理数据方式。
一、 Stream 实例化 三种方式
举个栗子:
//Stream 实例化方法
List list = new ArrayList<>();
list.add(new Person("Tome", 12));
list.add(new Person("Jack", 43));
//方式1:通过集合
Stream stream = list.stream();//顺序流
Stream personStream = list.parallelStream();//并行流
//方式2:通过数组
int[] arr = new int[]{1, 4, 2, 4, 232, 4, 5};
IntStream stream1 = Arrays.stream(arr); //数组流
//方式3:通过Stream 的of()
//public static Stream of(T... values) : 返回一个流
Stream stream2 = Stream.of(23, 4, 23, 24, 5, 5, 3);
二 、中间操作
1. 筛选与切片
/**
* 中间操作可以多个操作连成一个流水线,除非流水线触发终止操作,
* 否则中间操作不会执行任何的处理。而在终止操作一次性全部处理。 “惰性求值”
* 1.筛选和切片
*/
@Test
public void test3(){
/* list.add(new Employee(1001, "马化腾", 34, 6000.38));
list.add(new Employee(1002, "马云", 12, 9876.12));
list.add(new Employee(1003, "刘强东", 33, 3000.82));
list.add(new Employee(1004, "雷军", 26, 7657.37));
list.add(new Employee(1005, "李彦宏", 65, 5555.32));
list.add(new Employee(1006, "比尔盖茨", 42, 9500.43));
list.add(new Employee(1007, "任正非", 26, 4333.32));
list.add(new Employee(1008, "扎克伯格", 35, 2500.32));*/
List list = EmployeeData.getEmployees();
//筛选和切片
// filter(Predicate p) 接收Lambda ,从流中排除某些元素
Stream stream = list.stream();
/*stream.filter(new Predicate() {
@Override
public boolean test(Employee e) {
return e.getSalary() > 7000;
}
});
stream = list.stream();*/
System.out.println("--------------所有员工列表-----------------------");
stream.forEach(System.out::println); //调用终止操作才会执行
stream = list.stream(); // stream 执行完已经关闭,下面需要使用,重新获取
//获取 工资大于7000 员工
System.out.println("------- 工资大于7000 员工-----------------------------");
stream.filter(e -> e.getSalary() > 7000).forEach(System.out::println);
//获取 名字大于4个字的 员工
stream = list.stream();
System.out.println("--------- 名字大于4个字的 员工----------------------------");
stream.filter(employee -> employee.getName().length() >3).forEach(System.out::println);
//-----------------------------------------------
//limit(n); 截断流 使元素不超过给定数量 获取结合前n个元素
System.out.println("--------- 获取前三个员工信息----------------------------");
stream = list.stream();
stream.limit(3).forEach(System.out::println);
//-----------------------------------------------
//skip(n): 跳过元素,返回一个扔掉前n个元素的流。若流中元素不足n个,返回一个空流
System.out.println("--------- 获取4个之后的元素----------------------------");
list.stream().skip(4).forEach(System.out::println);
System.out.println("--------- 当跳过元素,大于集合中元素,返回空流----------");
list.stream().skip(list.size()).forEach(System.out::println);
//-----------------------------------------------
//distinct() -筛选 ,通过流所生成的元素的hashCode() 和 equals() 去除重复
list.stream().distinct().forEach(System.out::println);
}
2.映射
//映射
@Test
public void test4(){
//map(Function f) 接收一个函数作为参数,该函数会被应用到每个元
//素上,并将其映射成一个新的元素。(会把多个元素的流当作一个元素)
List list = EmployeeData.getEmployees();
Stream stream = list.stream();
/* stream.map(new Function() {
@Override
public Object apply(Employee employee) {
return null;
}
});*/
System.out.println("-------------------所有人工资都涨100000------------------------------");
stream.map(employee -> employee.getSalary() +100000 ).forEach(System.out::println);
//106000.38 109876.12 103000.82 107657.37 105555.32 109500.43
System.out.println("-------------------所有姓名长度大于3的员工姓名------------------------------");
Stream namesStream = list.stream().map(Employee::getName);
namesStream.filter(name->name.length() >3).forEach(System.out::println);
// list.stream().map(Employee::getName).filter(name ->name.length() >3).forEach(System.out::println);
// ---------------------------------------------
// flatMap();接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
3.排序
@Test
public void test5(){
//排序
//1.sorted(); 自然排序 产生一个新流,其中按自然顺序排序
List list = Arrays.asList(12, 34, 67, 3, 6, 125);
list.stream().sorted().forEach(System.out::println);
//2.sorted(Comparator com) 定制排序; 产生一个新流,其中按比较器顺序排序
List list1 = EmployeeData.getEmployees();
list1.stream().sorted(new Comparator() {
@Override
public int compare(Employee o1, Employee o2) {
if (Double.compare(o1.getSalary(), o2.getSalary()) == 0) {
return Integer.compare(o1.getId(), o2.getId());
}else {
return Double.compare(o1.getSalary(), o2.getSalary());
}
}
});
list1.stream().sorted((o1,o2)->{
if (Double.compare(o1.getSalary(), o2.getSalary()) == 0) {
return Integer.compare(o1.getId(), o2.getId());
}else {
return Double.compare(o1.getSalary(), o2.getSalary());
}
}).forEach(System.out::println);
}
三、终止操作
//终止操作
@Test
public void test6(){
//匹配与查找
List list = EmployeeData.getEmployees();
// allMatch(Predicate p) 检查是否匹配所有元素
System.out.println("-------是否所有员工年龄都大于18-----------------------");
boolean isAllMatch = list.stream().allMatch(e -> e.getAge() > 18);
System.out.println(isAllMatch);
// anyMatch(Predicate p) 检查是否至少匹配一个元素
System.out.println("-------判断至少一个员工工资大于10000-----------------------");
boolean b = list.stream().anyMatch(e -> e.getSalary() > 10000);
System.out.println(b);
// noneMatch(Predicate p) 检查是否没有匹配所有元素
System.out.println("-------判断是由有员工姓 雷-----------------------");
boolean isLei= list.stream().noneMatch(e -> e.getName().contains("雷"));
System.out.println(isLei);
// findFirst() 返回第一个元素
System.out.println(list.stream().findFirst());
// findAny() 返回当前流中的任意元素
Optional any = list.stream().findAny();
System.out.println(any);
System.out.println("----------------------------------------");
// count() 返回流中元素总数
long count = list.stream().count();
System.out.println(count);
// max(Comparator c) 返回流中最大值
System.out.println("--------最高的工资---------------");
Stream doubleStream = list.stream().map(e -> e.getSalary());
Optional max = doubleStream.max(Double::compare);
System.out.println(max);
// min(Comparator c) 返回流中最小值
// forEach(Consumer c)
// 内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。
// 相反,Stream API 使用内部迭代——它帮你把迭代做了)
}
2.归约
@Test//规约
public void test7() {
//reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T
// reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 Optional
System.out.println("-----员工所有工资和------------------");
List list = EmployeeData.getEmployees();
Stream doubleStream = list.stream().map(Employee::getSalary);
Double reduce = doubleStream.reduce(0.0, Double::sum);
System.out.println(reduce);
}
3.收集
//收集
// collect(Collector c) 将流转换为其他形式。
// 接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
List list = EmployeeData.getEmployees();
List list1 = list.stream().filter(e -> e.getSalary() > 4000).collect(Collectors.toList());
Set set = list.stream().filter(e -> e.getSalary() > 4000).collect(Collectors.toSet());
list1.forEach(System.out::println);
四、Optional
1.Optional描述
1.Optional 类(java.util.Optional) 是一个容器类,它可以保存类型T的值,代表
这个值存在。或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不存
在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
2. Optional类的Javadoc描述如下:这是一个可以为null的容器对象。如果值存在则
isPresent()方法会返回true,调用get()方法会返回该对象。
2.常用方法
/*创建Optional类对象的方法:
Optional.of(T t) : 创建一个 Optional 实例,t必须非空;
Optional.empty() : 创建一个空的 Optional 实例
Optional.ofNullable(T t):t可以为null*/
Person p = new Person();
//Optional.of(T t) t 对象不能为空
Optional p0 = Optional.of(new Person());
//Optional.ofNullable(T t) t 对象可以为空,得到的 p1 也会为空
p = null;
Optional p1 = Optional.ofNullable(p);
System.out.println(p1); //Optional.empty
@Test
public void test2() {
/* 判断Optional容器中是否包含对象:
boolean isPresent() : 判断是否包含对象
void ifPresent(Consumer super T> consumer) :如果有值,就执行Consumer 接口的实现代码,并且该值会作为参数传给它。*/
Person p = new Person();
Optional person = Optional.ofNullable(p);
//判断是否Optional 中是否包含Person 的对象
boolean present = person.isPresent();
person.ifPresent(new Consumer() {
@Override
public void accept(Person person) {
}
});
person.ifPresent((o)->{
System.out.println("");
});
person.ifPresent(System.out::println);
}
@Test
public void test3() throws Throwable {
/*获取Optional容器的对象:
T get(): 如果调用对象包含值,返回该值,否则抛异常
T orElse(T other) :如果有值则将其返回,否则返回指定的other对象。
T orElseGet(Supplier extends T> other) :如果有值则将其返回,否则返回由Supplier接口实现提供的对象。
T orElseThrow(Supplier extends X> exceptionSupplier) :
如果有值则将其返回,否则抛出由Supplier接口实现提供的异常。
*/
Optional optional = Optional.ofNullable(new Person());
// T get(): 如果调用对象包含值,返回该值,否则抛异常
Person person = optional.get();
// T orElse(T other) :如果有值则将其返回,否则返回指定的other对象。
Person person1 = optional.orElse(new Person());
// T orElseGet(Supplier extends T> other) :如果有值则将其返回,否则返回由Supplier接口实现提供的对象。
optional.orElseGet(new Supplier() {
@Override
public Person get() {
return new Person();
}
});
Person person2 = optional.orElseGet(() -> new Person());
Person person3 = optional.orElseGet(Person::new);
// T orElseThrow(Supplier extends X> exceptionSupplier) :
// 如果有值则将其返回,否则抛出由Supplier接口实现提供的异常。
optional.orElseThrow(new Supplier() {
@Override
public Throwable get() {
return new Exception();
}
});
Person person4 = optional.orElseThrow(() -> new Exception());
Person person5 = optional.orElseThrow(Exception::new);
}