Function用于定义一类对象的方法,将一个集合转换为其他类型集合,主要用于Colllections2, Lists, Iterables, Iterators,等类的transform方法,Functions类提供很多预定义的方法能将一组对象组合成一个复杂的对象。
简单示例 - 将countries集合转换为capital cities集合
@Test public void shouldPrintCountryWithCapitalCityUpperCase() throws Exception { // given Function<Country, String> capitalCityFunction = new Function<Country, String>() { public String apply(@Nullable Country country) { if (country == null) { return ""; } return country.getCapitalCity(); } }; // when Collection<String> capitalCities = Collections2.transform(Country.getSomeCountries(), capitalCityFunction); // then assertThat(capitalCities).contains("Warsaw", "Madrid"); }
Functions.compose() - 将两个或者多个functions对象组合成一个
@Test public void shouldComposeTwoFunctions() throws Exception { Function<Country, String> upperCaseFunction = new Function<Country, String>() { public String apply(@Nullable Country country) { if (country == null) { return ""; } return country.getCapitalCity().toUpperCase(); } }; Function<String, String> reverseFunction = new Function<String, String>() { public String apply(String string) { if(string == null) { return null; } return new StringBuilder(string).reverse().toString(); } }; Function<Country, String> composedFunction = Functions.compose(reverseFunction, upperCaseFunction); // when Collection<String> reversedCapitalCities = Collections2.transform(Country.getSomeCountries(), composedFunction); // then assertThat(reversedCapitalCities).contains("WASRAW", "DIRDAM"); }
Functions.forMap() - 预定义方法提供一组key从map中取出value
@Test public void shouldUseForMapFunction() throws Exception { // given Map<String, String> map = Maps.newHashMap(); map.put(Country.POLAND.getName(), Country.POLAND.getCapitalCity()); map.put(Country.BELGIUM.getName(), Country.BELGIUM.getCapitalCity()); map.put(Country.SPAIN.getName(), Country.SPAIN.getCapitalCity()); map.put(Country.ENGLAND.getName(), Country.ENGLAND.getCapitalCity()); // when Function<String, String> capitalCityFromCountryName = Functions.forMap(map); List<String> countries = Lists.newArrayList(); countries.add(Country.POLAND.getName()); countries.add(Country.BELGIUM.getName()); // then Collection<String> capitalCities = Collections2.transform(countries, capitalCityFromCountryName); assertThat(capitalCities).containsOnly(Country.POLAND.getCapitalCity(), Country.BELGIUM.getCapitalCity()); }
Functions.forMap() - 当没有找到对应的value,程序会抛出异常。这一种情况可以用设定默认值来改变。
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Key 'Belgium' not present in map") public void shouldUseForMapFunctionWithNonExistingKey() throws Exception { // given Map<String, String> map = Maps.newHashMap(); map.put(Country.POLAND.getName(), Country.POLAND.getCapitalCity()); // we omit this one intentionally // map.put(Country.BELGIUM.getName(), Country.BELGIUM.getCapitalCity()); map.put(Country.SPAIN.getName(), Country.SPAIN.getCapitalCity()); map.put(Country.ENGLAND.getName(), Country.ENGLAND.getCapitalCity()); // when Function<String, String> capitalCityFromCountryName = Functions.forMap(map); List<String> countries = Lists.newArrayList(); countries.add(Country.POLAND.getName()); countries.add(Country.BELGIUM.getName()); // then Collection<String> capitalCities = Collections2.transform(countries, capitalCityFromCountryName); assertThat(capitalCities).containsOnly(Country.POLAND.getCapitalCity(), Country.BELGIUM.getCapitalCity()); }
@Test public void shouldUseForMapFunctionWithDefaultValue() throws Exception { // given Map<String, String> map = Maps.newHashMap(); map.put(Country.POLAND.getName(), Country.POLAND.getCapitalCity()); // we omit this one intentionally // map.put(Country.BELGIUM.getName(), Country.BELGIUM.getCapitalCity()); map.put(Country.SPAIN.getName(), Country.SPAIN.getCapitalCity()); map.put(Country.ENGLAND.getName(), Country.ENGLAND.getCapitalCity()); // when Function<String, String> capitalCityFromCountryName = Functions.forMap(map, "Unknown"); List<String> countries = Lists.newArrayList(); countries.add(Country.POLAND.getName()); countries.add(Country.BELGIUM.getName()); // then Collection<String> capitalCities = Collections2.transform(countries, capitalCityFromCountryName); assertThat(capitalCities).containsOnly(Country.POLAND.getCapitalCity(), "Unknown"); }