Stream的执行流程可分为:Stream的创建 -> 一些列的中间操作(过滤,映射等) -> 终止操作
1.Stream的创建方式
package com.yl.pdfdemo.day08.p8;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* @Author wfj
* @Date 2021/7/14
* @Description Stream
* @Version 1.0
*/
public class StreamAPITest {
/**
* Stream关注的是对数据的计算,主要和cpu打交道
* 集合主要是存储数据,与内存打交道
*
* Stream的 执行流程
* 1.Stream的实例化
* 2.一些列的中间操作(过滤,映射等)
* 3.终止操作
*
*/
//创建Stream的方式一: 通过集合
@Test
public void test1() {
//返回一个顺序流
//default Stream<E> stream()
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream<String> stream1 = list.stream();
//返回一个并行流
//default Stream<E> parallelStream()
Stream<String> stream2 = list.parallelStream();
}
//创建Stream的方式二: 通过数组
@Test
public void test2() {
int[] arr = new int[]{11,22,33};
IntStream stream = Arrays.stream(arr);
Person p1 = new Person(1001,"xioabai",18);
Person p2 = new Person(1002,"xioahei",18);
Person[] persons = new Person[]{p1,p2};
Stream<Person> personStream = Arrays.stream(persons);
}
//创建Stream的方式三: 通过Stream的of()
@Test
public void test3() {
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
}
//创建Stream的方式四: 创建无限流
@Test
public void test4() {
//迭代
//遍历前10个偶数
Stream.iterate(0,t -> t + 2).limit(10).forEach(System.out::println);
//生成
Stream.generate(Math::random).limit(10).forEach(System.out::println);
}
}
2.用到的实体类
package com.yl.pdfdemo.day08.p8;
import java.util.Objects;
/**
* @Author wfj
* @Date 2021/7/14
* @Description
* @Version 1.0
*/
public class Person {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
public Person() {
}
public Person(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return id == person.id &&
age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name, age);
}
}
3.Stream的中间操作
package com.yl.pdfdemo.day08.p8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* @Author wfj
* @Date 2021/7/14
* @Description Stream中间操作
* @Version 1.0
*/
public class StreamAPITest1 {
public List<Person> getPersonList() {
Person p1 = new Person(1001,"xiaohei",17);
Person p2 = new Person(1002,"xiaobai",18);
Person p3 = new Person(1003,"xiaolon",20);
Person p4 = new Person(1004,"dahei",22);
Person p5 = new Person(1005,"dabai",17);
Person p6 = new Person(1006,"lilan",23);
Person p7 = new Person(1007,"lisiu",25);
List<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
list.add(p5);
list.add(p6);
list.add(p7);
return list;
}
//1.筛选与切片
@Test
public void test1() {
List<Person> list = getPersonList();
//filter(Predicate) 从流中排除某些元素
//筛选年龄大于20的
list.stream().filter(p -> p.getAge() > 20).forEach(System.out::println);
System.out.println();
//limit(n)截断流,使其元素不超过给定数量
list.stream().limit(3).forEach(System.out::println);
System.out.println();
//skip(n) -跳过元素,返回一个扔掉了前n个元素的流
list.stream().skip(2).forEach(System.out::println);
System.out.println();
//distinct() -筛选,根据流中元素的hashcode()和equals()方法去重
list.add(new Person(1008,"xxl",25));
list.add(new Person(1008,"xxl",25));
list.add(new Person(1008,"xxl",25));
list.stream().distinct().forEach(System.out::println);
}
//映射
@Test
public void test2() {
//map(Function f) 接收一个函数作为参数,将元素转换成其他形式或者提取信息
List<String> list = Arrays.asList("aa", "bb", "cc", "dd", "ee");
list.stream().map(s -> s.toUpperCase()).forEach(System.out::println);
List<Person> personList = getPersonList();
//获取年龄小于20的name
personList.stream().filter(p -> p.getAge() < 20).map(Person::getName).forEach(System.out::println);
//flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另外一个流,然后把所有流连接成一个流
list.stream().flatMap(StreamAPITest1::changeStringToStream).forEach(System.out::println);
}
public static Stream<Character> changeStringToStream(String str) {
ArrayList<Character> lsit = new ArrayList<>();
for (Character c : str.toCharArray()) {
lsit.add(c);
}
return lsit.stream();
}
//排序
@Test
public void test3() {
//sorted() -自然排序
List<Integer> list = Arrays.asList(10, 8, 90, 100, 19);
list.stream().sorted().forEach(System.out::println);
//sorted(Comparator com) -定制排序
List<Person> personList = getPersonList();
personList.add(new Person(1001,"xxl",25));
//先按照id从大到小排序,再按照年龄从小到大排序
personList.stream().sorted((p1,p2) -> {
int value = -Integer.compare(p1.getId(),p2.getId());
if (value != 0) {
return value;
} else {
return Integer.compare(p1.getAge(),p2.getAge());
}
}).forEach(System.out::println);
}
}
4.Stream的终止操作
package com.yl.pdfdemo.day08.p8;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Author wfj
* @Date 2021/7/14
* @Description Stream的终止操作
* @Version 1.0
*/
public class StreamAPITest2 {
public List<Person> getPersonList() {
Person p1 = new Person(1001,"xiaohei",17);
Person p2 = new Person(1002,"xiaobai",18);
Person p3 = new Person(1003,"xiaolon",20);
Person p4 = new Person(1004,"dahei",22);
Person p5 = new Person(1005,"dabai",17);
Person p6 = new Person(1006,"lilan",23);
Person p7 = new Person(1007,"lisiu",25);
List<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
list.add(p4);
list.add(p5);
list.add(p6);
list.add(p7);
return list;
}
//1.匹配与查找
@Test
public void test1() {
List<Person> list = getPersonList();
//allMatch(Predicate p) -检查是否匹配所有元素
//判断集合中所有带飞元素年龄是否都大于20
boolean b = list.stream().allMatch(p -> p.getAge() > 20);
System.out.println(b); //false
//anyMatch(Predicate p) -检查是否至少匹配一个元素
//是否存在年龄小于18
boolean b1 = list.stream().anyMatch(p -> p.getAge() < 18);
System.out.println(b1); //true
//noneMatch(Predicate p) -检查是否没有匹配的元素
boolean b2 = list.stream().noneMatch(p -> p.getAge() > 50);
System.out.println(b2); //true
//findFirst -返回第一个元素
Optional<Person> person = list.stream().findFirst();
System.out.println(person);//Optional[Person{id=1001, name='xiaohei', age=17}]
//findAny -返回流中任意一个元素
Optional<Person> person1 = list.parallelStream().findAny();
System.out.println(person1);//Optional[Person{id=1005, name='dabai', age=17}]
//count -返回流中元素的总个数
long count = list.stream().count();
System.out.println(count);//7
//max(Comparator com) -返回流中最大的值
//获取最大的年龄
Stream<Integer> stream = list.stream().map(p -> p.getAge());
Optional<Integer> max = stream.max(Integer::compareTo);
System.out.println(max.isPresent());// true 判断Optional内是否包含对象
System.out.println(max); //Optional[25]
System.out.println(max.get());//25
//min(Comparator com) -返回流中最小的值
//获取年龄最小的person
Optional<Person> min = list.stream().min((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));
System.out.println(min);//Optional[Person{id=1001, name='xiaohei', age=17}]
//forEach(Consumer c) - 内部迭代
list.stream().forEach(System.out::println);
}
//归约
@Test
public void test2() {
//reduce(T identity,BinaryOperator) -将流中元素反复结合起来,得到一个值,返回T
//比如1-10的和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
//第一个参数为初始值
Integer sum = list.stream().reduce(0, Integer::sum);
System.out.println(sum);//55
//reduce(BinaryOperator) -将流中元素反复结合起来,得到一个值,返回Optional<T>
List<Person> personList = getPersonList();
//比如获取所有年龄的总和
//方式一
Optional<Integer> total = personList.stream().map(Person::getAge).reduce(Integer::sum);
System.out.println(total); //Optional[142]
//方式二
Optional<Integer> total1 = personList.stream().map(Person::getAge).reduce((p1, p2) -> p1 + p2);
System.out.println(total1);// Optional[142]
}
//收集
@Test
public void test3() {
//collect(Collector c) -将流转换为其他形式
List<Person> list = getPersonList();
//获取年龄大于20的person的list
List<Person> persons = list.stream().filter(p -> p.getAge() > 20).collect(Collectors.toList());
System.out.println(persons.toString());//[Person{id=1004, name='dahei', age=22}, Person{id=1006, name='lilan', age=23}, Person{id=1007, name='lisiu', age=25}]
persons.forEach(System.out::println);
System.out.println();
Set<Person> set = list.stream().filter(p -> p.getAge() > 20).collect(Collectors.toSet());
set.forEach(System.out::println);
}
}
5.Optinal的使用
1)用到的实体类
package com.yl.pdfdemo.day08.p8;
/**
* @Author wfj
* @Date 2021/7/14
* @Description
* @Version 1.0
*/
public class Boy {
private Girl girl;
public Boy() {
}
public Boy(Girl girl) {
this.girl = girl;
}
public Girl getGirl() {
return girl;
}
public void setGirl(Girl girl) {
this.girl = girl;
}
@Override
public String toString() {
return "Boy{" +
"girl=" + girl +
'}';
}
}
package com.yl.pdfdemo.day08.p8;
/**
* @Author wfj
* @Date 2021/7/14
* @Description
* @Version 1.0
*/
public class Girl {
private String name;
public Girl() {
}
public Girl(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Girl{" +
"name='" + name + '\'' +
'}';
}
}
2)测试
package com.yl.pdfdemo.day08.p8;
import org.junit.Test;
import java.util.Optional;
/**
* @Author wfj
* @Date 2021/7/14
* @Description Optional类:为了在程序中避免空指针的出现
* @Version 1.0
*/
public class OptionalTest {
/**
* 1.创建Optional类实例的方法
* Optional.of(T t) 创建一个Optional的实例,t不能为空
* Optional.empty() 创建一个空的Optional实例
* Optional.ofNullable(T t) t可以为null
*
* 2.判断Optional容器内是否包含对象
* boolean isPresent() :判断是否包含对象
* void ifPresent(Consumer<? super T> consumer) :如果有值,就执行Consumer接口实现的代码,并且该值会作为参数传递给它
*
* 3.获取Optional容器内的对象
* T get():如果调用对象包含值,则返回值,否则抛异常
* T orElse(T other) :如果有值则将其返回,否则,返回other
* T orElseGet(Supplier<? extends T> other) :如果有值将其返回,否则返回由Supplier接口实现提供的对象
* T orElseThrow(Supplier<? extends X> exceptionSupplier) :如果有值将其返回,否则抛出由Supplier接口实现提供的异常
*/
@Test
public void test1() {
Girl g1 = new Girl();
Optional<Girl> opg1 = Optional.of(g1);
System.out.println(opg1);//Optional[Girl{name='null'}]
Optional<Object> empty = Optional.empty();
System.out.println(empty); //Optional.empty
Girl g2 = new Girl();
g2 = null;
Optional<Girl> opg2 = Optional.ofNullable(g2);
System.out.println(opg2);//Optional.empty
//orElse(T t):如果当前Optional内部的t是非空的,返回t,否则返回orElse()方法中的t
Girl girl = opg2.orElse(new Girl("xiaolan"));
System.out.println(girl);
}
@Test
public void test2() {
Boy boy = new Boy();
//会报空,因为没有Girl
// String girlName = getGirlName(boy);
String girlName1 = getGirlName1(boy);
System.out.println(girlName1);//小兰
}
public String getGirlName(Boy boy) {
return boy.getGirl().getName();
}
//使用Optional类改造
public String getGirlName1(Boy boy) {
Optional<Boy> optionalBoy = Optional.ofNullable(boy);
Boy boy1 = optionalBoy.orElse(new Boy(new Girl("小芳")));
Girl girl = boy1.getGirl();
Optional<Girl> girlOptional = Optional.ofNullable(girl);
Girl girl1 = girlOptional.orElse(new Girl("小兰"));
return girl1.getName();
}
}