java stream流
在Java 8中,得益于Lambda所带来的函数式编程, 引入了一个全新的Stream流概念。
目的:用于简化集合和数组操作的API。
Stream流式思想的核心
1.先得到集合或者数组的Stream流(就是一根传送带)
2.把元素放上去
3.然后就用这个Stream流简化的API来方便的操作元素。
Stream流的三类方法
获取Stream流
创建一条流水线,并把数据放到流水线上准备进行操作
-
集合获取Stream流的方式
可以使用Collection接口中的默认方法stream()生成流名称 说明 default Stream stream() 获取当前集合对象的Stream流 示例
//Collection集合获取流 Collection<String> list=new ArrayList<String>(); Stream<String> s=list.stream(); //Map获取流 Map<String,Integer> maps=new HashMap<>(); //Map的键流 Stream<String> keyStream=maps.keySet().stream(); //Map的值流 Stream<Integer> valueStream=maps.values().stream(); //键值对流 Stream<Map.Entry<String,Integer>> keyAndValue=maps.entrySet().stream();
-
数组获取Stream流的方式
名称 说明 public static Stream stream(T[] array) 获取当前数组的Stream流 public static Stream of(T… values) 获取当前数组/可变数据的Stream流 示例
//数组获取 String[] names={"小明","小白"}; Stream<String> nameStream= Arrays.stream(names); Stream<String> nameStream2=Stream.of(names);
中间方法
中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程
就像流水线上的操作。一次操作完毕之后,还可以继续进行其他操作。
筛选与切片
- filter:接收Lambda,从流中排除某些元素
名称 | 说明 |
---|---|
limit(long maxSize) | 获取前几个元素 |
skip(long n) | 跳过前几个元素 |
distinct() | 去除流中重复的元素。依赖(hashCode和equals方法) |
startsWith(String n) | 获取以n开头的元素 |
List<String> list=new ArrayList<>();
list.add("小百");
list.add("小1");
list.add("小2");
list.add("大3");
list.add("小4");
//filter处理数据
//获取以小开头的
list.stream().filter(s->s.startsWith("小")).forEach(s-> System.out.println(s));
//limit获取前几个数据
list.stream().filter(s->s.startsWith("小")).limit(2).forEach(s-> System.out.println(s));
//skip跳过前几个
list.stream().filter(s->s.startsWith("小")).skip(2).forEach(s-> System.out.println(s));
//map加工方法
//给集合中的元素都加上一个hi
list.stream().map(s->"hi"+s).forEach(s -> System.out.println(s));
//把所有的名字都加工成学生对象
list.stream().map(s -> new Student(s)).forEach(student -> System.out.println(student));
映射
map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素,再将新元素放在一个新流中
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
list.stream().map(str -> str.toUpperCase()).forEach(s->System.out.println(s));
map加工方法
//给集合中的元素都加上一个hi
list.stream().map(s->"hi"+s).forEach(s -> System.out.println(s));
//把所有的名字都加工成学生对象
list.stream().map(s -> new Student(s)).forEach(student -> System.out.println(student));
flatMap(Function f)
接收一个函数作为参数,将流中的每一个值都换成另一个流,然后将所有的流连接成一个
该方法适合集合套集合的情况
mapToDouble(ToDoubleFunction f) ——接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream
mapToInt(ToIntFunction f)—— 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream
mapToLong(ToLongFunction f) ——接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream
合并流
concat(Stream a, Stream b)合并a和b两个流为一个流
//合并流
Stream<String> s1=list.stream().filter(s->s.startsWith("小"));
Stream<Integer> s2=Stream.of(11,22,33);
Stream<Object> s3=Stream.concat(s1,s2);
排序
sorted:自然排序
List<Integer> list=Arrays.asList(1,2,3,4,8,6);
list.stream().sorted().forEach(s-> System.out.println(s));
sorted(Comparator com):定制排序,需要传入Comparator的实现
Student student1=new Student("小a",22);
Student student2=new Student("小b",23);
Student student3=new Student("小c",26);
Student student4=new Student("小d",24);
List<Student> students=Arrays.asList(student1,student2,student3,student4);
students.stream().sorted((s1,s2)->{
return Integer.compare(s1.getAge(),s2.getAge());
}).forEach(s-> System.out.println(s));
Stream终止操作
终止操作将不再返回流,而是对中间操作产生的流进行具体操作,可能有返回值,也可能没有。如果需要返回值但返回值有可能为空时,终止操作一般会返回一个Optional容器对象,把返回值封装在该容器对象中,可以通过调用Optional.get()获取具体的返回值,以避免出现空指针异常等。
Optional 类是一个可以为 null 的容器对象。
如果值存在则 isPresent() 方法会返回 true,调用 get() 方法会返回该对象。
匹配与查找
allMatch(Predicate p)检查是否匹配所有元素,流中的所有元素都满足条件
anyMatch(Predicate p)检查是否至少匹配一个元素,只要流中有一个元素满足条件就返回true
noneMatch(Predicate p)检查是否没有匹配任何元素,当至少有一个元素匹配时就返回false,当所有元素都不匹配时才返回true,通过该方法得出有匹配的元素的结论
boolean allMath=students.stream().allMatch(student -> student.getAge()>22);
boolean anyMath=students.stream().allMatch(student -> student.getAge()>22);
boolean noneMath=students.stream().allMatch(student -> student.getAge()>22);
findFirst()返回第一个元素,调用该方法后会返回一个Optional容器对象
findAny()返回当前流中的任意元素
Optional<Student> student=students.stream().findFirst();
System.out.println(student);
Optional<Student> student5=students.stream().findAny();
System.out.println(student5);
count()返回流中元素总数
max(Comparator c)返回流中最大值
min(Comparator c)返回流中最小值
Optional<Student> student6=students.stream().max((studen1,studen2)->studen1.getAge()-studen2.getAge());
System.out.println(student6);
Optional<Student> student7=students.stream().min((studen1,studen2)->studen1.getAge()-studen2.getAge());
System.out.println(student7);
Stream流的收集操作
把Stream流操作后的结果数据转回到集合或者数组中去
名称 | 说明 |
---|---|
R collect(Collector collector) | 开始收集Stream流,指定收集器 |
Collectors工具类提供了具体的收集方式
名称 | 说明 |
---|---|
public static Collector toList() | 把元素收集到List集合中 |
public static Collector toSet() | 把元素收集到Set集合中 |
public static Collector toMap(Function keyMapper , Function valueMapper) | 把元素收集到Map集合中 |
List<String> list=new ArrayList<>();
list.add("小百");
list.add("小1");
list.add("小2");
list.add("大3");
list.add("小4");
//流收集到集合中
Stream <String> str=list.stream().filter(s->s.startsWith("小"));
List<String> xiaList=str.collect(Collectors.toList());
//流收集到数组中
Stream <String> str1=list.stream().filter(s->s.startsWith("小"));
Object[] arr=str1.toArray();