在java中使用委托实现map/filter
在java中,假设你有一个user 对象的list,此user对象封装了用户的id, first name, last name and age. 然后你想调用一个web service(eg. UserService.deleteUsersByIds(List<Integer> userIds) 去删除数据库中指定的这些user。 听起来似乎不太困难,不是么? 你所需要只是将
6});
================================================
1 List<User> users = getUserListFromSomeWhere();
2List<Integer> ids = map(users, new MapDelegate<User,String>() {
3 public Integer map(User obj) {
4 return obj.getId();
5 }
6});
================================================
同样,我们可以编写一个filter函数
view plaincopy to clipboardprint?
<T> List<T> filter(List<T> list, FilterDelegate<T> filterDelegate) {
List<T> retval = new ArrayList<T>(list.size());
for (T item : list) {
if (filterDelegate.filter(item)
retval.add(item);
return retval;
}
interface FilterDelegate<T> {
boolean filter(T item);
}
Now the client code will look like this:
========================
view plaincopy to clipboardprint?
List<User> users = getUserListFromSomeWhere();
List<User> list = filter(users, new FilterDelegate<User>(){
boolean filter(User user){
return user.getAge()<21;
}
}) ;
========================
What about return value creation?
Use delegation, we can separate the parts of an algorithm in terms of their interfaces and leave the implementation to the caller. However, given the above filter and map methods, what if I don’t want the return type to be ArrayList? What if I want a LinkedList or a HashSet? Doesn’t the statement
1List<T> retval = new ArrayList<T>(list.size());
an implementation by itself?
Absolutely! For more flexibility, the “new” statement in the implementation body has to be delegated out as well. We introduce a ReturnDelegate interface:
1interface ReturnDelegate<R extends Collection<?>> {
2 R createReturnCollection();
3}
and plug in the return delegate to the map method:
1<FromType, ToType, R extends Collection<?>> R map(Collection<FromType> coll, MapDelegate<FromType, ToType> mapDelegate, ReturnDelegate<R> returnDelegate) {
2 R retval = returnDelegate.createReturnCollection();
3 for (FromType item : list) {
4 retval.add(mapDelegate.map(item));
5 }
6 return retval;
7}
Now the actual implementation has been completely separated. I know you can probably achieve flexibility without return delegate with the use of reflection, but on some systems (like GWT, which is what I’m working on and what this code is originally designed for), reflection is off limits.
更多消息请看Use delegation to write map/filter in Java