什么是Stream?
- 也叫Stream流,是Jdk8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据。
- 优势:Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好。
public class Demo15 {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰", "张无总", "周芷若", "张强");
//选出张开头,且三个字的名字,用stream流比较方便
List<String> list = names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).collect(Collectors.toList());
System.out.println(list);
}
}
/*
[张三丰, 张无总]
*/
Stream流的使用步骤
获取Stream流
public class Demo16 {
public static void main(String[] args) {
//1,如何获取List集合的Stream流
List<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰", "张无总", "周芷若", "张强");
Stream<String> stream = names.stream();
stream.filter(s -> s.contains("张")).forEach(s -> System.out.println(s));
//2,如何获取Set集合的Stream流?
Set<String> set = new HashSet<>();
Collections.addAll(set, "刘德华", "张曼玉", "玛德", "德玛两亚");
Stream<String> stream1 = set.stream();
stream1.filter(s -> s.contains("德")).forEach(s -> System.out.println(s));
//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();
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 = {"ggg", "ddd", "bbb", "aaa"};
//方法1
Stream<String> s1 = Arrays.stream(names2);
//方法2
Stream<String> s2 = Stream.of(names2);
}
}
/*
张三丰
张无总
张强
玛德
德玛两亚
刘德华
迪丽热巴==>168.3
卡尔扎巴==>168.3
*/
Stream流常见的中间方法
- 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)。
//学生类
public class Student {
public String name;
public int age;
public double height;
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
//只有两个对象内容一样就返回同样的哈希值
@Override
public int hashCode() {
return Objects.hash(this.name, this.age, this.height);
}
//只有两个对象内容一样就返回true
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Student student = (Student) obj;
return this.age == student.age && 0 == Double.compare(this.height, student.height) && this.name.equals(student.name);
}
}
//测试类
public class Test {
public static void main(String[] args) {
List<Double> scores = new ArrayList<>();
Collections.addAll(scores, 88.5, 100.0, 60.0, 99.0, 9.5, 99.6, 25.0);
//找出成绩大于等于60分的数据,并升序后,再输出
System.out.println("----------1----------");
scores.stream().filter(s -> s >= 60).sorted().forEach(s -> System.out.println(s));
List<Student> students = new ArrayList<>();
students.add(new Student("张三", 18, 169));
students.add(new Student("张三", 18, 169));
students.add(new Student("李四", 25, 170));
students.add(new Student("李四", 26, 180));
students.add(new Student("王五", 20, 167));
students.add(new Student("赵六", 18, 173));
// 需求2:找出年龄大于等于23,且年龄小于等于30岁的学生,并按照年龄降序输出。
System.out.println("----------2----------");
students.stream().filter(s -> s.age >= 20 && s.age <= 30)
.sorted((o1, o2) -> o2.age - o1.age)
.forEach(s -> System.out.println(s));
// 需求3:取出身高最高的前3名学生,并输出。
System.out.println("----------3----------");
students.stream().sorted((o1, o2)-> Double.compare(o2.height, o1.height))
.limit(3).forEach(s->System.out.println(s));
// 需求4:取出身高倒数的2名学生,并输出。
System.out.println("----------4----------");
students.stream().sorted(((o1, o2) -> Double.compare(o2.height, o1.height)))
.skip(students.size() - 2).forEach(System.out::println);
// 需求5:找出身高超过168的学生叫什么名字,要求去除重复的名字,再输出。
System.out.println("---------5.1---------");
//map用来把对象中的name成员变量单独取出,简化处理,也迎合需求
students.stream().filter(s ->s.height > 168).map(s ->s.name)
.distinct().forEach(System.out::println);
System.out.println("---------5.2---------");
//distinct去重复,自定义类型的对象(希望内容一样就认为重复,重写hashCode,equals)
students.stream().filter(s -> s.height > 168)
.distinct().forEach(System.out::println);
System.out.println("----------6----------");
//需求6:合并两个Stream流
Stream<String> st1 = Stream.of("张三", "李四");
Stream<String> st2 = Stream.of("张三2", "李四3");
//类型不一样是可以用Object接
Stream<String> allSt = Stream.concat(st1, st2);
allSt.forEach(System.out::println);
}
}
/*
----------1----------
60.0
88.5
99.0
99.6
100.0
----------2----------
Student{name='李四', age=26, height=180.0}
Student{name='李四', age=25, height=170.0}
Student{name='王五', age=20, height=167.0}
----------3----------
Student{name='李四', age=26, height=180.0}
Student{name='赵六', age=18, height=173.0}
Student{name='李四', age=25, height=170.0}
----------4----------
Student{name='张三', age=18, height=169.0}
Student{name='王五', age=20, height=167.0}
---------5.1---------
张三
李四
赵六
---------5.2---------
Student{name='张三', age=18, height=169.0}
Student{name='李四', age=25, height=170.0}
Student{name='李四', age=26, height=180.0}
Student{name='赵六', age=18, height=173.0}
----------6----------
张三
李四
张三2
李四3
*/
Stream的终结方法
- 终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了。
- 收集Stream流:就是把Stream流操作后的结果转回到集合或者数组中去返回
- Stream流:方便操作集合/数组的手段;集合/数组;才是开发中的目的。
public class Test {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("张三", 18, 169));
students.add(new Student("张三", 18, 169));
students.add(new Student("李四", 25, 170));
students.add(new Student("李四", 26, 180));
students.add(new Student("王五", 20, 167));
students.add(new Student("赵六", 18, 173));
//需求1:请计算出身高超过168的学生有几人。
System.out.println("----------------1-----------------");
long size = students.stream().filter(s -> s.height > 168).count();
System.out.println(size);
//需求2:请找出身高最高的学生对象,并输出。
System.out.println("----------------2-----------------");
//注意,最后要用到get(),从容器中取出
Student sh = students.stream().max(((o1, o2) -> Double.compare(o1.height, o2.height))).get();
System.out.println(sh);
//需求3:请找出身高最矮的学生对象,并输出。
System.out.println("----------------3-----------------");
Student sl = students.stream().min(((o1, o2) -> Double.compare(o1.height, o2.height))).get();
System.out.println(sl);
//需求4:请找出身高超过170的学生对象,并放到一个新集合中去返回。
// 流只能收集一次。没错用要新建
System.out.println("---------------4.1----------------");
List<Student> students1 = students.stream().filter(a -> a.height > 170).collect(Collectors.toList());
System.out.println(students1);
System.out.println("---------------4.2----------------");
Set<Student> students2 = students.stream().filter(a -> a.height > 170).collect(Collectors.toSet());
System.out.println(students2);
//需求5:请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Hap集合返回,
System.out.println("----------------5-----------------");
Map<String, Double> map =
students.stream().filter(s -> s.height > 170).distinct()
//要指定键值对
.collect(Collectors.toMap(s -> s.name, s -> s.height));
System.out.println(map);
//需求5:数组返回,
System.out.println("----------------6-----------------");
Object[] arr = students.stream().filter(a -> a.height > 170)
.toArray(s -> new Student[s]);
System.out.println(Arrays.toString(arr));
}
}
/*
----------------1-----------------
5
----------------2-----------------
Student{name='李四', age=26, height=180.0}
----------------3-----------------
Student{name='王五', age=20, height=167.0}
---------------4.1----------------
[Student{name='李四', age=26, height=180.0}, Student{name='赵六', age=18, height=173.0}]
---------------4.2----------------
[Student{name='赵六', age=18, height=173.0}, Student{name='李四', age=26, height=180.0}]
----------------5-----------------
{李四=180.0, 赵六=173.0}
----------------6-----------------
[Student{name='李四', age=26, height=180.0}, Student{name='赵六', age=18, height=173.0}]
*/
标签:name,Stream,age,特性,height,JDK8,Student,println
From: https://www.cnblogs.com/arioya/p/18682637