2

How can I write the following function using Java 8?

private static final Function<String, Integer> EmpIdToInt = (id) -> {   
    return Integer.valueOf(ACI.generate("emp",id).revealId().intValue());
};

Is there a better way of writing this function in Java 8?

Can anyone help?

Unheilig
  • 16,196
  • 193
  • 68
  • 98
zm10
  • 227
  • 1
  • 5
  • 18

2 Answers2

3

Is there a better way of writing this function in java 8??

you're already using the features of java 8 and yes you can make the code shorter by removing
( ) because there is only one param and removing { } because there is only one statement of execution.

you could simplify it like so:

private static final Function<String, Integer> EmpIdToInt = id -> Integer.valueOf(ACI.generate("emp",id).revealId().intValue());
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
2

Note: I take away private static final for printing page.

IF your revealId is an Integer you can simplified to :

Function<String, Integer> EmpIdToInt = id -> ACI.generate("emp",id).revealId();

OR when revealId is not an Integer, but a int will be auto-boxing to an Integer, so you can remove the Integer.valueOf method call:

Function<String, Integer> EmpIdToInt = id -> ACI.generate("emp",id)
                                                .revealId().intValue();

OR you can using a curry method chaining the functions step by step:

Note: class X is where revealId method is declared, and class Y is where intValue method is declared.

// revealId is an Integer
Function<String, Integer> EmpIdToInt = curry(ACI::generate, "emp")
                                      .andThen(X::revealId);
// revealId is not an Integer
Function<String, Integer> EmpIdToInt = curry(ACI::generate, "emp")
                                      .andThen(X::revealId)
                                      .andThen(Y::intValue);

private static <T, A, R> Function<T, R> curry(BiFunction<A, T, R> it, A arg) {
    return other -> it.apply(arg, other);
}
holi-java
  • 29,655
  • 7
  • 72
  • 83
  • 2
    I think it's safe to assume `Y` is a `Number`. – shmosel Apr 21 '17 at 07:17
  • @shmosel maybe we are right, but I left it to the OP for thinking. – holi-java Apr 21 '17 at 07:19
  • 1
    To be a little pedantic, I think you're demonstrating partial application rather than currying. – shmosel Apr 21 '17 at 07:22
  • @shmosel My mind is to convey the **reusable** and **describility** by using `curry` method to chaining the functions. as you see the `curry(ACI::generate, "emp") .andThen(X::revealId)` can be reused. – holi-java Apr 21 '17 at 07:27
  • 1
    I understand what you're doing, and I like it. I'm just saying currying isn't the accurate term for it. – shmosel Apr 21 '17 at 07:29
  • 4
    I believe it's "partial application". See [here](http://stackoverflow.com/questions/218025/what-is-the-difference-between-currying-and-partial-application) for more detail. – shmosel Apr 21 '17 at 07:31
  • 4
    @shmosel is correct. Simply said, currying means converting the `(a,t)->r` function to the `a->t->r` form. When you apply that (outer) function to a value, you get a function result of the `t -> r` form, which is partial application. However, I usually call such methods `bind`, as the concept of binding parameter argument values to a function, to get a function with less parameters, is immediately understandable for average Java developers without the need to know the FP terms. – Holger Apr 21 '17 at 07:48
  • @shmosel I found it's "partial application" if you starts at `Function`, and it's "currying" when you starts at `ACI::generate` after reading the [link](http://stackoverflow.com/questions/218025/what-is-the-difference-between-currying-and-partial-application), am I right? – holi-java Apr 21 '17 at 07:49
  • 3
  • @Holger yes, you are right, but I want to remove the middle function since java8 have not provided `curry` method in Functional Interface. but I think `bind` method is not better than `curry`. Can you give me some advice, Holger? – holi-java Apr 21 '17 at 07:57
  • 3
    @holi-java: well, in our projects, we also have a need to bind other parameters than the first, e.g. `Function bindSecond(BiFunction func, A arg)`, which have no FP equivalent, so there is no benefit in naming `bindFirst` as `partialApplication` or `curryAndApply`, just because it happens to match that FP concept. Consistency is more important. Note that in real FP languages, you usually don’t have functions of such names, as currying or partial application happens implicitly. The need for specialized methods translating from one interface to another, is a Java specific issue. – Holger Apr 21 '17 at 08:02