1.功能
Stream流,用于操作集合或数组的数据。
2.优势
Stream流大量结合Lambda表达式的语法风格来编程,提供更简单、强大的方式操作集合或数组中的数据,代码更简洁,可读性更好。
3.示例
public class test {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张强");
System.out.println(names);
// 找出姓张,但是3个字的名字,存入到一个新集合中去。
List<String> list = new ArrayList<>();
for (String name : names) {
if (name.startsWith("张") && name.length() == 3) {
list.add(name);
}
}
System.out.println(list);
// 开始使用Stream流来解决这个需求。
List<String> streamList = names.stream()
.filter(name -> name.startsWith("张") && name.length() == 3)
.collect(Collectors.toList());
System.out.println(streamList);
}
}
4.使用步骤
(1)获取Stream流
public class test {
public static void main(String[] args) {
// 1. 如何获取List集合的Stream流
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张强");
Stream<String> stream = names.stream();
// 2. 如何获取Set集合的Stream流
Set<String> set = new HashSet<>();
Collections.addAll(set, "刘德华", "张学友", "蜘蛛精", "马德", "倚西西");
Stream<String> stream1 = set.stream();
stream1.filter(s -> s.startsWith("张")).forEach(System.out::println);
// 3. 如何获取Map集合的Stream流
Map<String, Double> map = new HashMap<>();
map.put("古力娜扎", 172.3);
map.put("迪丽热巴", 168.3);
map.put("李沁", 166.3);
map.put("卡尔凡", 168.3);
Set<String> keys = map.keySet();
Stream<String> ks = keys.stream();
Collection<Double> values = map.values();
Stream<Double> vs = values.stream();
Set<Map.Entry<String, Double>> entries = map.entrySet();// 注意:entrySet()返回的是Set集合,而非Stream流
Stream<Map.Entry<String, Double>> kvs = entries.stream();
kvs.filter(e -> e.getKey().contains("丽"))
.forEach(e -> System.out.println(e.getKey() + "-->" + e.getValue()));
// 4. 如何获取数组的Stream流
String[] names2 = {"求求呆", "东方不败", "唐大山", "独孤求败"};
Stream<String> stream2 = Arrays.stream(names2);
stream2.forEach(System.out::println);
//或者
Stream<String> s2 = Stream.of(names2);
}
}
(2)Stream流的中间方法
中间方法指的是调用完成后返回新的Stream流,可以继续使用(支持链式编程)。
public class test {
public static void main(String[] args) {
// 需求1:找出成绩大于等于60的成绩数据,并升序后,再输出。
List<Double> scores = new ArrayList<>();
Collections.addAll(scores, 88.5, 100.0, 60.0, 99.0, 9.5, 99.6, 25.0);
scores.stream().filter(s -> s >= 60).sorted().forEach(s -> System.out.println(s));
// 学生对象
List<Student> students = new ArrayList<>();
Student s1 = new Student("蜘蛛精", 26, 172.5);
Student s2 = new Student("蜘蛛精", 26, 172.5);
Student s3 = new Student("紫霞", 23, 167.6);
Student s4 = new Student("白晶晶", 25, 169.0);
Student s5 = new Student("牛魔王", 35, 183.3);
Student s6 = new Student("牛大人", 34, 168.5);
Collections.addAll(students, s1, s2, s3, s4, s5, s6);
// 需求2:找出年龄大于等于23,且年龄小于等于30岁的学生,并按照年龄升序输出。
students.stream()
.filter(s -> s.getAge() >= 23 && s.getAge() <= 30)
.sorted((o1, o2) -> o2.getAge() - o1.getAge())
.forEach(s -> System.out.println(s));
// 需求3:取出身高最高的前3名学生,并输出。
students.stream()
.sorted((o1, o2) -> Double.compare(o2.getHeight(), o1.getHeight()))
.limit(3)
.forEach(System.out::println);
System.out.println("------------------------------------------------");
// 需求4:取出身高最低的2名学生,并输出。
students.stream()
.sorted((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()))
.skip(students.size() - 2)
.forEach(System.out::println);
// 需求5:找出身高超过168的学生叫什么名字,要求去除重复的名字,再输出。
students.stream()
.filter(s -> s.getHeight() > 168)
.map(Student::getName)//对元素进行加工,只取出名字
.distinct()
.forEach(System.out::println);
// distinct去重, 自定义类型的对象(希望内容一样就认为重复,在Student构造器重写hashCode, equals)
students.stream()
.filter(s -> s.getHeight() > 168)
.distinct()
.forEach(System.out::println);
//concat合并两个流
Stream<String> st1 = Stream.of("张三", "李四");
Stream<String> st2 = Stream.of("张三", "李四2", "王五");
Stream<String> allSt = Stream.concat(st1, st2);
allSt.forEach(System.out::println);
}
}
(3)终结方法
调用完成后,不返回新Stream流,无法继续使用流。
收集Stream流:把Stream流操作后的结果转回到集合或者数组中去返回
public class test {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
Student s1 = new Student("蜘蛛精", 26, 172.5);
Student s2 = new Student("蜘蛛精", 26, 172.5);
Student s3 = new Student("紫霞", 23, 167.6);
Student s4 = new Student("白晶晶", 25, 169.0);
Student s5 = new Student("牛魔王", 35, 183.3);
Student s6 = new Student("牛夫人", 34, 168.5);
Collections.addAll(students, s1, s2, s3, s4, s5, s6);
// 需求1:请找出身高超过168的学生有几人。
long size = students.stream().filter(s -> s.getHeight() > 168).count();
System.out.println(size);
// 需求2:请找出身高最高的学生对象,并输出。
Student tallest = students.stream()
.max((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()))
.get();
System.out.println(tallest);
// 需求3:请找出身高最低的学生对象,并输出。
Student shortest = students.stream()
.min((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()))
.get();
System.out.println(shortest);
// 需求4:请找出身高超过170的学生对象,并放到一个新集合中去返回。
List<Student> students1 = students.stream()
.filter(a -> a.getHeight() > 170)//流只能收集一次,所以需要重新创建流
.collect(Collectors.toList());
System.out.println(students1);
Set<Student> students2 = students.stream()
.filter(a -> a.getHeight() > 170)//流只能收集一次,所以需要重新创建流
.collect(Collectors.toSet());
System.out.println(students2);
// 需求5:请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Map集合去返回。
Map<String, Double> map = students.stream()
.filter(a -> a.getHeight() > 170)
.distinct()
.collect(Collectors.toMap(
Student::getName,
Student::getHeight
));
System.out.println(map);
// 将流转换为数组
Student[] arr = students.stream()
.filter(a -> a.getHeight() > 170)
.toArray(len -> new Student[len]);
System.out.println(Arrays.toString(arr));
}
}