Functional Idioms
Predicates class & Predicate interface
Iterables
all
any
find
filter
transform
Collections2
filter
transform
Lists
transform
Sets
filter
Maps
filterEntries
filterKeys
filterValues
uniqueIndex
transformValues
Iterables.filter(Iterable, Predicate)
FluentIterable.filter(Predicate)
Iterators.filter(Iterator, Predicate)
Collections2.filter(Collection, Predicate)
Sets.filter(Set, Predicate)
Sets.filter(SortedSet, Predicate)
Maps.filterKeys(Map, Predicate)
Maps.filterValues(Map, Predicate)
Maps.filterEntries(Map, Predicate)
Maps.filterKeys(SortedMap, Predicate)
Maps.filterValues(SortedMap, Predicate)
Maps.filterEntries(SortedMap, Predicate)
Multimaps.filterKeys(Multimap, Predicate)
Multimaps.filterValues(Multimap, Predicate)
Multimaps.filterEntries(Multimap, Predicate)
boolean all(Iterable, Predicate)
Iterators.all(Iterator, Predicate)
FluentIterable.allMatch(Predicate)
boolean any(Iterable, Predicate)
Iterators.any(Iterator, Predicate)
FluentIterable.anyMatch(Predicate)
T find(Iterable, Predicate)
Iterators.find(Iterator, Predicate)
Iterables.find(Iterable, Predicate, T default)
Iterators.find(Iterator, Predicate, T default)
Optional<T> tryFind(Iterable, Predicate)
Iterators.tryFind(Iterator, Predicate)
FluentIterable.firstMatch(Predicate)
indexOf(Iterable, Predicate)
Iterators.indexOf(Iterator, Predicate)
removeIf(Iterable, Predicate)
Iterators.removeIf(Iterator, Predicate)
Predicates
alwaysFlase 常にfalseを返す
alwaysTrue 常にtrueを返す
and 複数のPredicateを合わせた結果を返す
compose Functionの変換後の値をpredicateに渡す
equals 同じどうか
in collectionに含まれるかどうか
instanceOf クラスのインスタンスかどうか
isNull nullかどうか
not 結果を逆にする
notNull nullでないかどうか
or 複数のPredicateのいずれかがtrueの場合、trueを返す
Predicates.and(Iterable<Predicate<T>> predicates)
Predicates.and(Predicate<T>... predicates)
Predicate predicate = Predicates.and(aPredicate, bPredicate);
Predicates.or(Iterable<Predicate<T>> predicates)
Predicates.or(Predicate<T>... predicates)
Predicate predicate = Predicates.or(aPredicate, bPredicate);
Predicate predicate = Predicates.not(xPredicate);
Map<String, State> stateMap = ...;
Function<String,State> lookup = Functions.forMap(stateMap);
Predicate<String> predicate = Predicates.compose(xPredicate, lookup);
Functions class & Function interface
Iterables.transform(Iterable, Function)
FluentIterable.transform(Function)
Iterators.transform(Iterator, Function)
Collections2.transform(Collection, Function)
Lists.transform(List, Function)
Maps.transformValues(Map, Function)
Maps.transformEntries(Map, EntryTransformer)
Maps.transformValues(SortedMap, Function)
Maps.transformEntries(SortedMap, EntryTransformer)
Multimaps.transformValues(Multimap, Function)
Multimaps.transformEntries(Multimap, EntryTransformer)
Multimaps.transformValues(ListMultimap, Function)
Multimaps.transformEntries(ListMultimap, EntryTransformer)
Tables.transformValues(Table, Function)
Functions
compose 一つ目のFunctionの値を2つ目のFunctionの元にして値を返す
constant 常に一定の値を返す
forMap mapから値を取り出す
(値がnullの場合、IllegalArgumentException発生。デフォルト値指定可)
forPredicate Predicateの結果を返す
identity 変換元をそのまま返す
toStringFunction toString()した文字列を返す
Map<String, State> stateMap = ...;
Function<String,State> lookup = Functions.forMap(stateMap);
State state = lookup.apply("NY");
Function<State, String> stateFunction = new Function<State, String> {
@Override
public String apply(State input) {
return Joiner.on(",").join(input.getCities());
}
};
Function<String,String> composed =
Functions.compose(stateFunction, lookup);
String cities = composed.apply("NY");
あるいは
String cities = stateFunction.apply(lookup.apply("NY"));
Suppliers class & Supplier interface
private final LargeObject largeObject;
private Double average;
public Sample(LargeObject largeObject) {
this.largeObject = largeObject;
}
public Double calcAverage() {
if (average != null) {
return average;
}
// largeObjectに対する処理
return average;
}
↓
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
private final Supplier<Double> average;
public Sample(final LargeObject largeObject) {
Supplier<Double> supplier = new Supplier<Double>() {
@Override
public Double get() {
// largeObjectに対する処理
return average;
}
};
average = Suppliers.memoize(supplier);
}
public Double calcAverage() {
return average.get();
}
Supplier<Predicate<String>> supplier =
Suppliers.memoizeWithExpiration(xSupplier, 5L, TimeUnit.MINUTES);
サンプル1
List<Integer> list = Ints.asList(1, 2, 3, 4, 5);
Collection<Integer> evenList = Collections2.filter(list,
new Predicate<Integer>() {
@Override
public boolean apply(Integer input) {
return input % 2 == 0;
}
}
);
List<Integer> negativeList = Lists.transform(list,
new Function<Integer, Integer>() {
@Override
public Integer apply(Integer input) {
return -1 * input;
}
}
);
Collection<Employee> result = Collections2.filter(empList,
new Predicate<Employee>() {
@Override
public boolean apply(Employee emp) {
return emp.empNo <= 100;
}
}
);
Collection<String> result = Collections2.transform(empList,
new Function<Employee, String>() {
@Override
public String apply(Employee emp) {
return emp.name;
}
}
);
サンプル2
//書き方1
Function<String, Integer> lengthFunction = new Function<String, Integer>() {
public Integer apply(String string) {
return string.length();
}
};
Predicate<String> allCaps = new Predicate<String>() {
public boolean apply(String string) {
return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
}
};
Multiset<Integer> lengths = HashMultiset.create(
Iterables.transform(Iterables.filter(strings, allCaps), lengthFunction)
);
//書き方2
Multiset<Integer> lengths = HashMultiset.create(
FluentIterable.from(strings)
.filter(new Predicate<String>() {
public boolean apply(String string) {
return CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string);
}
})
.transform(new Function<String, Integer>() {
public Integer apply(String string) {
return string.length();
}
})
);
//書き方3
Multiset<Integer> lengths = HashMultiset.create();
for (String string : strings) {
if (CharMatcher.JAVA_UPPER_CASE.matchesAllOf(string)) {
lengths.add(string.length());
}
}
サンプル3
List<String> names;
Map<String, Person> personWithName;
List<Person> people
= Lists.transform(names, Functions.forMap(personWithName));
ListMultimap<String, String> firstNameToLastNames;
ListMultimap<String, String> firstNameToName =
Multimaps.transformEntries(firstNameToLastNames,
new EntryTransformer<String, String, String> () {
public String transformEntry(String firstName, String lastName) {
return firstName + " " + lastName;
}
}
);
注意点:Functionがシリアライズできないため
return Lists.transform(listA, new Function(...));
↓
listB = Lists.transform(listA, new Function(...));
return Lists.newArrayList(listB);
あるいは
return ImmutableList.copyOf(listB);