通常我们想通过接口实现固定的接口实现某些自定义的业务功能,需实现固定接口并一一编写实现类的功能,过于死板,代码修改过于繁琐,所以可通过装饰类(装饰者模式)来对代码进行优化,实现用户自定义业务代码的功能。
案例:自定义java中的map、filter、reduce等方法
装饰类
public class MyList<T> {
//传入的参数类型List<T>
private List<T> oldList;
//构造方法传参传入变量值
public MyList(List<T> oldList) {
this.oldList = oldList;
}
//怎样定义这个map方法呢?
//map方法的功能是做映射,输入一个T,然后返回一个String
public <R> MyList<R> map(Function<T, R> func) { 类上无R类型,故在返回值类型前要加上<R>对其进行标识
//先定义一个新的List
List<R> nList = new ArrayList<R>();
//对原来的集合进行遍历,
for(T oldWord: oldList) {
//应用传入的逻辑,
R nWord = func.call(oldWord);
//将返回的结果,放入到新的List中
nList.add(nWord);
}
return new MyList(nList);
}
public MyList<T> filter(Function<T, Boolean> func) {
//注意传入的Function的泛型也需要加入
//创建一个新的集合
List<T> nList = new ArrayList<>();
//遍历老的集合中的元素
for(T word: oldList) {
//应用传递过来的逻辑
boolean flag = func.call(word);
//返回true的添加到新集合中
if(flag) {
nList.add(word);
}
}
return new MyList(nList);
}
public List<T> getOldList() {
return oldList;
}
public <R> MyList<R> flatMap(FlatMapFunction<T, R> func) {
//创建一个新的集合
List<R> nList = new ArrayList<>();
//迭代每一行
for (T line : oldList) {
//应用外面传过来的逻辑
Iterator<R> it = func.call(line);
while (it.hasNext()) {
R word = it.next();
nList.add(word);
}
}
return new MyList(nList);
}
public T reduce(ReduceFunction<T> func) {
T sum = null;
//循环
for (int i = 0; i < oldList.size(); i++) {
T word = oldList.get(i);
if (i == 0) {
sum = word;
} else {
sum = func.call(sum, word);
}
}
return sum;
}
}
接口类:
/**
* Created by zx on 2019/2/14.
*
* Function<T, R> 有两个泛型,T代表输入,R代表方法的返回
*/
public interface Function<T, R> {
R call(T t);
}
测试类:
public class MyListTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(new Integer[]{1,2,3,4,5,6,7,8,9});
//List<String> list = Arrays.asList(new String[]{"HADOOP", "SPARK", "FLINK"});
//通过装饰模式扩展
MyList<Integer> myList = new MyList(list);
// MyList<Integer> filtered = myList.filter(new Function<Integer, Boolean>() {
// @Override
// public Boolean call(Integer i) {
// return i % 2 == 0;
// }
// });
//
// MyList<Double> result = filtered.map(new Function<Integer, Double>() {
// @Override
// public Double call(Integer i) {
// return i * 10.0;
// }
// });
//
// for(Double i : result.getOldList()) {
// System.out.println(i);
// }
Integer reduced = myList.reduce(new ReduceFunction<Integer>() {
@Override
public Integer call(Integer t1, Integer t2) {
return t1 + t2;
}
});
System.out.println(reduced);
}
}