Java generators with function.

I play with the functions of the Java utility. I have the following code:

public class Checker<T>{ private T value; private Function<T, T> callback; private Checker(T value) { this.value = value; } public static Checker when(String o) { return new Checker<String>(o); } public static Checker when(int o) { return new Checker<Integer>(o); } public Checker then(Function<T, T> callback) { this.callback = callback; return this; } public void execute() { if (this.value instanceof String) { this.callback.apply("123"); } if (this.value instanceof Integer) { this.callback.apply(123); } } Checker.when("123").then(str -> { return ""; }).execute(); Checker.when(123).then(str -> { return ""; }).execute(); 

Now I get an error for this.callback.apply("123") , because it requires T and cannot pass it to String .

Is it possible to have common return types for Function<T,T> ? I can send T , but then received it as Object in my lambda, but I want it as String or Integer .

+5
source share
3 answers

I made some changes to your Checker class, which makes sense to me. I removed all the raw types, and I used the value member in execute . I added the return type execute to be able to print its result.

 class Checker<T>{ private T value; private Function<T, T> callback; private Checker(T value) { this.value = value; } public static Checker<String> when(String o) { return new Checker<>(o); } public static Checker<Integer> when(int o) { return new Checker<>(o); } public Checker<T> then(Function<T, T> callback) { this.callback = callback; return this; } public T execute() { return this.callback.apply(value); } public static void main (String[] args) { Checker.when("123").then(str -> { return "." + str + "."; }).execute(); Checker.when(123).then(i -> { return i + 100; }).execute(); } } 

Now that you are checking your class with:

 System.out.println (Checker.when("123").then(str -> "." + str + ".").execute()); System.out.println (Checker.when(123).then(i -> i + 100).execute()); 

You are getting:

 .123. 223 
+6
source

This code can be further simplified, for example:

 static class Checker<T> { private final T value; private UnaryOperator<T> callback; private Checker(T value) { this.value = value; } public static <T> Checker<T> when(T o) { return new Checker<>(o); } public Checker<T> then(UnaryOperator<T> callback) { this.callback = callback; return this; } public T execute() { return this.callback.apply(value); } } 
+2
source

As others suggested, the code can be simplified, but why not make a chain of calls, as well as the final class, so you will have a simple and clean model:

 final class Checker<T> { private final T value; private final UnaryOperator<T> callback; private Checker(T value, UnaryOperator<T> callback) { this.value = value; this.callback = callback; } public static <T> Checker<T> when(T t) { return new Checker<>(t, UnaryOperator.identity()); } public Checker<T> then(UnaryOperator<T> callback) { return new Checker<>(value, t -> callback.apply(this.callback.apply(t))); } public T execute() { return callback.apply(value); } } 

Instead of returning this to then() , this approach returns a completely new Checker instance

+1
source

Source: https://habr.com/ru/post/1273975/


All Articles