powered by JΛVΛ
LΛNG
@arekjurasz
arkadiusz.jurasz@gmail.com
"Javaslang core is a functional library for Java 8+. It helps to reduce the amount of code and to increase the robustness. A first step towards functional programming is to start thinking in immutable values. Javaslang provides immutable collections and the necessary functions and control structures to operate on these values. The results are beautiful and just work."
Tuple3<String, Long, Double> newTuple3 = tuple3.map((first, second, third) ->
Tuple.of(first.toUpperCase(), second * 10, third - 0.5)
);
assertThat(newTuple3._1).isEqualTo("STRING");
assertThat(newTuple3._2).isEqualTo(100L);
assertThat(newTuple3._3).isEqualTo(5.0);assertThat(tuple3._1).isEqualTo("String");
assertThat(tuple3._2()).isEqualTo(10L);Tuple3<String, Long, Double> tuple3 = Tuple.of("String", 10L, 5.5);Function1<String, String> mapFirstFunc = String::toLowerCase;
Function1<Long, Long> mapSecondFunc = l -> l + 1;
Function1<Double, Double> mapThirdFunc = d -> 0.0;
Tuple3<String, Long, Double> newTuple3 = tuple3.map(mapFirstFunc,
mapSecondFunc, mapThirdFunc);
assertThat(newTuple3._1).isEqualTo("string");
assertThat(newTuple3._2).isEqualTo(11L);
assertThat(newTuple3._3).isEqualTo(0.0);String transformed = tuple3.transform((first, second, third) ->
first + second + third);
assertThat(transformed).isEqualTo("String105.5");Tuple3<String, Long, Double> newTuple3 = tuple3.map2(second -> 0L);
assertThat(newTuple3._2).isEqualTo(0L);@FunctionalInterface
public interface TriFunction<A, B, C, R> {
R apply(A a, B b, C c);
}Function<Integer, Function<Integer, Function<Integer, Integer>>> addTri =
a -> (b -> (c -> a + b + c));
assertThat(addTri.apply(1).apply(2).apply(3)).isEqualTo(6);@FunctionalInterface
public interface TriFunctionChecked<A, B, C, R> {
R apply(A a, B b, C c) throws Exception;
}CheckedFunction2<Integer, Integer, Integer> divide = (a, b) -> a / b;
assertThat(catchThrowable(() -> divide.apply(3, 0)))
.isInstanceOf(ArithmeticException.class);public static Integer add(Integer a, Integer b) {
return a + b;
}
Function2<Integer, Integer, Integer> addMethodReference =
Function2.of(Functions::add);
assertThat(addMethodReference.apply(5, 5)).isEqualTo(10);Function1<Integer, Integer> plusOne = a -> a + 1;
Function1<Integer, Integer> multiplyByTwo = a -> a * 2;Function1<Integer, Integer> add1AndMultiplyBy2 = plusOne.andThen(multiplyByTwo);
assertThat(add1AndMultiplyBy2.apply(1)).isEqualTo(4);Function1<Integer, Integer> add1AndMultiplyBy2 = multiplyByTwo.compose(plusOne);
then(add1AndMultiplyBy2.apply(1)).isEqualTo(4);Function2<Integer, Integer, Integer> divide = (a, b) -> a / b;Function2<Integer, Integer, Option<Integer>> safeDivide = Function2.lift(divide);
Option<Integer> i1 = safeDivide.apply(1, 0);
Option<Integer> i2 = safeDivide.apply(4, 2);
assertThat(i1).isEqualTo(Option.none());
assertThat(i2).isEqualTo(Option.of(2));Function2<Integer, Integer, Integer> func = (a, b) -> (2 * a) + b;
Function1<Integer, Integer> func2 = func.curried().apply(2);
// func2 = (b) -> (2*2) + b;
assertThat(func2.apply(4)).isEqualTo(8);Function0<Double> hashCache =
Function0.of(Math::random).memoized();
double randomValue1 = hashCache.apply();
double randomValue2 = hashCache.apply();
assertThat(randomValue1).isEqualTo(randomValue2);Option<Integer> op1 = Option.of(1); // Some(1)
Option<Integer> op2 = Option.of(null); // None
Option<Integer> op3 = Option.some(2); // Some(2)
Option<Integer> op4 = Option.none(); // None
assertThat(op1).isInstanceOf(Option.Some.class);
assertThat(op2).isInstanceOf(Option.None.class);String result = Try.of(() -> "Try this function")
.getOrElseGet(throwable -> "Ups");
assertThat(result).isEqualTo("Try this function");String result = Try.of(Values::throwException)
.recover(throwable -> "Recovered")
.getOrElseGet(throwable -> "Ups");
assertThat(result).isEqualTo("Recovered");Lazy<Double> lazy = Lazy.of(Math::random);
assertThat(lazy.isEvaluated()).isFalse();
lazy.get();
assertThat(lazy.isEvaluated()).isTrue();
assertThat(lazy.get()).isEqualTo(lazy.get());CharSequence chars = Lazy.val(() -> "Yay!", CharSequence.class);public interface MyInterface {
DtoObject compute();
}
public class DtoObject {
private final Integer x;
private final Integer y;
(...)
}
MyInterface lazy = Lazy.val(() -> {
MyInterface dtoInterface = () -> new DtoObject(1, 2);
return dtoInterface;
}, MyInterface.class);public static Either<String,Integer> computeL() {
return Either.left("Error");
}
public static Either<String,Integer> computeR() {
return Either.right(1);
}
//--
Function0<Either<String,Integer>> compute = Function0.of(Values::computeL);
Either<String,Integer> value = compute.apply().right()
.map(i -> i * 2)
.toEither();
assertThat(value).isInstanceOf(Either.Left.class);
assertThat(value.getLeft()).isEqualTo("Error");
//--
Function0<Either<String,Integer>> compute = Function0.of(Values::computeR);
Either<String,Integer> value = compute.apply().right()
.map(i -> i * 2)
.toEither();
assertThat(value).isInstanceOf(Either.Right.class);
assertThat(value.get()).isEqualTo(2);Future<Integer> future = Future.of(() -> {
Thread.sleep(1000L);
return 10;
});
System.out.println("First");
future.onSuccess(System.out::println);
future.await();assertThat(Arrays.asList(1, 2, 3).stream().mapToInt(i -> i).sum()).isEqualTo(6);
assertThat(List.of(1, 2, 3).sum()).isEqualTo(6);
assertThat(List.of(1, 2, 3).head()).isEqualTo(1);
assertThat(List.of(1, 2, 3).tail()).isEqualTo(List.of(2, 3));
//--
java.util.List java8 = Arrays.asList(1, 2, 3).stream()
.map(i -> i * 2)
.collect(toList());
List javaslang = List.of(1, 2, 3).map(i -> i * 2);
assertThat(java8).isEqualTo(Arrays.asList(2, 4, 6));
assertThat(javaslang.toJavaList()).isEqualTo(Arrays.asList(2, 4, 6));
//--
String java8 = Arrays.asList("a", "b", "c").stream().collect(Collectors.joining(", "));
String javaslang = List.of("a", "b", "c").mkString(", ");
assertThat(java8).isEqualTo("a, b, c");
assertThat(javaslang).isEqualTo("a, b, c");$() - wildcard pattern
$(value) - equals pattern
$(predicate) - conditional pattern
Integer i = 1;
String s = Match(i).of(
Case($(1), "one"),
Case($(2), "two"),
Case($(), "?")
);
assertThat(s).isEqualTo("one");Option<String> s = Match(i).option(
Case($(0), "zero")
);
assertThat(s).isEqualTo(Option.none());//import static javaslang.Patterns.*;
Match(_try).of(
Case(Patterns.Success($()), value -> ...),
Case(Patterns.Failure($()), x -> ...)
);import static javaslang.Predicates.*;
Integer i = 1;
String s = Match(i).of(
Case(is(1), "Yes"),
Case(noneOf(is(2), is(3)), "No"),
Case($(), "?")
);
assertThat(s).isEqualTo("Yes");Tuple2<Integer, Integer> tuple = Tuple.of(10, 20);
String s = Match(tuple).of(
Case(Patterns.Tuple2($(x -> x == 10), $()), "_1 == 10"),
Case($(), "?")
);
assertThat(s).isEqualTo("_1 == 10");class Person {
String name;
Address address;
}
class Address {
String street;
int number;
}
Tuple3<Integer, String, Double> tuple3 = Tuple.of(1, "two", 2.5);
String result = Match(tuple3).of(
Case(Patterns.Tuple3($(), $("two"), $()), (_1, _2, _3) ->
"elements " + _1 + _2 + _3),
Case($(), "default")
);
assertThat(result).isEqualTo("elements 1two2.5");Option<Integer> op1 = Option.none();
Integer result = Match(op1).of(
Case(Patterns.Some($()), v -> v * 10),
Case(Patterns.None(), -1)
);
assertThat(result).isEqualTo(-1);if (person != null && "Carl".equals(person.getName())) {
Address address = person.getAddress();
if (address != null) {
String street = address.getStreet();
int number = address.getNumber();
...
}
}
}Match(person).of(
Case(Person($("Carl"), Address($(), $())), (p, a) -> ...)
)@Patterns
class Starter {
@Unapply
static Tuple2<String, Address> Person(Person person) {
return Tuple.of(person.getName(), person.getAddress());
}
@Unapply
static Tuple2<String, Integer> Address(Address address) {
return Tuple.of(address.getStreet(), address.getNumber());
}
}Blog Bartka Kuczyńskiego:
http://koziolekweb.pl/2016/06/17/pattern-matching-w-javie-z-javaslang-i/
http://koziolekweb.pl/2016/06/18/pattern-matching-w-javie-z-javaslang-ii/
http://koziolekweb.pl/2016/06/19/pattern-matching-w-javie-z-javaslang-iii/
http://koziolekweb.pl/2016/06/20/pattern-matching-w-javie-z-javaslang-iv/
Dokumentacja javaslang:
http://www.javaslang.io/javaslang-docs/Blog javaslang (outdated)
http://blog.javaslang.io/pattern-matching-starter/
http://blog.javaslang.io/pattern-matching-essentials/Repozytorium z przykładami
http://github.com/ajurasz/bbjug-javaslang