Java8-lambda expression (3)

Source: Internet
Author: User

A functional interface definition and only one abstract method is defined. A functional interface is useful because the signature of an abstract method can describe the signature of a lambda expression. The signature of an abstract method of a functional interface is called a function descriptor. So in order to apply different lambda expressions, you need a set of functional interfaces that describe common function descriptors. There are several functional interfaces in the Java API, such as comparable, Runnable, and callable.

1. Functional interfaces in the system

Several new functional interfaces are introduced in the Java.util.function package in Java8, such as predicate, Consumer, function, and so on.

(1). predicate

The Java.util.function.preicate<t> interface defines an abstract method named Test that receives a generic T object and returns a Boolean type. This is exactly what you created earlier, and now you can use it directly. You can use this excuse when you need to represent a Boolean expression that has a design type of T. For example, you can define a lambda expression that accepts a string object.

1  Public classDemo3 {2      Public Static voidMain (string[] args) {3list<string> stringlist = Arrays.aslist ("1","2","","a");4List<string> list = Filter (Stringlist, (String s)!s.isempty ());5          for(Stringstring: List) {6System. out. println (string);7         }8     }9 Ten      Public Static<T> list<t> Filter (list<t> List, predicate<t>p) { Onelist<t> result =NewArraylist<>(); A          for(T t:list) { -             if(P.test (t)) { - Result.add (t); the             } -         } -         returnresult; -     } +}

(2). Consumer

Java.util.function.consumer<t> defines an abstract method called accept, which receives the object of the generic T and does not return (void). You can use this interface if you need to access an object of type T and perform some action on it. For example, you can use it to create a foreach method, receive a list of integers, and perform actions on each of these elements. In the following code, you can use this foreach method and work with lambda to print all the elements in the list.

1  Public classDemo3 {2      Public Static voidMain (string[] args) {3list<string> stringlist = Arrays.aslist ("1","2","","a");4List<string> list = Filter (Stringlist, (String s)!s.isempty ());5ForEach (list, (String s), System. out. println (s));6     }7 8      Public Static<T> list<t> Filter (list<t> List, predicate<t>p) {9list<t> result =NewArraylist<>();Ten          for(T t:list) { One             if(P.test (t)) { A Result.add (t); -             } -         } the         returnresult; -     } -      Public Static<T>voidForEach (list<t> List, consumer<t>c) { -          for(T t:list) { + c.accept (t); -         } +     } A}

(3). Function

Java.uil.functin.function<t, the R> interface defines a method called apply, which receives an object of a generic T and returns an object of the generic R. If you need to define a lambda and map the information of the input object to the output, you can use this interface (such as extracting the weight of the Apple, the torch string being mapped to its length). In the following code, we show you how to use it to create a map method that maps a string list to an integer collection that contains each string length.

 Public classDemo4 { Public Static voidMain (string[] args) {List<Integer> list = map (Arrays.aslist ("Lambda","Java","C + +"), (String s),s.length ());  for(Integer i:list) {System. out. println (i); }    }     Public Static<t, r> list<r> map (list<t> List, Function <t, r>f) {List<R> result =NewArraylist<>();  for(t t:list) {Result.add (f.apply (t)); }        returnresult; }}

2. Original type of Special

We have introduced three generic functional interfaces:predicate<t>, consumer<t>, and Function<t, r>. There are also functional interfaces designed specifically for some classes.

Recap: Java types are either reference types (such as Byte, Integer, Object, list, and so on), or primitive types (such as int, double, Byte, char). But generics, such as T in consumer<t>, can only be bound to reference types. This is caused by the way the generics are implemented internally. Therefore, in Java there is a mechanism to convert the original type to the corresponding reference type. This mechanism is called boxing (boxing). Instead, the reference type is converted to the corresponding primitive type, called the unboxing (unboxing). Java also has an automatic boxing mechanism to help programmers perform this task: both boxing and unpacking are done automatically. For example, this is why the following code is valid (an int type is boxed as an integer):

1         New Arraylist<>(); 2          for (int0; i++) {3            list.add (i); 4         }

But this has to pay a price in terms of performance. The boxed value is essentially wrapping the original type and storing it in the heap. Therefore, the boxed value requires more memory, and additional memory searches are required to obtain the original value of the package.

Java8 brings a special version of the functional interface that we have previously described so that the input and output are primitive types and avoid automatic boxing operations. For example, the following code uses Intpredicate to avoid boxing a value of 1000, but if you use predicate<integer>, the parameter 1000 is boxed into an Integer object:

1         Intpredicate evennumbers = (int20; 2         Evennumbers.test (+); 3         4         2 0 ; 5         Oddnumbers.test (+);

In general, the names of functional interfaces for specialized input parameter types are prefixed with the corresponding raw data type prefixes, such as Doublepredicate, Intconsumer, Longbinaryoperator, Intfunction, and so on. The function interface also has variant:tointfunction<t>, inttodoublefunction, and so on for the output type parameter type.

The following table summarizes the most common functional interfaces and their function descriptors available in the Java API, and the right side of the table represents the parameter types. Please remember this is just a starting point. If necessary, you can design one yourself. Remember, the expression (T, U)-R shows how to think about a function descriptor, where it represents a function that has two parameters, T and U, and a return type of R.

Common functional Interfaces in Java8

Function-Type interface Function descriptor Original Type Special Exchange
Predicate<t> Boolean, T Intpredicate, Longpredicate, doublepredicate
Consumer<t> T->void Intconsumer, Longconsumer,doubleconsumer
Function<t,r> T-R

Intfunction<r>,inttodoublefunction,

Inttolongfunction,longfunction<r>,

Longtodoublefunction,longtointfunction,

Doublefunction<r>,tointfunction<t>,

Todoublefunction<t>,tolongfunction<t>

Supplier<t> ()->t

Booleansupplier,intsupplier, Longsupplier,

Doublesupplier

Unaryoperator<t> T-t

Intunaryoperator, Longunaryoperator,

Doubleunaryoperator

Binaryoperator<t> T (t, T)

Intbinaryoperator,longbinaryoperator

Doublebinaryoperator

Bipredicate<l, r> (L, R)->boolean
Biconsumer<t, u> void (T, U)

Objintconsumer<t>, Objlongconsumer<t>,

Objdoubleconsumer<t>

Bifunction<t, U, r> R (T, U)

Tointbifunction<t, U>, Tolongbifunction<t, u>

Todoublebifunction<t, u>

To summarize the discussion of functional interfaces and lambda, the following table summarizes some examples of use cases, lambda, and functional interfaces that can be used

Examples of lambda and functional interfaces

Use case Examples of Lambda The corresponding function-type interface
Boolean expression (list<string> List), List.isEmpty () Predicate<list<string>>
Creating objects () New Apple () Supplier (Apple)
Consume an Object (Apple a), System.out.println (A.getweight ()) Consumer<apple>
Select/Extract from Object (String s), S.length ()

Function<string, integer> or

Tointfunction<string>

Merge two values (int a, int b), A * b Inbinaryoperator
Comparison of two objects (Apple A1, Apple A2), A1.compareto (A2)

Comparator<apple> or

Bifunction<apple, Apple, integer> or

Tointbifunction<apple, apple>

3. Anomalies, LAMBDA, and functional interfaces What's going on?

Note that any functional interface is not allowed to throw a checked exception (checked exception). If you need a lambda expression to throw an exception, there are two ways to define a functional interface of your own, declare an exception to be checked, or wrap a lambda in a try/catch block.

For example, before we defined a functional interface bufferedreaderprocessor, it is the reality that declares a ioexception:

1  Public Interface bufferedreaderprocessor {2    String process (BufferedReader b) throws IOException; 3 }

But you may be using an API that receives a functional interface, such as Function<t, R>, and there is no way to create one yourself. In this case, you can explicitly catch an exception that is being checked:

1         Function<bufferedreader, string> f = (BufferedReader B), {2             try  { 3                 return b.readline (); 4             Catch (IOException e) {5                 Throw New runtimeexception (); 6             }7         };

Java8-lambda expression (3)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.