在java中使用委托实现map/filter

在java中,假设你有一个user 对象的list,此user对象封装了用户的id, first name, last name and age. 然后你想调用一个web service(eg. UserService.deleteUsersByIds(List<Integer> userIds) 去删除数据库中指定的这些user。  听起来似乎不太困难,不是么? 你所需要只是将 所有你先写下下面的代码:

 

 

然后你继续使用您的ID list,这一切都非常好。

但是,两分钟后,你会发现自己不得不为获取一个String型的用户名列表而重新定义一个API方法。

 

或许你还需要一个21岁以下的user list。

  

或许你还需要的更多。。。。
很快你发现这件事情变得很乏味。
根据目前情形,你会发现这里有2个非常重要的功能 map 和filter
1.map(coll, f):遍历集合coll, 在集合中调用f的方法,将f的方法处理结果装入一个集合返回(也就是调用f中的方法组装另外一个需要的集合,然后返回)。
2.filter(coll, f):遍历集合coll, 在集合中调用f的方法,当f(element) returns true 将结果装入一个集合返回。
为了达到上面得到Id 的List我们可能需要这样中

这样看起来似乎跟下面的code没有什么区别。
1 List<Integer> ids = new ArrayList<Integer>(users.size());
2for (User user : users) {
3  ids.append(user.getId());
4}
由于java不提供语言级别的委托,因此我们需要为这个委派提供一个接口
1interface MapDelegate<FromType, ToType> {
2  ToType map(FromType obj);
3}
委托是参数化(提供FromType和ToType更多类型安全)。FromType是在原来的列表中的对象类型,ToType就是对象的映射类型的清单。现在,我们需要改变我们的方法签名,以纳入委托。
 
1 <FromType, ToType> List<ToType> map(ArrayList<FromType> list, MapDelegate<FromType, ToType> mapDelegate) {
2  List<ToType> retval = new ArrayList<ToType>(list.size());
3  for (FromType item : list) {
4    retval.add(mapDelegate.map(item));
5  }
6  return retval;
7}
 
 
<FromType, ToType> List<ToType> map(ArrayList<FromType> list, MapDelegate<FromType, ToType> mapDelegate) {
2  List<ToType> retval = new ArrayList<ToType>(list.size());
3  for (FromType item : list) {
4    retval.add(mapDelegate.map(item));
5  }
6  return retval;
7}
 
Now the client code will look like this:
 ================================================
1 List<User> users = getUserListFromSomeWhere();
2List<String> names= map(users, new MapDelegate<User,String>() {
3  public String map(User obj) {
4    return new StringBuilder(user.getFirstName()).append(" ").append("user.getLastName()).toString();
5  }
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函数

 

  

 

 Now the client code will look like this:

========================

 

 

========================

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值