在guava中存在一个com.google.common.base.Functions和com.google.common.base.Function类,利用他们,可以为集合类的转换提供自定义的转换函数。
首先我们看第一个例子,简单的自定义一个函数,然后用于一个简单的list对象的转换,代码如下:
初始化的代码:
static class School { public String name; public String location; public static School newSchool(String name,String loc) { School s = new School(); s.name = name; s.location = loc; return s; } } Listschools; @Before public void init() { schools = Lists.newLinkedList(); schools.addAll(Arrays.asList(School.newSchool("xigongda", "xi'an"), School.newSchool("xijiaoda", "chengdu"))); } @After public void end() { if(schools!=null) { schools.clear(); } }
下面开始第一个测试,我们将定义一个功能函数,然后在集合转换的时候使用它,最后测试结果,如下:
@Test public void testFunctions1() { //测试一个功能函数,用于集合转换 //1、定义一个功能函数,用于将School类转为地址字符串 Functionf = new Function () { @Override public String apply(School s) { if(s==null) { return ""; } return s.location; } }; //2、开始转换集合 Collection locationList = Collections2.transform(schools, f); //3、验证结果含有期望的值 assertThat(locationList, hasItems("xi'an","chengdu")); }
这个比较简单,但是可能有些情况需要将不同的函数组合起来,进行合并运算,比如先执行一个转换,然后再执行一个大小写的转换,这个情况guava也是支持的,代码如下:
@Test public void testFunctions2() { //测试组合两个功能函数,用于集合转换 //1、定义第一个功能函数,用于将School类转为地址字符串,即:f(school)=location Functionf = new Function () { @Override public String apply(School s) { if(s==null) { return ""; } return s.location; } }; //2、定义第二个功能函数,用于转换大小写,即:f(string)=STRING Function f2 = new Function () { @Override public String apply(String s) { if(s==null) { return ""; } return s.toUpperCase(); } }; //3、定义函数组合,将对每个元素执行f,然后对结果进行f2计算,即:result=f2(f(school)) Function f3 = Functions.compose(f2, f); //4、开始转换集合 Collection locationList = Collections2.transform(schools, f3); //5、验证结果含有期望的值 assertThat(locationList, hasItems("XI'AN","CHENGDU")); }
最后,guava还支持预定义的基于map的映射函数,即给他一个Map,他会按照Map的key/value定义,将集合的元素逐个和key匹配,如果发现匹配的,则返回value,代码如下:
@Test public void testForMap() { //测试对map的预定义函数,即使用forMap构造的函数,在集合转换的时候会被自动映射 //1、定义映射表 Mapm = Maps.newHashMap(); m.put(schools.get(0), "hangtian"); //m.put(schools.get(1), "tielu"); //2、定义函数 Function f = Functions.forMap(m,"UNKNOWN"); //3、转换,此时会对schools中的每个元素调用映射进行转换,得到学校属性 Collection types = Collections2.transform(schools, f); //4、验证 assertThat(types, hasItems("hangtian","UNKNOWN")); }