Java Functional Programming (eight): string and method References _java

Source: Internet
Author: User
Tags instance method

Chapter III strings, comparators and filters

Some of the methods introduced by JDK are useful for writing code that is functional style. Some of the classes and interfaces in the JDK library we've been very familiar with, like string, we have to proactively look for opportunities to use these new methods in order to get rid of the old style we used to be. Again, when we need to use an anonymous inner class with only one method, we can now replace it with a lambda expression, not as tedious as it used to be.

In this chapter we use lambda expressions and method references to traverse strings, implement comparator interfaces, view files in directories, and monitor changes to files and directories. Some of the methods described in the previous chapter will continue to appear here to help us accomplish these tasks better. The new technologies you've learned help to make tedious and cumbersome code simple, not only fast but also easy to maintain.

Traversal string

The chars () method is a new method in the String class, which is part of the Charsequence interface. It is a useful tool to quickly traverse a string's character sequence. With this internal iterator, we can easily manipulate individual characters in the string. First, use it to process a string to try. Here are some ways to use the method reference.

Copy Code code as follows:

Final String str = "w00t";
Str.chars ()
. ForEach (ch-> System.out.println (ch));

The chars () method returns a Stream object that we can iterate over with its internal iterator, foreach (). In the iterator, we can directly access the characters in the string. The following is the result of traversing the string and printing each character's output.
Copy Code code as follows:

119
48
48
116

This is not the result we want. What we want to see is the letter, but the output is the number. This is because the chars () method returns an integral stream instead of a character type. Let's take a look at the API and then optimize the results of the output.

In the preceding code we created a lambda expression as an entry for the Foreach method. It simply passes the argument to a println () method. Since this is a common operation, we can use the Java compiler to simplify this code. As in the 25-page usage reference, replace it with a method reference, and let the compiler do the parameter routing for us.

We have seen how to create a method reference for an instance method. For example, the Name.touppercase () method, the method reference is string::touppercase. In the following example, we call an instance method of the static reference System.out. Method refers to the left of the two colon, which can be a class name or an expression. With this flexibility, we can easily create a reference to a println () method, just like the following.

Copy Code code as follows:

Str.chars ()
. ForEach (System.out::p rintln);

As you can see, the Java compiler is smart enough to complete the routing of parameters. Recall that lambda expressions and method references can only occur where the function interface is now received, and the Java compiler generates a corresponding method in that place (the compiler generates a function-interface implementation with only one method). The method we used previously referred to String::touppercase, passed to the parameters of the build method, and finally became the target object of this method invocation, like this: Parameter.touppercase (). This is because the method reference is based on the class name (String). The method reference in the example above is based on an expression that is an instance of PrintStream, referenced by System.out. Because the object already has the method call, the Java compiler determines to use the arguments in the build method as the parameter of this println method: System.out.println (name).

In fact, the main two scenarios are also passed a method reference, one is to take the object of the traversal, of course, the target object of the method call, such as Name.touppercase, the other is as a method call parameters, such as SYSTEM.OUT.PRINTLN (name).

The code is much simpler after using the method reference, but we have to go into the details of how it works. Once we are familiar with the method reference, we can figure out the parameter routing.

Although the code in this example is concise enough, the output is still unsatisfactory. What we want to see is the letter results but the numbers appear. To solve this problem, let's write a method to output an int as a letter.

Copy Code code as follows:

private static void Printchar (int achar) {
System.out.println ((char) (Achar));
}

The use of method references makes it easy to optimize output results.
Copy Code code as follows:

Str.chars ()
. ForEach (iteratestring::p Rintchar);

Now, although chars () returns an int, it doesn't matter, and when it needs to be printed, we convert it to a character. This time the output is finally the letter.
Copy Code code as follows:

W
0
0
T

If we want to deal with characters instead of int from the beginning, you can convert an int to a character directly after chars is called:
Copy Code code as follows:

Str.chars ()
. maptoobj (Ch-> character.valueof ((char) ch))
. ForEach (System.out::p rintln);

Here we use an internal iterator for the stream returned by chars (), and of course it can be used in more than one way. After getting the stream object, it's those methods that we use, such as map (), filter (), reduce (), and so on. We can use the filter () method to filter out those characters that are numbers:
Copy Code code as follows:

Str.chars ()
. Filter (ch-> character.isdigit (CH))
. ForEach (ch-> printchar (ch));

So we can only see the numbers when we output:
Copy Code code as follows:

0
0

Similarly, in addition to passing lambda expressions to the filter () and foreach () methods, we can also use method references.
Copy Code code as follows:

Str.chars ()
. Filter (Character::isdigit)
. ForEach (iteratestring::p Rintchar);

The method references here omit the extra parameter routing. In this case, we also see a different use of references to the previous two methods. The first time we refer to an instance method, the second is a method on a static reference (System.out). This time it is a reference to a static method--the method reference has been silently paid.

The references to instance methods and static methods all look the same: String::touppercase and character::isdigit, for example. The compiler determines whether the method is an instance method or a static method to determine how to route the parameters. If it is an instance method, it will use the arguments of the build method as the target object of the method invocation, such as Parameter,touppercase ();(Of course there are exceptions, such as the target object of the method invocation has been specified, like System::out.println (). In addition, if it is a static method, the incoming parameter of the generated method will be used as the parameter of the referenced method, such as character.isdigit (parameter). 152-page Appendix 2, with detailed method references and syntax instructions.

Although the method reference is convenient to use, there is one problem--the two semantics caused by the method naming conflict. If the matching method has both instance method and static method, the compiler will make an error due to the ambiguous method. So to write, double::tostring, we actually want to convert a Double type to a string, but the compiler doesn't know whether the instance method that calls public string toString () is good or calls the public static String toString (double) method, because all two methods are double. If you're in a situation like this, don't lose heart, just use a lambda expression to do it.

Once we have adapted to functional programming, we can switch back and forth between lambda expressions and method references.

In this section, we use a new method in Java 8 to traverse a string. Let's look at what's improved with the comparator interface.

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.