Stream流是jdk8开始新增的一套API,可以用于操作集合或者数组的数据
Stream优势:Stream流大量的结合了Lambda的语法风格来编辑,功能强大,代码简洁,可读性好。
Steam流的使用步骤:
1.从数据源(集合/数组/...)获取Stream流,Stream流代表一条流水线 ,并能与数据源建立连接。
of方法中T... 是可变参数。
public class test1 {
public static void main(String[] args) {
//1.调用集合获stream()方法
Collection<String> collection = new ArrayList<>();
Stream<String> stream = collection.stream();
//2.Map集合获取stream()方法
Map<String,Integer> map=new HashMap<>();
//获取键流
Stream<String> stream1 = map.keySet().stream();
//获取值流
Stream<Integer> stream2 = map.values().stream();
//获取键值对流
Stream<Map.Entry<String,Integer>> stream3 = map.entrySet().stream();
//获取数组的流
String[] str={"1","2","3"};
//1.arrays.stream()方法
Stream<String> stream4 = Arrays.stream(str);
//2.Stream.of()方法
Stream<String> stream5 = Stream.of(str);//可变参数,可以给任何类型,多个参数,也可以不给参数
}
}
2.调用流水线(数据流)的各种中间方法,对数据进行处理,计算。
Stream流的常用方法
中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)。
collection.stream().filter(s -> s.contains("1")).filter(s -> s.length()>2).collect(Collectors.toList());
List<String> list =new ArrayList<>();
list.add("张三");
list.add("王五");
list.add("小王");
list.add("小王");
list.add("张块头");
list.add("张四");
//返回名字长度未2,且以张开头
list.stream().filter(x->(x.length()==2)&&(x.startsWith("张"))).forEach(System.out::print) ;
System.out.println();
//返回长度最小的两个
list.stream().sorted((s1,s2)->s1.length()-s2.length()).limit(2).forEach(System.out::print);
System.out.println();
//对元素进行加工,并返回队形的流
list.stream().map(s->s+"nb").forEach(System.out::print);
System.out.println();
//合并流
Stream<String> stream1 = Stream.of("张三", "王五", "小王", "小王", "张块头", "张四");
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6);
Stream.concat(stream1, stream2).forEach(System.out::print);
输出结果:
张三张四
张三王五
张三nb王五nb小王nb小王nb张块头nb张四nb
张三王五小王小王张块头张四123456
3.获取处理的结果,遍历,统计、收集到一个新集合中返回 (终结方法)
终结方法指的是调用完成之后,不会返回新Stream了,没法继续使用流了。
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("张三", 18, 100));
students.add(new Student("李四", 19, 103));
students.add(new Student("王五", 17, 66));
students.add(new Student("小六", 20, 101));
// 获取分数大于100的
students.stream().filter(s->s.score()>100).forEach(System.out::print);
// 获取年龄小于18岁的
students.stream().filter(x->x.age()<18).count();
//获取分数最高的学生对象
Optional<Student> max = students.stream().max((s1, s2) -> Double.compare(s1.score(), s2.score()));
System.out.println(max.get());
//获取分数最高的学生对象
Optional<Student> min = students.stream().min((s1, s2) -> Double.compare(s1.score(), s2.score()));
System.out.println(min.get());
//用Optional接收最大最小值是为了防止出现空指针异常
}
收集Stream流:就是把Stream流操作后的结果转会到集合或者数组中去返回。
Stream流:方便操作集合/数组的手段; 集合/数组:才是开发中的目的。
List<Student1> students = new ArrayList<>();
students.add(new Student1("张三", 18));
students.add(new Student1("李四", 19));
students.add(new Student1("王五", 17));
students.add(new Student1("小六", 20));
students.add(new Student1("张七", 16));
List<String> list = new ArrayList<>();
list.add("张三");
list.add("王五");
list.add("小王");
list.add("小王");
list.add("张块头");
list.add("张四");
//收集到集合或者数组中去
//收集到LIst集合中
Stream<String> s1 = list.stream().filter(s -> s.startsWith("张"));
List<String> list1 = s1.collect(Collectors.toList());
System.out.println(list1);
//收集到Set集合中
/*Set<String> set = s1.collect(Collectors.toSet());
System.out.println(set);*/
//此时会报错,流只能收集一次.需要重新创建流
Stream<String> s2 = list.stream().filter(x -> x.startsWith("张"));
Set<String> set1 = s2.collect(Collectors.toSet());
System.out.println(set1);
//收集到数组中
Stream<String> s3 = list.stream().filter(s -> s.startsWith("张"));
//装到数组中去
String[] strings = s3.toArray(String[]::new);
//如何收集到Map集合
Stream<Student1> s4= students.stream();
Map<String,Integer> map = s4.collect(Collectors.toMap(Student1::getName, Student1::getAge));
System.out.println(map);
运行结果:
[张三, 张块头, 张四]
[张四, 张三, 张块头]
{李四=19, 张三=18, 小六=20, 王五=17, 张七=16}