I have just begun to use Java 8 and I am wondering if there is a way to write a method that returns a Function?
Right now I have method like below:
Function<Integer, String> getMyFunction() {
return new Function<Integer, String>() {
#Override public String apply(Integer integer) {
return "Hello, world!"
}
}
}
Is there a way to write that more succinctly in Java 8? I was hoping this would work but it does not:
Function<Integer, String> getMyFunction() {
return (it) -> { return "Hello, world: " + it }
}
Get rid of your return statement inside of your function definition:
Function<Integer, String> getMyFunction() {
return (it) -> "Hello, world: " + it;
}
You are missing semi colons:
return (it) -> { return "Hello, world: " + it; };
Although as noted it can be shortened to:
return it -> "Hello, world: " + it;
I would like to point out that it might be more appropriate to use the built-in IntFunction in this case:
IntFunction<String> getMyFunction() {
return it -> "Hello, world: " + it;
}
IntFunction is a part of the standard API for functional interfaces which defines a range of good to have interfaces, mostly related to Java primitives.
You could write it simply like that:
Function<Integer, String> function = n -> "Hello, world " + n;
So, the answer for 99% of the cases has been given by #assylias
You are missing semi colons:
return (it) -> { return "Hello, world: " + it; }; Although as noted it
can be shortened to:
return it -> "Hello, world: " + it;
Yet, I think that it's worth it to add that, if you want to assign your lambda to a variable (to use later).
You can do so by typing:
Callable<YourClass> findIt = () -> returnInstanceOfYourClass();
And then you can easily use it, one example of such a use:
if(dontNeedzToWrap()) {
return findIt.call();
}
return Wrapp.withTransaction(() -> findIt.call());
Given, things can be even made simpler if the Wrapp.withTransaction() method accepts the same kind of Callable's as parameters.
(I use this for JPA atm)
Related
I have a function that returns String.
private String processQuery(String[] args){
//code logic
}
Returned result can either be a answer (Your account detail is $account_detail.) or response (Sorry I cannot understand you?). Depending upon the result, code will do separate things.
What I came up with is to user Either<String, String>.
private Either<String,String> processQuery(String[] args){
//code logic
}
private void reply(String[] args){
//code logic
var either = processQuery(args);
return either.fold((l){
//returned result is answer
},(r){
//returned result is response
});
}
If it returns left then it is answer, if it returns right it is response. But since there is not Either type in java so I tried passing AtomicBoolean around.
What is the better solution for this only using java stl?
One solution is to make the method take two lambda functions that corresponds to a correct and an incorrect answer and then call only the appropriate one
private void processQuery(String[] args, Consumer<String> correct, Consumer<String> incorrect){
if (args.length == 0) {
incorrect.accept("Sorry I cannot understand you?");
return;
}
correct.accept("Your account detail is $account_detail.");
}
which can be called like this
private void reply(String[] args){
processQuery(args, (
reply -> System.out.println("Success!, " + reply)
),
(
reply -> System.out.println("Fail, " + reply)
)
);
}
or create variables for the different functions
Consumer<String> badAnswer = reply -> System.out.println("Fail, " + reply);
Consumer<String> goodAnswer = reply -> System.out.println("Success!, " + reply);
private void reply(String[] args){
processQuery(args, goodAnswer, badAnswer);
}
You can use Pair:
Pair<String, String> pair = Pair.with("Blah", "Blee");
See some example here
A better approach, if your responses actually represent some kind of an error, will be to throw an exception of some kind, and to keep the return value of String to represent a "good" flow.
1/ Working code:
public Student process (int id, name){
Optional<Student> studentOpt = myrepo.findById(id);
studentOpt.isPresent() {
return updateStudent(id, name);
} else {
return createStudent(id, name);
}
2/ I try to change it to 'full lambdas code' (not working):
public Student process (int id, name){
Optional<Student> studentOpt = myrepo.findById(id);
return studentOpt.ifPresentOrElse(student-> return updateStudent(id, name), () -> return createStudent(id, name));
}
1/ should I change it to full lambda? what is the cleanest?
2/ if yes, how ?
Given that your methods updateStudent and createStudent involve some form of side effect and you should generally prefer side effect free lambdas, I don't recommend you use them here. In fact, a simple if-then-else block would be sufficient. However, if you are curious, the equivalent lambda would look like:
return studentOpt
.map(unused -> updateStudent(id, name))
.orElseGet(() -> createStudent(id, name));
Hey if anyone has an idea I would be really thankfull.
I'm in a Java stream and i would like to sort my list that i'll be returning.
I need to sort the list via TradPrefis ( MyObject::getTradPrefix ).
But this would be way too easy. Because i want to sort following the number at the end of TradPrefix exampleTradPrefix_[NUMBER TO SORT]
Exemple : hello_1
test_2
...
still_there_22
Here is a piece of code so you can imagine easier.
public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
return (toReturn.stream()
.map(this::createWsQuestion)
.sorted(comparing(WsQuestion::getTradPrefix.toString().length()))
.collect(Collectors.toCollection(LinkedHashSet::new)));
}
One method would simply be to split getTradPrefix().toString() by _ and parse the rightmost value as an int, and use it to sort the Stream:
public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
return toReturn.stream()
.map(this::createWsQuestion)
.sorted(Comparator.comparingInt(question -> {
String[] args = question.getTradPrefix().toString().split("_");
return Integer.parseInt(args[args.length - 1]);
}))
.collect(Collectors.toCollection(LinkedHashSet::new));
}
If I where you I would simply put a method on the WsQuestion class, let's call it sort order:
public int getSortOrder() {
return Integer.valueOf(tradPrefix.substring(tradPrefix.lastIndexOf("_") + 1));
}
The Integer parse is needed since comparing strings would give "11" < "2" (thanks Holger for pointing this out). The lastIndexOf() makes sure that any number of underscores are allowed in tradPrefix, as long as there is at least one.
Then simply create a comparotor by using Comparator.comparingInt()
public LinkedHashSet<WsQuestion> get(String quizId, String companyId) {
LinkedHashSet<QuizQuestionWithQuestion> toReturn = quizQuestionRepository.findAllQuizQuestionWithQuestionByQuizId(quizId);
return (toReturn.stream()
.map(this::createWsQuestion)
.sorted(comparingInt(WsQuestion::getSortOrder))
.collect(Collectors.toCollection(LinkedHashSet::new)));
}
You can make a small Comparator like this:
private static final Comparator<String> questionComparator = Comparator.comparingInt(s -> {
String[] pieces = s.split("_");
return Integer.parseInt(pieces[pieces.length-1]);
});
Then use it in your sorted().
Having a separate Comparator will make your code more readable too, since you will be separating concerns.
return toReturn.stream()
.map(this::createWsQuestion)
.sorted(questionComparator)
.collect(Collectors.toCollection(LinkedHashSet::new));
I have a rather simple question for you guys. In Java 8 it was introduced the Optional type. I have two objects of type Optional<String> and I want to know which is the more elegant way to concatenate them.
Optional<String> first = Optional.ofNullable(/* Some string */);
Optional<String> second = Optional.ofNullable(/* Some other string */);
Optional<String> result = /* Some fancy function that concats first and second */;
In detail, if one of the two original Optional<String> objects was equal to Optional.empty(), I want the whole concatenation to be empty too.
Please, note that I am not asking how to concatenate the evaluation of two Optionals in Java, but how to concatenate two Strings that are inside some Optional.
Thanks in advance.
The solution I found is the following:
first.flatMap(s -> second.map(s1 -> s + s1));
which can be cleaned using a dedicated method, such the following:
first.flatMap(this::concat);
Optional<String> concat(String s) {
second.map(s1 -> s + s1);
}
However, I think that something better can be found.
If we want to generalize to a list or an array of Optional<String>, then we can use something similar to the following.
Optional<String> result =
Stream.of(Optional.of("value1"), Optional.<String>empty())
.reduce(Optional.of(""), this::concat);
// Where the following method id used
Optional<String> concat(Optional<String> first, Optional<String> second) {
return first.flatMap(s -> second.map(s1 -> s + s1));
}
Note that in order to compile the above code, we have to manually bind the type variable of Optional.empty() to String.
You can stream the Optionals and reduce them with a concat.
Optional<String> first = Optional.of("foo");
Optional<String> second = Optional.of("bar");
Optional<String> result = Stream.of(first, second).flatMap(Optional::stream).reduce(String::concat);
If you are using Java 8 replace the flatMap operator with filter(Optional::isPresent).map(Optional::get).
Consider also to use the joining collectors: this will return String, not an Optional<String>.
You can use something like :
Optional<String> result;
result = first.isPresent() && second.isPresent() ? Optional.of(first.get() + second.get()) : Optional.empty();
Any solution that requires a flexible number of optional strings must explicitly use a StringBuilder, rather than rely on the compiler to generate one for you.
String concatThem(Stream<String> stringsin) {
StringBuilder sb = new StringBuilder();
stringsin.forEach(s -> sb.append(s));
return sb.toString();
}
If you have a Stream<Optional<String>> then it becomes:
String concatThem(Stream<Optional<String>> stringsin) {
StringBuilder sb = new StringBuilder();
stringsin.filter(Optional::isPresent).forEach(s -> sb.append(s.get()));
return sb.toString();
}
Otherwise if you have N optional strings you end-up with a heavy cycle of creation and destruction of N-1 single-use StringBuilder objects (generated at compile time) and N-1 strings.
Edit: I had misread, so here's how to do it if any of them is missing to clear it all:
String concatThem(Stream<Optional<String>> stringsin) {
StringBuilder sb = new StringBuilder();
try {
stringsin.forEach(s -> {
if (!s.isPresent()) throw new IllegalArgumentException();
sb.append(s.get())
});
}
catch(IllegalArgumentException ex) {
sb.setLength(0);
}
return sb.toString();
}
This is of course if you insist on using the new API that's light on the syntax and heavy on the execution.
#SafeVarargs
public final Optional<String> concat(Optional<String>... inputs)
{
return Arrays.stream(inputs)
.reduce((left, right) -> left.flatMap(leftValue -> right.map(rightValue -> leftValue + rightValue)))
.get();
}
#Test
public void shouldReturnEmptyIfFirstItemIsEmpty()
{
assertThat(concat(Optional.empty(), Optional.of("B")), is(Optional.empty()));
}
#Test
public void shouldReturnEmptyIfSecondItemIsEmpty()
{
assertThat(concat(Optional.of("A"), Optional.empty()), is(Optional.empty()));
}
#Test
public void shouldConcatIfNoItemIsEmpty()
{
assertThat(concat(Optional.of("A"), Optional.of("B")), is(Optional.of("AB")));
}
Here's an implementation using the reduce method on Stream.
Here's another pretty way:
#Value.Immutable
public abstract class Person {
public Optional<String> firstName() {
return Optional.of("John");
}
public Optional<String> lastName() {
return Optional.of("Smith");
}
public Optional<String> location() {
return Optional.of("Paris");
}
#Value.Lazy
public String concat() {
return Stream.of(firstName(), lastName(), location())
.filter(Optional::isPresent)
.map(Optional::get)
.filter(StringUtils::isNotBlank)
.reduce((first, second) -> first + '.' + second)
.orElse("");
}
}
Note that, as mentioned in other comments, the concat() method performs string concatenations without using a StringBuilder (which might not be performant if you call the method a lot of times). To fix this, in the above example we're using Immutables' [1] #Value.Lazy, which makes sure the concat() method is called once and the result is cached for further calls. Works great!
[1] https://immutables.github.io
I would like to create a class in Java 8 which is able to recursively create an object which has a method that takes a function parameter based on the parameters I added.
For example, I would like to be able to do this:
new X().param(23).param("some String").param(someObject)
.apply((Integer a) -> (String b) -> (Object c) -> f(a,b,c))
The apply method would then apply the collected parameters to the given function.
I feel this should be possible without reflection while maintaing type-safety, but I can't quite figure out how. A solution in Scala is also welcome, if I can translate it to Java 8. If it's not possible, I'll also accept an answer that explains why.
What I have so far is essentially this:
class ParamCmd<A,X> {
final A param;
public ParamCmd(A param) {
this.param = param;
}
public<B> ParamCmd<B, Function<A,X>> param(B b) {
return new ParamCmd<>(b);
}
public void apply(Function<A,X> f) {
// this part is unclear to me
}
public static void main(String[] args) {
new ParamCmd<Integer,String>(0).param("oops").param(new Object())
// the constructed function parameters are reversed relative to declaration
.apply((Object c) -> (String b) -> (Integer a) ->
"args were " + a + " " + b + " " + c
);
}
}
As noted in the code comments, my problems are keeping the function parameters in the order of the calls of param(), and actually applying the parameters.
For an unlimited amount of parameters, the only solution I could think of is with Heterogeneous Lists in Scala.
It is probably isn't feasible in Java as there is type level computation going on with path-dependant types.
Using Heterogeneous Lists and Path-Dependant types:
import scala.language.higherKinds
object Main extends App {
val builder1 = HCons(23, HCons("Hello", HNil))
val builder2 = HCons(42L, builder1)
val res1:String = builder1.apply(i => s => i + s)
val res2:String = builder2.apply(l => i => s => (i+l) + s)
println(res1) // 23Hello
println(res2) // 65Hello
}
sealed trait HList {
type F[Res]
def apply[Res]: F[Res] => Res
}
case class HCons[Head, HTail <: HList](head: Head, tail: HTail) extends HList {
type F[Res] = Head => (tail.type)#F[Res]
def apply[Res]: F[Res] => Res = f => tail.apply(f(head))
}
case object HNil extends HList {
type F[Res] = Res
def apply[Res]: F[Res] => Res = identity
}
This code prints:
23Hello
65Hello
The second, more limited way of doing this, but which might work with Java, is to create multiple classes for each function length, which returns the next sized function length class wrapping the value, up to some maximal length - See the Applicative Builder in Scalaz: "Scalaz Applicative Builder"
This doesn't answer your question. However, maybe it helps someone to find a solution, or to explain why it isn't possible in Java and/or Scala.
It can be done in C++, with an arbitrary number of parameters, and without losing type-safety. The call-side look as follows. Unfortunately, the lambda syntax in C++ is quite verbose.
bar{}.param(23).param("some String").param(4.2).apply(
[](int i) {
return [=](std::string s) {
return [=](double d) {
std::cout << i << ' ' << s << ' ' << d << '\n';
};
};
});
Following is the definition of foo and bar. The implementation is straight-forward. However, I doubt that it is possible to build something like this in Java, because the way type parameters work in Java. Generics in Java can only be used to avoid type casts, and that's not enough for this use case.
template <typename Param, typename Tail>
struct foo {
Param _param;
Tail _tail;
template <typename P>
auto param(P p) {
return foo<P, foo>{p, *this};
}
template <typename Function>
auto apply(Function function) {
return _tail.apply(function)(_param);
}
};
struct bar {
template <typename P>
auto param(P p) {
return foo<P, bar>{p, *this};
}
template <typename Function>
auto apply(Function function) {
return function;
}
};
Sorry I just could give some leads in Scala:
Perhaps it would help to have a look at http://www.scala-lang.org/api/2.10.4/index.html#scala.Function$
.apply((Integer a) -> (String b) -> (Object c) -> f(a,b,c))
pretty much looks like Function.uncurried
param(23).param("some String").param(someObject)
could be implemented using a list for an accumulator if you don't care for Type safety. If you want to keep the Types you could use the HList out of Shapeless https://github.com/milessabin/shapeless which comes with a handy tuppled method.
Implementation of param():
import shapeless._
import HList._
import syntax.std.traversable._
class Method(val l : HList = HNil) {
def param(p: Any) = new Method( p :: l )
}
Example
scala> val m = new Method().param(1).param("test")
m: Method = Method#1130ad00
scala> m.l
res8: shapeless.HList = test :: 1 :: HNil