sum :: Num a => a -> a -> a
sum x y = x + y
sum 2 3
def sum(x: Int)(y: Int): Int = {
x + y
}
sum(2)(3)
public int sum(int a, int b){
return a + b;
}
sum(2, 3);
public static int sumOfSquares(int[] input) {
int sum = 0;
for(int i: input){
sum += i * i;
}
return sum;
}
def sumOfSquares(xs: Array[Int]): Int = {
var sum = 0
for(i <- xs){
sum += i * i
}
sum
}
def sumOfSquares(xs: Array[Int]): Int = {
xs.foldLeft(0)((sum, x) => sum + (x * x))
}
sumOfSquares :: Num a => [a] -> a
sumOfSquares xs = foldl (\sum x -> sum + (x * x)) 0 xs
def sumOfSquares(xs: Array[Int]): Int = {
xs.map(x => x * x).reduceLeft((sum, x) => sum + x)
}
sumOfSquares :: Num a => [a] -> a
sumOfSquares xs = foldl1 (\sum x -> sum + x) (map (\x -> x * x) xs)
public static int sumSquares(final Integer[] input) {
final Collection<Integer> squared =
Collections2.transform(Arrays.asList(input),
new Function<Integer, Integer>() {
public Integer apply(Integer integer) {
return integer * integer;
}
});
int sum = 0;
for(int i: squared){
sum += i;
}
return sum;
}
These [functional idioms] are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code "a one-liner," the Guava team weeps.
public static int sumSquares(int[] input) {
for(int i=0; i<input.length; i++){
input[i] = input[i] * input[i];
}
int sum = 0;
for(int i: input){
sum += i;
}
return sum;
}
public static int sumSquares(final Collection<Integer> input) {
final Collection<Integer> squared =
Collections2.transform(input,
new Function<Integer, Integer>() {
public Integer apply(Integer integer) {
return integer * integer;
}
});
int sum = 0;
for(int i: squared){
sum += i;
}
return sum;
}
public static <T> int mapThenSum(final Collection<T> input,
final Function<T, Integer> processor) {
final Collection<Integer> processed =
Collections2.transform(input, processor);
int sum = 0;
for(int i: processed){
sum += i;
}
return sum;
}
public static <T, U, V> V mapReduce(final Collection<T> input,
final Function<T, U> mapper,
final Function<V, Function<U, V>> reducer,
final V initial) {
final Collection<U> mapped =
Collections2.transform(input, mapper);
V result = initial;
for(U value : mapped){
final Function<U, V> toApply = reducer.apply(result);
result = toApply.apply(value);
}
return result;
}
mapReduce(Lists.newArrayList(1, 2),
new Function<Integer, Integer>() {
public Integer apply(final Integer integer) {
return integer * integer;
}
}, new Function<Integer, Function<Integer, Integer>>() {
public Function<Integer, Integer> apply(final Integer a) {
return new Function<Integer, Integer>() {
public Integer apply(final Integer b) {
return a + b;
}
};
};
}, 0));
public static <T, U, V> V mapReduce(final Iterator<T> input,
final Function<T, U> mapper,
final Function<V, Function<U, V>> reducer,
final V initial) {
if (!input.hasNext()) {
return initial;
} else {
final V next = reducer.apply(initial).apply(mapper.apply(input.next()));
return reduce(input, mapper, reducer, next);
}
}
mapReduce(Iterators.forArray(1, 2),
new Function<Integer, Integer>() {
public Integer apply(final Integer integer) {
return integer * integer;
}
}, new Function<Integer, Function<Integer, Integer>>() {
public Function<Integer, Integer> apply(final Integer a) {
return new Function<Integer, Integer>() {
public Integer apply(final Integer b) {
return a + b;
}
};
};
}, 0));
Executors.newSingleThreadExecutor().submit(new Runnable() {
public void run() {
// ...
}
});
Collections.sort(collection, new Comparator<T>() {
public int compare(T o1, T o2) {
// ...
}
});
Collection<String> presenters =
Lists.newArrayList("Gray", "Michael", "Caroline", "Will");
Predicate<String> query = Predicates.or(
new Predicate<String>() {
public boolean apply(String o) {
return o.startsWith("M");
}
}, new Predicate<String>() {
public boolean apply(String o) {
return o.startsWith("C");
}
});
Collections2.filter(presenters, query); // { "Michael", "Caroline" }
Collection<String> presenters =
Lists.newArrayList("Gray", "Michael", "Caroline", "Will");
final Function<String, String> capitalizeAndReverse =
Functions.compose(new Function<String, String>() {
public String apply(final String s) {
return s.toUpperCase();
}
}, new Function<String, String>() {
public String apply(final String s) {
final char[] chars = s.toCharArray();
for(int i = 0, j = chars.length - 1;
i < chars.length / 2; i++, j--) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
return new String(chars);
}
}
);
Collections2.transform(presenters, capitalizeAndReverse); // { "YARG", "LEAHCIM", "ENILORAC", "LLIW" }
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import java.util.function.Function;
import java.util.function.Predicate;
final List<String> presenters =
Arrays.asList("Gray", "Michael", "Caroline", "Will");
presenters.stream()
.filter(s -> s.startsWith("G") || s.startsWith("M"))
.forEach(s -> System.out.println(s));
final List<String> presenters =
Arrays.asList("Gray", "Michael", "Caroline", "Will");
presenters.stream()
.filter(s -> s.startsWith("G") || s.startsWith("M"))
.forEach(System.out::println);
Stream
@FunctionalInterface
map
flatMap
filter
reduce
forEach
findFirst
final List<String> strings = Arrays.asList("Gray", "Michael", "Caroline", "Will");
strings.stream()
.filter(s -> s.startsWith("G") || s.startsWith("M"))
.forEach(System.out::println);
strings.stream()
.allMatch(s -> s.length() > 3); // true
strings.stream()
.count(); // 4
strings.stream()
.map(String::toUpperCase)
.collect(Collectors.joining()); // GRAYMICHAELCAROLINEWILL
final List<String> strings = Arrays.asList("Gray", "Michael", "Caroline", "Will");
strings.parallelStream()
.filter(s -> s.startsWith("G") || s.startsWith("M"))
.forEach(System.out::println);
strings.parallelStream()
.allMatch(s -> s.length() > 3); // true
strings.parallelStream()
.count(); // 4
strings.parallelStream()
.map(String::toUpperCase)
.collect(Collectors.joining()); // GRAYMICHAELCAROLINEWILL
package java.util.function;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R>
compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V>
andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
excerpt from java/util/function/Function.java
package scala
trait Function1[-T1, +R] extends AnyRef { self =>
def apply(v1: T1): R
def compose[A](g: A => T1): A => R = { x => apply(g(x)) }
def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) }
}
excerpt from scala/Function1.scala
scala> val x = List((1,2)).toMap
x: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2)
scala> x.get(1)
res2: Option[Int] = Some(2)
scala> x.get(3)
res3: Option[Int] = None
scala> x.getOrElse(4, 5)
res4: Option[Int] = 5
Prelude> import qualified Data.Map.Lazy as M
Prelude M> let x = M.fromList[(1,2)]
Prelude M> M.lookup 1 x
Just 2
Prelude M> M.lookup 3 x
Nothing
Prelude M> M.findWithDefault 5 4 x
5
null
mean?
HashMap<Integer, Integer> someHashMap = new HashMap<>();
someHashMap.put(1, 2);
Optional<Integer> foo = Optional.fromNullable(someHashMap.get(1));
Optional<Integer> bar = Optional.fromNullable(someHashMap.get(3));
if (foo.isPresent()) foo.get(); // 2
bar.isPresent(); // false
bar.get(); // IllegalStateException
bar.or(5); // 5
import com.google.common.base.Optional;
/* or */
import java.util.Optional;