zoukankan      html  css  js  c++  java
  • 【从零单排】Java 8 实战演练

    Java 8 新引入的 Optional 和 Stream 功能很强大,用的好可以大大简化代码,提高效率。同时,大数据编程框架的源码以及业务代码大量使用了流式编程的思想。所以,这一块必须熟练掌握。

    但是,流式编程不是 "the silver bullet" ,有些场景使用可能 overkill ,让代码不那么易读,而且打 log 或者 debug 的时候费劲。下面就举 2 例。

    例1

    业务逻辑:写一个函数,判断 Student 的性别是男生还是女生。

    • 实现1:是比较老派的写法,中规中矩。
    • 实现2:是新式的写法。使用了 Optional + map + filter

    废话不多说,上代码:

    实体类

    public class Student {
        private String name;
        private Gender gender;
    
        public Student(String name, Gender gender) {
            this.name = name;
            this.gender = gender;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Gender getGender() {
            return gender;
        }
        public void setGender(Gender gender) {
            this.gender = gender;
        }
    }
    
    enum Gender {
        Boy, Girl
    }
    

    实现1

    public static boolean isBoy(Student student) {
    	if (student == null || student.getGender() == null) return false;
    
    	if (student.getGender() == Gender.Boy){
    		return true;
    	} else {
    		return false;
    	}
    }
    

    实现2

    public static boolean isGirl(Student student) {
    	return Optional.ofNullable(student)
    			.map(Student::getGender)
    			.filter(gender -> gender == Gender.Girl).isPresent();
    }
    

    主函数

    public static void main(String[] args) {
    
    	Student s1 = new Student("Alice", Gender.Girl);
    	Student s2 = new Student("Bob", Gender.Boy);
    
    	System.out.println(s1.getName() + " is a girl: " + isGirl(s1));
    	System.out.println(s2.getName() + " is a boy: " + isBoy(s2));
    
    }
    

    输出

    Alice is a girl: true
    Bob is a boy: true
    

    个人认为,这里使用流式编程有一点点 overkill ,因为老派的实现方法已经足够简洁。

    例2

    业务逻辑:有一个 list ,里面放了一堆 map ,而 map 里面放的是键值对:【姓名-成绩】。要求,把所有学生的名字收集起来,做成一个字符串输出。

    • 实现1:使用 for 循环的常规写法。
    • 实现2:使用了 flatmap + collect

    数据准备

    	List<Map<String, String>> scoreList = new ArrayList<>();
    	Map<String, String> scoreGroup1 = new HashMap();
    	scoreGroup1.put("Alice", "70");
    	scoreGroup1.put("Bob", "90");
    	Map<String, String> scoreGroup2 = new HashMap();
    	scoreGroup2.put("Charles", "80");
    	scoreList.add(scoreGroup1);
    	scoreList.add(scoreGroup2);
    

    实现1

    	StringBuilder names1 = new StringBuilder();
    	for (Map<String, String> map: scoreList) {
    		Set<String> set = map.keySet();
    		for(String key: set) {
    			if (!names1.toString().isEmpty()){
    				names1.append(", " + key);
    			} else {
    				names1.append(key);
    			}
    		}
    	}
    	System.out.println("Process 1 - Student names: " + names1.toString());
    

    实现2

    	String names2 = scoreList
    			.stream()
    			.flatMap(e -> e.keySet().stream())
    			.collect(Collectors.joining(", "));
    	System.out.println("Process 2 - Student names: " + names2);
    

    输出

    Process 1 - Student names: Bob, Alice, Charles
    Process 2 - Student names: Bob, Alice, Charles
    

    这个例子中,使用 flatpmap 还是大大简化了代码的。

    总结

    从个人角度出发,打铁还需自身硬。有些流式编程的代码一开始看确实晦涩难懂,那我们就平时多用 Stream 练练手,写的多了,自然就熟了。

    • 如果是一个 legacy 的项目,就尽量跟原来的 coding style 保持一致,这样减少 bug 率。
    • 如果是一个新的或者大数据的项目,那就多用流式编程。

    参考

  • 相关阅读:
    专业实训项目需求分析
    2015年秋季个人阅读计划
    场景调研
    二维数组最大连通子数组
    单元测试
    《大道至简——软件工程实践者的思想》阅读笔记之三
    《大道至简——软件工程实践者的思想》阅读笔记之二
    人机交互-输入法使用评价
    第一阶段个人总结10
    第一阶段个人总结09
  • 原文地址:https://www.cnblogs.com/maxstack/p/15167407.html
Copyright © 2011-2022 走看看