模拟实现Guava中,输入一个List<F>, 实现一个抽象方法,即可获取输出的List<T>. 即 List<F> => List<T>.
注意,在远程调用RPC,例如navi-rpc当中使用时,请不要使用Function以及Predicate返回的Collection、List等对象传输。
原因是navi-rpc使用的Runtimeprotobuf,会利用反射构造出属性未填充的空对象,然后再merge字节流进去,这时候如果是guava内部封装的内部类,而不是ArrayList等JDK实现类,会出现一些意外的错误,原因是guava的内部类有些是不支持添加修改操作的。
class Person implements Comparable<Person> {
private String name;
private int age;
/**
* @param name
* @param age
*/
public Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
return Objects.hashCode(age, name);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person that = (Person) obj;
return Objects.equal(age, that.age) && Objects.equal(name, that.name);
}
return false;
}
@Override
public String toString() {
return Objects.toStringHelper(this).add("name", name).add("age", age).toString();
}
@Override
public int compareTo(Person o) {
return ComparisonChain.start().compare(name, o.name).compare(age, o.age).result();
}
}
import java.util.Iterator;
import java.util.List;
import java.util.RandomAccess;
import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Lists;
public class TestMain {
public static void main(String[] args) {
/******************** 初始化数据 ************************/
List<Person> persionArrayList = Lists.newArrayList();
persionArrayList.add(new Person("peter", 12));
persionArrayList.add(new Person("tony", 24));
persionArrayList.add(null);
persionArrayList.add(new Person("jason", 11));
persionArrayList.add(new Person("tomson", 21));
List<Person> persionLinkedList = Lists.newLinkedList();
persionLinkedList.add(new Person("peter", 12));
persionLinkedList.add(new Person("tony", 24));
persionLinkedList.add(null);
persionLinkedList.add(new Person("jason", 11));
persionLinkedList.add(new Person("tomson", 21));
/******************** 实现抽象并调用 ************************/
List<String> nameList = myTransform(persionLinkedList, new FTWork<Person, String>() {
@Override
public String apply(Person acc) {
return acc == null ? "" : acc.getName();
}
});
/******************** 实现抽象并调用 ************************/
List<Integer> ageList = myTransform(persionArrayList, new FTWork<Person, Integer>() {
@Override
public Integer apply(Person acc) {
return acc == null ? -1 : acc.getAge();
}
});
System.out.println(nameList);
System.out.println(ageList);
}
/**
* 进行转化的方法
*
* @param fromList 需要进行转化的对象集合
* @param work 抽象工作类
* @return List<T> 转化后的结果集
*
* @author zhoudongdong
*/
public static <F, T> List<T> myTransform(List<F> fromList, FTWork<? super F, ? extends T> work) {
List<T> resultList = Lists.<T> newArrayList();
if (fromList instanceof RandomAccess) {
System.out.println("instanceof RandomAccess ...");
for (int i = 0; i < fromList.size(); ++i) {
resultList.add((T) work.apply(fromList.get(i)));
}
} else {
System.out.println("instanceof SequenceList ...");
for (Iterator<F> itr = fromList.iterator(); itr.hasNext();) {
resultList.add((T) work.apply(itr.next()));
}
}
return resultList;
}
/**
* 工作抽象类
* <p>
*
* @author zhoudongdong
*/
static abstract class FTWork<F, T> {
public abstract T apply(F f);
}
}
输出结果:
instanceof SequenceList ...
instanceof RandomAccess ...
[peter, tony, , jason, tomson]
[12, 24, -1, 11, 21]