Java 8 vs. Scala (a) Lambda expressions

By Jacob Mcdonald,2015-05-12 00:27
26 views 0
Java 8 vs. Scala (a) Lambda expressions

    Java 8 vs. Scala (a) : Lambda expressions

    this article ?the author by comparing the Java and Scala, analyses the

    performance and the expression differences, and in-depth discussions about the Stream API, the difference between theOneAPMEngineers in translation.

    8 years waiting, Java finally add the higher-order functions this feature.I like Java, but had to admit that, compared with other modern programming language, Java syntax is very long.Yet by Java8, directly using the lambda expressions can write both readable and concise code (and sometimes even more readable than traditional methods).

    Java 8 were published on March 3, 2014, but I recently have a chance of contact.Because I also familiar with Scala, so the result is contrast Java and Scala 8 in expressiveness and performance differences, more will be built around the Stream API, it will also introduce how to use the Stream API to set operation.

    The article is so long, so the following three parts described in detail.

    Part 1. Lambda expressions

    Part 2. Stream API vs Scala collection API

    Part 3. Trust no one, bench everything (quoted fromsbt-jmh)

    First, we come to know Java 8 lambda expressions, although don't know even if the expression is alternative, they are called lambda expressions.Here full statement can be used in place of the expression, and then said Java 8 also supports lambda statement.Programming languages will function as a first class citizen, function can be as a parameter or return value, because it is regarded as object.Java is a static strongly typed language.So, function must have a type, so it is also an interface.

    Lambda functions, on the other hand, is a class implements the function interface.Don't need to create this function in the class, the compiler can achieve directly.Unfortunately, the Java interface without advanced Scala type.If you want to declare a lambda expressions, you must specify the target type.In fact, as Java must maintain backwards compatibility, which is understandable, but for now the Java done very well.For example, Thread. The stop () in JDK version 1.0 was released, has been out of date for more than ten years, but even to this day is still in use.So, don't cry because it is the grammar of the language XYZ (or method) is better, just expect Java radically change the syntax structure.

    So, the Java language designers ideas, 8 make function interface!Function interfaces is only an abstract method.You know, most of the callback interface has been meet this requirement.Therefore, we can not do any modification to reuse these interfaces.@FunctionalInterfaceIs says it has annotated interface is the annotation of the interface function.This annotation is optional, unless there is a check request, otherwise don't have to.

    Please remember, lambda expressions must be defined types, and the type must be only an abstract method.

    //Before Java 8

    Runnable r = new Runnable(){

     public void run(){

     System.out.println(“This should be run in another thread”);



    //Java 8

    Runnable r = () -> System.out.println(“This should be run in another thread”);

    If a function has one or more arguments and returns a value?In order to solve this problem, Java 8 provides a series of generic function interface, in Java. Util. Function bag.

    //Java 8

    Function<String, Integer> parseInt = (String s) -> Integer.parseInt(s);

    The parameter type can be inferred from the function, likeJava 7 of the diamond operator, so can be omitted.We can rewrite this function, as shown below: //Java 8

    Function<String, Integer> parseInt = s -> Integer.parseInt(s);

    If a function has two parameters?Don't have to worry about, Java BiFunction of 8.

    //Java 8

BiFunction<Integer, Integer, Integer> multiplier =

     (i1, i2) -> i1 * i2; //you can’t omit parenthesis here!

    If a function interface has three parameters?TriFunction?Language designers stop BiFunction.Otherwise, could have really TriFunction, quadfunction, pentfunction etc.Explain that the author is named after the function USES the IUPAC rules.You can then define TriFunction as follows.

    //Java 8


    interface TriFunction<A, B, C, R> {

     public R apply(A a, B b, C c);


    Then import interface, and use it as a lambda expression type used. //Java 8

    TriFunction<Integer, Integer, Integer, Integer> sumOfThree

     = (i1, i2, i3) -> i1 + i2 + i3;

    Here you should be able to understand why designers stop BiFunction.

    If not understand, look at PentFunction, suppose that we have defined the PentFunction elsewhere.

    //Java 8

    PentFunction<Integer, Integer, Integer, Integer, Integer, Integer>

     sumOfFive = (i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5;

    Do you know how long Ennfunction?(9) in Latin, enn said you must declare 10 types (nine parameters, before the last one is the return type), probably only type the whole line.Then declare a type is it necessary?The answer is yes.(this is why the author thinks that the Scala type interface is better than the Java)

    Scala also has its type of lambda expressions.In Scala, you can create a 22 parameters lambda expressions, means that Scala has the type of each function (Function22 Function0, once Function1,...).Function types in Scala function is a Trait, traits like abstract classes in Java, but can be used as mixed type.If you need more than 22 parameters, it is about function of the design you have any question.Must want to consider the type of the passed a set of parameters.In this, the author will go into details about Lambda expressions.

    Take a look at the Scala other content.Scala is also similar to Java static strongly-typed language, but it is functional languages.Therefore, it can well fusion of object-oriented and functional programming.Because Scala and Java methods, adopted by the given Runnable instances of Scala is not allowed here.Scala has its own methods to solve the problem, so the next will be discussed in detail. //Scala

    Future(println{“This should be run in another thread”})

    With the following code equivalent Java8.

    //Java 8

    //assume that you have instantiated ExecutorService beforehand.

Runnable r = () -> System.out.println(“This should be run in another thread”);


    If you want to declare a lambda expressions, can need not like Java, an explicit type declaration.

    //Java 8

    Function<String, Integer> parseInt = s -> Integer.parseInt(s);


    val parseInt = (s: String) => s.toInt


    val parseInt:String => Int = s => s.toInt


    val parseInt:Function1[String, Int] = s => s.toInt

    So, there are a variety of ways to declare the type in Scala.Let the compiler to perform.So PentFunction?

    //Java 8

    PentFunction<Integer, Integer, Integer, Integer, Integer, Integer> sumOfFive

     = (i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5;


    val sumOfFive = (i1: Int, i2: Int, i3: Int, i4: Int, i5: Int) =>

     i1 + i2 + i3 + i4 + i5;

    Scala shorter, because they do not need to declare the interface type, and integer types in Scala is int.Short does not always mean better.Scala's approach is better, not because of short, but because more readable.Types of context in the

parameter list, can quickly find out the parameter types.If you are not sure, can refer

    to the following code.

    //Java 8

    PentFunction<String, Integer, Double, Boolean, String, String>

     sumOfFive = (i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5; //Scala

    val sumOfFive = (i1: String, i2: Int, i3: Double, i4: Boolean, i5: String) => i1 + i2 + i3 + i4 + i5;

    In Scala, you can clearly tell i3 type is Double, but in Java 8, also need to figure

    out what it is type.You might argue that Java can also, but in this situation: //Java 8

    PentFunction<Integer, String, Integer, Double, Boolean, String> sumOfFive

     = (Integer i1, String i2, Integer i3, Double i4, Boolean i5)

     -> i1 + i2 + i3 + i4 + i5;

    You must repeat down over and over again.

    In addition, Java8 PentFunction no, need to define your own. //Java 8


    interface PentFunction<A, B, C, D, E, R> {

     public R apply(A a, B b, C c, D d, E e);


    Does that mean the Scala is better?Is in some ways.But there are also many places Scala than Java.So it's hard to say which one is better, I was compared between the two, because Scala is a functional language, and Java 8 support some function characteristics, so need to find function language to compare.Because Scala can run on the JVM, to compare with it better.You might use function, Scala has more concise syntax and method, it is because it is the function of language, and Java designers before without breaking on the basis of development design, there will be more clearly.

    Although Java compared with lambda expressions in syntax has certain limitations, but Java8 also introduced some of the cool feature.For example, the use of the characteristics of the method reference by reusing existing methods make writing more concise lambda expressions.More concise???

    //Java 8

    Function<String, Integer> parseInt = s -> Integer.parseInt(s);

    Can use the method reference to rewrite the function, as shown below //Java 8

    Function<String, Integer> parseInt = Integer::parseInt;

    Can also use method reference by instance methods.Then in the second part of the Stream in the API is pointed out that the availability of this method.

    The structure of the method reference rules

    1.(args) -> ClassName.staticMethod(args);

    Can rewrite the ClassName: something like this: staticMethod; Function<Integer, String> intToStr = String::valueOf;

    2.(instance, args) -> instance.instanceMethod(args);

    Can rewrite the ClassName: something like this: instanceMethod; BiFunction<String,String, Integer> indexOf = String::indexOf;

    3.(args) -> expression.instanceMethod(args);

    Can rewrite the expression: something like this: instanceMethod; Function<String, Integer>indexOf = new String()::indexOf;

    Did you notice the rule 2 is a bit strange?Have a little confusion?Although indexOf function need only one parameter, but BiFunction of target type is need two parameters.In fact, this usage is usually used in Stream API, when see the type name to be meaningful.;

    // The signature of map() function can be derived as

    // <String> Stream<String> map(Function<? super Pet, ? extends String> mapper)

    From the rule 3, you may wonder whether replace new String with lambda expressions ()?

    You can use this method to construct a object

Supplier<String> str =String::new;

    You can do this?

    Function<Supplier<String>,Integer> indexOf = (String::new)::indexOf;

    Can't.It cannot be compiled, The compiler will be prompted to "The target type of this expression must be a functional interface".Error message is easy to cause misunderstanding, and seem to be a Java 8 through generic parameter type does not support the interface.Even with a Functionalinterface instance (" STR ") as mentioned earlier, also there will be another mistake "The type: Supplier < String > does not define indexOf: Supplier < String >) that is applicable here".String: : the functions of the new interface is: Supplier < String >, and it is only method named the get ().IndexOf is a String object instance methods.Therefore, you must rewrite this code, as shown below.


    Function<String, Integer> indexOf = ((Supplier<String>)String::new).get()::indexOf;

    Java 8 supports currying, partial function)?

    The method is feasible, but you can't use references.You can be thought of as a partial function, but it returns the function rather than the result.Then will introduce using currying simple example, but this example might not work.Before we passed to the function, we usually parameters processing.But no matter how, first take a look at how to implement partial function using lambda expressions.If you need to use two ints function currying implementation.

Report this document

For any questions or suggestions please email