找回密码
 立即注册
首页 资源区 代码 Java-Stream API

Java-Stream API

盒礁泅 6 天前
Stream API 基础(初识)
基本步骤


  • 获取Stream流
  • 对Stream流进行操作
  • 获取处理结果
目的

简化对集合,数组等的操作,使代码更加简洁美观,减少工程量
1.获取Stream流:


  • 获取集合(Collection)的Stream流:
    1.png

  • 获取数组的Stream流:
    2.png

  • 获取Map的Stream流:
    对于Map,不同于前两种,有三种获取方法,一种是对于Key,一种是对于Value,还有一种就是对于键值对(虽然作者还没有看懂怎么对键值对进行操作)
  1. //1.获取Stream流,调用集合提供的Stream方法
  2.         Collection<String> s = new ArrayList<>();
  3.         Stream<String> k = s.stream();
  4.         //Map流的获取
  5.         Map<String,Integer> m = new HashMap<>();
  6.         Stream<String>  key = m.keySet().stream();
  7.         Stream<Integer> value = m.values().stream();
  8.         Stream<Map.Entry<String,Integer>> dou = m.entrySet().stream();
  9.         //数组
  10.         String[] p = {"112","111","11","321"};
  11.         Stream<String> a =Arrays.stream(p);
  12.         Stream<String> a1 = Stream.of(p);
  13.         Stream<String> a2 = Stream.of("112","111","11","321");
复制代码
2.中间方法:

包含:排序,过滤,去重等等。

3.png

过滤:
  1. //过滤
  2.         a.filter(t -> t.startsWith("1") && t.length() > 2).forEach(t -> System.out.println(t));
  3.         System.out.println("---------------------------------------");
  4.         //等于
  5.         String[] c = a1.filter(t -> t.startsWith("1") && t.length() > 2).toArray(String[]::new);
  6.         //对于数组要用toArray
  7.         //但对于集合要用Collectors
  8.         //因为Stream有toArray方法,而变为集合要调用Collectors的静态方法
  9.         List<String> b = k.filter(t -> t.startsWith("1") && t.length() > 2).collect(Collectors.toList());
复制代码
使用lambda函数进行编写过滤条件,注意filter前面跟的是一个流,经过filter筛选得到一个新流,原流保持不变。
排序:
  1. //排序  
  2. //排序一般用于浮点数,整数之间  
  3. List<Integer> num = new ArrayList<>();  
  4. num.add(1);  
  5. num.add(12);  
  6. num.add(121);  
  7. num.add(321);  
  8. List<Integer> list = num.stream().sorted().collect(Collectors.toList());  
  9. System.out.println(list);  
  10. System.out.println("------------------------------------------------");  
  11. num.stream().sorted((s1,s2)->Integer.compare(s2,s1)).forEach(System.out::println);
复制代码
排序严格来说使用于有ToCompare方法的对象,因为在sorted里进行比较需要用到compare静态方法,所以对数据类型有所限定。
  1. System.out::println
复制代码
类似于这种用法是方法引用,有兴趣可以去了解。另外,获取数据后再打印是打印列表,而直接在流下打印则是对数据进行直接打印,不同如下:
4.png

跳过,去重,合并等 :

跳过 :skip(long n),是对流进行处理的操作,可以跳过前n个数据。
保留(我喜欢这么叫) :limit(maxSize)对应跳过操作,保留前maxSize个数据。
去重:distinct(),如果要对自定义对象进行去重操作,需要重写它的hashCode和equals.
合并:concat(stream a1,stream a2),是对两个流进行合并。
映射/加工方法:对原数据进行处理,返回新流。
示例如下:
  1. //跳过,保留
  2. num.stream().skip(2).forEach(System.out::println);
  3. System.out.println("--------------");
  4. num.stream().limit(2).forEach(System.out::println);
  5. System.out.println("--------------");
  6. //如果希望自定义对象可以去重复,那么需要重写hashCode和equals方法,才可以去重
  7. num.stream().distinct().forEach(System.out::println);
  8. System.out.println("--------------");
  9. //假如我想要num中的每一个数都增加10,那么就可以使用map;
  10. //叫做映射/加工方法
  11. num.stream().map(t->"增加10后: " + (t + 10)).forEach(System.out::println);
  12. System.out.println("--------------");
  13. //合并流
  14. Stream<Double> q1 = Stream.of(1.0,2.0,3.0,4.0);
  15. Stream<String> q2 = Stream.of("hi","bye","ok");
  16. Stream<Object> con  = Stream.concat(q1,q2);
  17. System.out.println(con.count());
复制代码
3.收集,终结:

终结方法:

一旦使用终结方法后,流就不可以再次使用,也不会返回流。
5.png


  • forEach,其实就是增强循环,用来遍历操作
  • count是得到流中数据个数的
  • max和min返回类型是Option,因为返回的数据有可能为空,避免空指针异常。
  1. List<Employee> employee = new ArrayList<>();
  2.         employee.add(new Employee("张三", 3000, 23));
  3.         employee.add(new Employee("李四",10000,20));
  4.         employee.add(new Employee("王五",5000,30));
  5.         employee.stream().filter(t->t.getSalary() >= 5000).forEach(System.out::println);
复制代码
在运行这段代码之后,我想得到过滤后的员工信息,但是我却得到了
Employee@4f023edbEmployee@3a71f4dd ,这是因为我并没有在Employee中重写toString方法,下面是Employee的最终实现:
  1. public class Employee {
  2.     private String name;
  3.     private double salary;
  4.     private int age;
  5.     public Employee(String name,double salary,int age)
  6.     {
  7.         this.name = name;
  8.         this.salary = salary;
  9.         this.age = age;
  10.     }
  11.     public double getSalary()
  12.     {
  13.         return salary;
  14.     }
  15.     @Override
  16.     public String toString() {
  17.         return String.format("[员工] 姓名: %s | 薪资: %d | 年龄: %d", name, salary, age);
  18.     }
  19. }
复制代码
接下来是对终结方法的使用:
  1. List<Employee> employee = new ArrayList<>();
  2.         employee.add(new Employee("张三", 3000, 23));
  3.         employee.add(new Employee("李四",10000,20));
  4.         employee.add(new Employee("王五",5000,30));
  5.         //得到月薪不低于5000的员工
  6.         employee.stream().filter(t->t.getSalary() >= 5000).forEach(System.out::println);
  7.         //得到员工的数量
  8.         System.out.println(employee.stream().count());
  9.         //获取薪水最高的员工
  10.         Optional<Employee> max = employee.stream().max((t1,t2) -> Double.compare(t1.getSalary(),t2.getSalary()));
  11.         Employee maxemployee = max.get();
  12.         System.out.println(maxemployee);
复制代码
收集方法:

6.png

总结:

Stream流的使用模板其实就是:集合/数组等 . 中间方法 . 终结方法/收集

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册