为了账号安全,请及时绑定邮箱和手机立即绑定

Java函数式编程(2):流式计算

标签:
Java

您好,我是湘王,这是我的慕课手记,欢迎您来,欢迎您再来~


Lambda表达式虽然将接口作为代码块赋值给了变量但如果仅仅只是Lambda表达式还无法让Java由量变引起质变真正让Lambda能够发挥出巨大威力的就是流式计算

所谓流式计算就是让数据像在流水线上一样从一道工序流转到下一道工序就像这样

https://img1.sycdn.imooc.com//6367c3c40001cc7f08260368.jpg

 


如果把数据处理的方式比作流水线那么SparkStorm和Flink就是目前市面上头部的三家工厂它们有各种各样的数据装配间也就是各种处理数据的算子,将数据按照所需加工成型所以不懂流式计算根本就做不了大数据开发上面那张图如果换成流式计算的就是这样

https://img1.sycdn.imooc.com//6367c3cb000190b608020368.jpg

 


Lambda表达式就变成了一个个的数据装配间

还是以实际的代码例子来说明假如有这样的代码

/**
 * 雇员数据
 *
 * @author 湘王
 */
public class Employee {
   public enum Type { MANAGER, SELLER, OFFICER };
   private String name;
   private String genger;
   private Integer age;
   private boolean married;
   private Type type;
   public Employee(final String name, final String genger, final Integer age, final boolean married, final Type type) {
      super();
      this.name = name;
      this.genger = genger;
      this.age = age;
      this.married = married;
      this.type = type;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getGenger() {
      return genger;
   }
   public void setGenger(String genger) {
      this.genger = genger;
   }
   public Integer getAge() {
      return age;
   }
   public void setAge(Integer age) {
      this.age = age;
   }
   public boolean isMarried() {
      return married;
   }
   public void setMarried(boolean married) {
      this.married = married;
   }
   public Type getType() {
      return type;
   }
   public void setType(Type type) {
      this.type = type;
   }
   @Override
   public String toString() {
      return this.name + "(" + this.genger + ")-" + this.age;
   }
}

 

如果想筛选28岁以下的员工并按年龄排序用老办法只能这么做

List<Employee> employees = Arrays.asList(
      new Employee("张勇", "男", 28, true, Employee.Type.MANAGER),
      new Employee("李强", "男", 22, false, Employee.Type.SELLER),
      new Employee("王武", "男", 32, false, Employee.Type.SELLER),
      new Employee("梅丽", "女", 26, true, Employee.Type.OFFICER),
      new Employee("郑帅", "男", 29, false, Employee.Type.OFFICER),
      new Employee("曾美", "女", 27, true, Employee.Type.SELLER),
      new Employee("郝俊", "男", 22, true, Employee.Type.SELLER),
      new Employee("方圆", "女", 24, false, Employee.Type.SELLER)
);

// 传统筛选数据的方法
// 筛选28岁以下的员工
List<Employee> list1 = new ArrayList<>();
for(Employee employee : employees) {
   if (employee.getAge() < 28) {
      list1.add(employee);
   }
}
// 按年龄排序
list1.sort(new Comparator<Employee>() {
   @Override
   public int compare(Employee o1, Employee o2) {
      return o1.getAge().compareTo(o2.getAge());
   }
});


 

如果要转换成Lmabda表达式的话就是这样

/**
 * 雇员函数式接口
 *
 * @author 湘王
 */
@FunctionalInterface
public interface EmployeeInterface<T> {
   boolean select(T t);
}



public static List<Employee> filter(List<Employee> employees, EmployeeInterface<Employee> ei) {
   List<Employee> list = new ArrayList<>();
   for(Employee employee : employees) {
      if (ei.select(employee)) {
         list.add(employee);
      }
   }
   return list;
}



// 使用Lambda表达式得到28岁以下的员工
List<Employee> list2 = filter(employees, employee -> employee.getAge() < 28);

// 按年龄排序
list2.sort((e1, e2) -> e1.getAge().compareTo(e2.getAge()));


 

可以看到这虽然用了Lambda表达式替代了旧的方法但可能要写大量的函数式接口,Lambda沦为鸡肋完全谈不上简便快速更别说优雅

所以这时候如果用流式计算那简直不要太优雅

// Lambda表达式 + 流式计算
List<Employee> list3 = employees
                        // 生成「流」
                        .stream()
                        // 过滤
                        .filter(emp -> emp.getAge() < 28)
                        // 排序
                        .sorted((o1, o2) -> o1.getAge().compareTo(o2.getAge()))
                        // 生成新的结果集合
                        .collect(Collectors.toList());

 

仅仅几行代码就搞定了完全没有之前那种傻大黑粗的感觉了

上面的代码可以用这幅图来还原

https://img1.sycdn.imooc.com//6367c44e0001525a10860597.jpg


1、先用filter算子流式计算中的函数或者方法在大数据中统称为算子我也习惯这么称呼将符合年龄条件的雇员筛选出来

2、再按照年龄从低到高排序

3、将排好序的员工列表输出出来

就是这么简单粗暴

就像藏宝图一样只有将Lambda表达式和流式计算这两张碎片拼起来才是完整的Java函数式编程

 

所有的流式计算算子可以分为两大类中间操作和终端操作

1、中间操作:返回另一个流,如filter、map、flatMap等

2、终端操作:从流水线中生成结果,如collect、count、reduce、forEach等

 

现在咱们已经找到了函数式编程这个宝藏那么再回到最初的问题当要实现某宝某东和某哈哈的员工联谊并解决单身问题时有更好的办法吗

当然有而且只用一行代码就可以搞定

List<Employee> unMarriedList4 = list.stream().filter(company -> Company.Type.BIG == company.getType()).flatMap(companys -> companys.getEmployees().stream()).filter(Employee::isMarried).sorted(Comparator.comparing(Employee::getAge)).collect(Collectors.toList());

 

 

感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~



点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消