说到这里,先说一下我个人的一个习惯,我在写javaBean的set()方法时,一半都不是void类型,都是返回当前对象,这样子我在给这个对象设值的时候就可以一直打点调下去了,不用罗里吧嗦的写很多次对象了。
OK,现在回到主题,我们先来考虑一个情景,我们自己写一个静态方法来实现对一个字符串的处理,代码如下:
public class Linkin { public static void main(String[] args) { // 操作"LinkinPark..."第一次 String str1 = function("LinkinPark...", String::toLowerCase); System.out.println(str1); // 操作"LinkinPark..."第二次 String str2 = function(str1, String::toUpperCase); System.out.println(str2); } // 模拟一个静态方法,来对str这个字符串做一元操作 public static String function(String str, UnaryOperator<String> function) { return function.apply(str); } }
上面的代码没什么问题,但是我们性能上考虑一下上面的这种编码就会发现一个坏处,就是我们在对“LinkinPark”这个字符串做了多次操作,其实我们只是需要最后一次的结果,那么在这中间我们都创建了一个中间字符串,它可能需要不小的存储空间,所以我们现在应该将这些操作都组合起来,然后将组合起来的操作一次性的应用到每个像素上,这样就好多了。看下面代码:
public class Linkin { public static void main(String[] args) { // 将前面的2次操作直接合并 String str1 = function1("LinkinPark...", String::toLowerCase, String::toUpperCase); System.out.println(str1); } // 模拟一个静态方法,来对str这个字符串做一元操作 public static String function(String str, UnaryOperator<String> function1, UnaryOperator<String> function2) { return function2.apply(function1.apply(str)); } // 模拟一个静态方法,不限制传入操作的个数 public static String function1(String str, UnaryOperator<String>... function) { for (UnaryOperator<String> unaryOperator : function) { str = unaryOperator.apply(str); } return str; } }
总结一下:一般来说,当我们在写一个可以被用户连续变换效果的API时,就应该能让用户组合这些效果。其实Stream也是这么建议我们用它的API来这样子编码的。