Skip to content

Instantly share code, notes, and snippets.

@msfroh
Last active December 11, 2015 19:28
Show Gist options
  • Save msfroh/4648290 to your computer and use it in GitHub Desktop.
Save msfroh/4648290 to your computer and use it in GitHub Desktop.
Project Lambda examples for my blog
public class DiamondTest {
private interface Print {
void print();
}
private interface Hello extends Print {
default void print() {
System.out.println("Hello");
}
}
private interface World extends Print {
default void print() {
System.out.println("World");
}
}
// This doesn't compile
private static class HelloWorld implements Hello, World {}
}
public interface Function0<R> extends Supplier<R> {
R evaluate();
default R get() {
return Function0ResultsHolder.resolveValue(this);
}
}
final class Function0ResultsHolder {
private static WeakHashMap<Function0, Object> results = new WeakHashMap<>();
static synchronized <R> R resolveValue(Function0<R> f) {
return (R) results.computeIfAbsent(f, (ff) -> ff.evaluate());
}
}
public interface Function1<T, R> extends Function<T, R> {
// Force evaluation of lazy input
default R apply(Supplier<T> input) {
return apply(input.get());
}
// Known input, lazy result
default Function0<R> applyLazy(T input) {
return () -> apply(input);
}
// Lazy input, lazy result
default Function0<R> applyLazy(Supplier<T> input) {
return () -> apply(input);
}
}
public interface Function2<T1, T2, R> extends BiFunction<T1, T2, R> {
// Partial application of a known result
default Function1<T2, R> apply(T1 i1) {
return (i2) -> apply(i1, i2);
}
// Partial application of a lazy result
default Function1<T2, R> apply(Supplier<T1> i1) {
return (i2) -> apply(i1.get(), i2);
}
}
@FunctionalInterface
public interface Function3<T1, T2, T3, R> {
// The functional application method
R apply(T1 i1, T2 i2, T3 i3);
// Partial application of a known result
default Function2<T2, T3, R> apply(T1 i1) {
return (i2, i3) -> apply(i1, i2, i3);
}
// Partial application of a lazy result
default Function2<T2, T3, R> apply(Supplier<T1> i1) {
return (i2, i3) -> apply(i1.get(), i2, i3);
}
// compose method consistent with Function and BiFunction
default <W> Function3<T1, T2, T3, W> compose(Function<R, W> after) {
return (i1, i2, i3) -> after.apply(apply(i1, i2, i3));
}
}
IntFunction<String> strlen = String::length;
public class LambdaTest {
private static <T, R> R foldLeft(BiFunction<R, T, R> f,
R init, Iterable<T> c) {
R out = init;
for (T elem : c) {
out = f.apply(out, elem);
}
return out;
}
@Test
public void testPartialApplication() throws Exception {
// Treat our method as a higher-order String foldLeft function:
Function3<BiFunction<String, String, String>, String,
Iterable<String>, String> stringOpFoldLeft = LambdaTest::foldLeft;
// Bind the string operator and seed value for the fold by partial application
Function1<Iterable<String>, String> concat =
stringOpFoldLeft.apply((a, b) -> a + b).apply("");
// Finally, pass collections as the third argument
assertEquals("abc", concat.apply(Arrays.asList("a", "b", "c")));
assertEquals("HelloWorld", concat.apply(Arrays.asList("Hello", "World")));
}
}
IntBinaryOperator addUgly = new IntBinaryOperator() {
@Override
public int applyAsInt(final int a, final int b) {
return a + b;
}
};
IntBinaryOperator add = (a, b) -> a + b;
public class LambdaTest {
private static int add(int a, int b) {
return a + b;
}
IntBinaryOperator add = LambdaTest::add;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment