Java 8+
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."
Show me some
CODE!
Tuple
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);Functions
@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);Values
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();Collections
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");Pattern matching
$() - 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());
}
}Resources
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-javaslangJava 8+ powered by javaslang
By Arkadiusz Jurasz
Java 8+ powered by javaslang
- 890