20145326 "Java program Design" The 7th Week study summary textbook Learning content Summary
12th Chapter
First, understanding the lambda syntax
1.LAMBDA Syntax overview
Arrays's sort () method can be used to sort, but you have to tell it what the order of two elements compare, Sort () specifies that you have to manipulate java.util.Comparator to illustrate the matter, and we can use Bylength () to make the sorting intent clearer, just as long as the anonymous class is operating comparator, there is too much repetition, and if you use JDK8, you can work with Lambda feature to remove duplicate information. Lambda is not just an anonymous class of syntax honey, but now focuses on its repetitive removal and readability improvements. What would you do if you had a need to sort by string lengths in many places? If it's the same method, I'm going to use a byname local variable, and if it's shared among multiple methods within a class, use a byname data member! Since the instance to be referenced by byname has no state problem, it is appropriate to declare static, and if it is to be shared among multiple classes, it is set to public static. JDK8 provides a method reference feature, while introducing Lambda in Java while maintaining compatibility with existing APIs is one of the main considerations, the method reference features play an important role in reusing existing APIs, and reusing existing operations avoids writing lambda expressions everywhere, not only that, It also makes the program code clearer.
2.Lambda Expressions and Function interfaces
A lambda expression can be split into two parts, the right side of the equals sign is a lambda expression, and the left side of the equals sign is the target type of the lambda expression. Chunks can be made up of several descriptive sentences, but it is not recommended to use them at all, but it is better to use a simple expression when using lambda expressions, and if your operations are more complex, consider other ways such as method references. In a lambda expression, you must write down parentheses, even if you do not use any parameters. In the case of a lambda expression only, the type of the parameter must be written out, and if there is a target type, you can not write out the parameter type of the lambda expression if the compiler can infer the type. The lambda expression itself is neutral and does not represent any type of instance. The same lambda expression can be used to represent object operations of different target types. JDK8 Lambda does not import a new type as a type of lambda expression, but instead defines the function interface for the existing interface syntax, as the target type of the lambda expression, the function interface is the interface, but requires only a single abstract method, Many existing interfaces are such interfaces, such as runnable, callable, comparator in the standard API, and only one method is defined. In JDK8, however, it is sometimes difficult to discern directly whether an interface is a function interface, because JDK8 evolves interface syntax, allows for default methods, and interfaces may inherit other interfaces, redefine certain methods, and so on, which makes it more difficult to confirm that the interface is a function interface. If the interface uses @functionalinterface to label and is not itself a function interface, a compilation error is thrown.
3.Lambda encounters this and final
Operation Result:
In the example above, because the Hello class encloses the lambda expression, the lambda expression can refer to the name in the class category, and the ToString () of the Hello class is defined in the example to return "hello,world! "String, which is then displayed two times when executed" hello,world! ”。 Before JDK8 occurs, if you want to access local variables in an anonymous inner class, the local variable must be final, or a compilation error will occur, whereas in JDK8, if the variable itself is equivalent to the final local variable, that is, if the variable does not have a re-specified action in the anonymous class, You don't have to add the final keyword. Attention! In a lambda expression, you cannot change the value of a captured local variable, JDK8 deliberately prevents you from modifying the value of a local variable in a lambda, because one of the reasons JDK8 wants to use lambda is to further support parallel programming, a modifiable local variable in a lambda expression, It is also common to say that in parallel programs, you might have to deal with synchronization locking issues, JDK8 to prevent you from modifying local variable values in your lambda to avoid such problems.
4. Method and constructor reference
Lambda expressions are really handy when you're temporarily trying to define an operation for a function interface, but sometimes you'll find that some of the static methods themselves operate in the same way as the lambda expression you define yourself, JDK8. Lambda expressions are just one way to define function interface operations, and in addition, as long as the method signature of a static method is the same as the return value definition, a static method can be used to define the function interface operation. Such features are called method references in JDK8 and can improve readability. A function interface operation can also refer to a non-static method defined on a class, and the function interface attempts to use the first parameter as the method receiver, and the subsequent parameter is sequentially used as the parameter of the referenced non-static method.
5. Interface Default method
JDK8 wants these APIs to have an object-oriented programming style that is smoother when writing program code. JDK8 's strategy is to directly evolve the interface syntax, which, in JDK8, can be added to the default action, or called the default method, in the interface definition, and the default method makes the interface look like an abstract class with abstract methods, but the difference is that data members cannot be used in the default method. Because the interface itself cannot define a data member, it is a process in which the default method cannot have a direct change state. JDK8 before the interface has a default method is a reason, because the operation interface is generalized multiple inheritance, the interface does not operate, the class and interface inheritance when the method source in the judgment will be simple, the interface in the JDK8 allows the default operation, the introduction of powerful power, but also introduced more complexity. Just as a subclass can inherit a parent class, an interface can be inherited, an abstract method or default method is inherited, and an abstract method that is defined by the parent interface is redefined in a sub-interface, usually for documentation, which is often seen in the past (practice), Once the default method can be defined in the interface, there are a number of things to be aware of when the operation version is identified, if there is a default method in the parent interface, the sub-interface again declares the same method as the parent interface default method name, but does not write default, that is, there is no method operation, In that case, the method in the Subinterface directly redefined the default method action in the parent class as an abstract method, and if there are two parent interfaces that define the default method named by the same method, a conflict is raised. The workaround is to explicitly redefine the method, whether it is redefined as an abstraction or a default method. If a subclass inherits the parent class to manipulate an interface at the same time, and the method in the parent class has the same method name as the default method in the interface, the method definition of the parent class is used. In simple terms, the definition in a class takes precedence over the definition in the interface, and if there is a redefinition, it is redefined as the primary and, if necessary, which default method is used when using the interface with super.
Second, functional and stream API
1. Use optional instead of NULL
The most fundamental problem of NULL is the ambiguity of semantics, literally, NULL can be "not exist", "no", "no", "empty" meaning, so in the application, always someone to touch the ambiguous, but also let developers have their own interpretation of the space. When the developer puts a null without thinking for a reason, the user always forgets to check for null, triggering various possible errors. We want to confirm the timing and purpose of using NULL and use explicit semantics. If you do not want to return NULL, you can return an optional instance, and if the return type is optional when the method is called, you should immediately think that it may or may not contain a value. To establish a optional instance there are several static methods, use the of () method to specify a non-null value to establish an optional instance, and use the empty () method to establish a optional instance that does not contain a value. When the optional does not contain a value, the java.util.NoSuchElementException is thrown directly, which implements the concept of a fast error. A good way to do this is to use the OrElse () method to specify an alternative value when the value does not exist. In the past, many of the link libraries used a lot of NULL, these link libraries can not be changed to change, using optional ofnullable () to the link library will return null method, when using the Ofnullable () method, if you specify a non-null value will call the of () method , the Empty () method is called when a null value is specified.
2. function interfaces for standard APIs
JDK8 defines the general function interface, basically placed in the Java.util.function suite, in terms of behavior, basically can be divided into consumer, Function, predicate and supplier four types. If the desired behavior is to accept an argument and then not return a value after processing, you can use the consumer interface. Consumer interface is mainly to accept a single object instance as an argument, for the basic type int, long, double, there are also Intconsumer, Longconsumer, doubleconsumer three function interfaces For an interface that accepts two instances of an object as an argument, Biconsumer, plus objintconsumer, Objlongconsumer, Objdoubleconsumer, the first parameter of the three function interfaces accepts an object instance, The second parameter accepts an int, a long, and a double, respectively. If you need to accept an argument and then return the result after the argument is evaluated, you can use the function interface. The sub-interface of the function is Unaryoperator, the specialization is the same type as the parameter and the return value, although JDK8 still does not support operator overloading, but the naming is obviously derived from some languages, and the operator is also the concept of a function. You can use the predicate function interface if you accept an argument and then return only the Boolean value, which is the direct assertion of the true or false behavior based on the arguments passed in. If the desired behavior is to not accept any arguments and then return a value, then you can use the Supplier function interface.
3. Using stream for pipeline operation
It can be seen that the biggest difference is that there is no use of the For loop and if judgment, and the use of the pipe style, but also the difference in functionality, if the read file is large, the second program fragment will be more effective than the first program fragment. The difference in functionality is that The Files.readalllines () method of the first program fragment returns a list instance that includes all the rows in the document, and if the first line matches the specified condition, then the subsequent row reads are superfluous, and the second program fragment's lines () method actually does not read any line, filter () Nor does it filter any line until the FindFirst () is called, and the filter () specifies that the condition is actually executed, while the stream returned by the lines () is required to read the first row, and if the first row is met, the subsequent rows are no longer read. A pipeline includes: source, 0 or more intermediate operations, and a final operation. Stream can iterate only once and iterate over the stream repeatedly, raising an error.
4. Reduce and collect for stream
Operation Result:
In a set of data, the criteria for a number, or a set of data conditionally collected to another container, there are many places in the design of such requirements, the use of loops to solve such requirements, is also the most common method for many developers. In this loop structure, there is actually a step, which takes a set of data out of the cut, and then by specifying the operation to obtain the structure of the result, JDK8 the process structure to generalize, define the reduce () method to achieve the custom computing requirements. The lambda expression for reduce () must accept two arguments, the first argument is the result of the operation after accessing the element on the set of data, the second argument is the current access element, and the lambda expression itself is the operation you originally intended to perform in the loop. Reduce () If you do not specify an initial value, you will try to use the first element in the group data as the first argument value when you invoke the lambda expression first, because the data group may be empty, so reduce () does not specify the version of the initial value and returns Optionint. When collect () needs to collect objects, the first lambda is used to get the container object, which is equivalent to collector's supplier (), and the second lambda defines how the object is collected. That is, the role of Collector accumulator (), when using a stream with parallel processing capability, it is possible to divide the original data group using multiple containers, and when each small task is completed, how to merge is the third lambda to be defined.
5. About the Flatmap () method
In the process of programming, there are sometimes nested or waterfall-like processes, the structure of each layer is very similar to the operation, but the return type is different, it is difficult to extract process reuse. Method may have no value, it is not recommended to use NULL as a representative without a value. Optional's FlatMap () is a confusing name, FlatMap () is like taking another box out of the box, and the lambda expression specifies the conversion relationship between the value in the previous box and the next box, because the calculation scenario that determines whether a value is hidden, So the user can explicitly specify the specific operation of interest. The difference between the map () method and the Flatmap () method is that in the map () method operation, the result of the mapper.apply (value) is used with the optional.ofnullable () method, so there is a way to continue to handle null.
Third, lambda and parallel processing
1.Stream and parallel Stream () and Parallelstream () two methods, the former represents the loop processing, the latter represents the parallel processing, want to know whether stream is parallel processing, can call Isparallel () to know. Be careful! The use of Parallelstream () does not necessarily mean that parallel processing is necessary to make the execution inevitably faster. It is important to think about whether the process can divide and merge results. In the Collect () operation, if you want to have a parallel effect, you must meet three conditions: stream must have parallel processing capability, collector must have Collector.Characteristics.CONCURRENT characteristics, Stream is unordered or collector has Collector.Characteristics.UNORDERED characteristics. When the API handles small problems, you should not interfere, and it is best to do only one thing at a time.
2. Using Completablefuture
If you want to read a text file asynchronously and do something after the document has been read, you can use Executorservice to submit () a Runnable object. This asynchronous operation uses a callback style that, in each callback, can be easily written back to hell, resulting in poor readability, if the asynchronous operation and callbacks are repeated again. The static method of Completablefuture Supplyasync () accepts the supplier instance, which specifies the asynchronous execution of the task, which returns the Completablefuture instance.
13th chapter,
I. Time and date of recognition
1. Measurement of Time
Before you formally know what time Java provides for processing APIs, you have to understand some historical issues of time and date, so that you know that time and date are really a complex issue, and that using a program to handle time and date is not just a matter of using the API.
A. GMT: Greenwich Mean Time is referred to as GMT, and at the beginning it is the standard solar time from the Royal Observatory of Greenwich, when the sun arrives at the highest point of the sky at Greenwich Standard Time, Greenwich Mean time is often considered as UTC time.
B. World time: It is more accurate to observe the sun than by observing distant stars crossing the meridian, also known as UT. GMT is the same as UT before UTC is introduced in 1972.
C. International Atomic time: While observing a distant star is more accurate than observing the sun, UT is still largely affected by the Earth's rotational velocity and is subject to errors. When the International Atomic Time (TAI) was defined in 1967, the International unit of the second was defined as the time spent on the radiation vibrations of cesium atoms for 9,192,631,770 weeks, and the time was synchronized from the 1958 of UT.
D. World coordination time: Since the second length based on the definition of cesium atom vibration is fixed, the rotation of the earth will be slower, which will actually lead to the fact that Tai time will continue to advance based on the Earth rotation of the UT series time, in order to maintain the TAI and UT time is not too large, Therefore, the world coordinated Time (UTC) with a compromise revision is proposed.
E.unix Time: The time representation of a UNIX system, defined as the number of seconds elapsed in UTC time January 1, 1970 00:00:00 as the starting point, regardless of the leap second correction, to express a moment on the timeline.
F.epoch: The beginning of a particular era, a moment on the timeline. For example, the time information in the Java.util.Date package is the number of milliseconds that January 1,1970,00:00:00 GMT passes, which can be referred to as the epoch millisecond.
For now, even though it is GMT, the time actually referred to is UTC time. The unit definition of the second is based on the Tai, which is the number of radiation vibrations of the cesium atom. Unix time is the number of seconds elapsed from January 1, 1970 00:00:00 for the starting point, regardless of leap seconds.
2. Introduction to the Calendar
Measuring time is one thing, the expression date is another thing, the beginning of the time mentioned before, are the use of the Gregorian calendar, the Chinese world is often called the Gregorian calendar, before referring to the Gregorian calendar, first to look at other calendars. The Julian calendar is the predecessor of the current Gregorian calendar, used to replace Ides. The Julian calendar amended the Roman calendar three years to set a leap year error, four years to change a run. Gregorian calendar reformed the Julian calendar, the Julian calendar on Thursday October 4, 1582, the next day, the Gregorian calendar October 15, 1582 Friday. In some relatively new time-date API applications, you may see ISO 8601, strictly speaking, ISO 8601 is not a calendar system, but a time-date representation of the standard, to unify the time-date data Interchange Format, ISO 8601 in the data definition most of the same as the Gregorian calendar, But there's still a small difference. In the definition of ISO 8601, 19th century refers to 1900 to 1999 (inclusive of the year), while the Gregorian calendar of 19th century refers to 1801 to 1900 (including the year).
3. Recognize time zones
Geographically, because the earth is round, basically one day on the other side is the night, in order to let people on the time of cognition in line with the rest, so set a UTC offset, roughly speaking, longitude every 15 degrees is offset one hours, considering the UTC offset time representation, usually identifies the z symbol. However, some countries have a large latitude across the territory, a country has a lot of time instead of trouble, so do not take every 15 degrees offset an hour, such as the United States only 4 time zones, and China, India only use a single quarter. The number of milliseconds in a year is definitely notpurely 3651000, and do not perform time and date calculations based on such erroneous notions.
Fourth. Understanding Date and Calendar
1. Instantaneous date on the timeline
If you want to get system time, One way to do this is to use the System.currenttimemillis () method, which returns a long integer representing the number of milliseconds since January 1, 1970 0:0 0 seconds 0 milliseconds to date, that is, the beginning of time is the same as the beginning of the Unix time mentioned earlier. But in this way it is the machine's time view, which represents a moment on the timeline, a long string of epoch milliseconds that is not a human time view, and has no meaning for human beings to read. Date has two constructors that can be used, one can be built using the epoch millisecond number, and the other is no argument constructor. It also uses System.currenttimemillis () to get the epoch milliseconds, and calls GetTime () to get the epoch millisecond values that are stored internally. The GetXXX () method outside of GetTime () is deprecated, and the setxxx () method outside of SetTime () is deprecated. The date instance is basically recommended to be used only as a moment on the timeline, that is, the number of milliseconds that have elapsed since the January 1, 1970 0:0 0 seconds, and other settings and acquisition of time Date fields, which are recommended for calendar execution.
Operation Result:
2. DateFormat of formatted time and date
For processing of string time formats, Responsibility falls to Java.text.DateFormat body, DateFormat is an abstract class, its operation class is Java.text.SimpleDateFormat, you can directly build SimpleDateFormat instance, or use DateFormat getd Static methods such as Ateinstance (), Gettimeinstance (), Getdatetimeinstance ().
Results:
SimpleDateFormat also has a parse () method that can parse the specified string into a date instance in the format specified when the SimpleDateFormat was built.
Results:
3. Calendar of processing time dates
Date is now recommended as an instantaneous representation on the timeline, to format the time date through DateFormat, and if you want to obtain a time-date information, or to manipulate the time-date, you can use the calendar instance. Calendar is an abstract class, Java.util.GregorianCalendar is its subclass, manipulating the Julian calendar and Gregorian calendar of the mixed calendar, through the calendar getinstance () to obtain the calendar instance, the default is to obtain the GregorianCalendar instance. You can use the after () or before () method if you want to compare the time and date successively for two calendar days.
Results:
4. Setting timezone
Before using the calendar, the time zone information is not used, which uses the default time zone, and you can use Java.util.TimeZone's Getdefault () to get the default time zone information.
Results:
Fifth. JDK8 new time and date API
1. API for Machine time view
The date instance really represents not the dates, the closest concept should be a specific moment on the timeline, the time precision is milliseconds, that is, UTC time January 1, 1970 0:0 0 milliseconds to a specific instantaneous millisecond difference. The date name appears to be a human concept of time, but it is actually the time concept of the machine. The only real reliable information is the number of epoch milliseconds that are included. So if you get the date instance, the next step to get the time information should be to get the epoch milliseconds through the date gettime (). JDK8 the new time and date processing API, the most important thing is to clearly separate the concept of time from the concept of human time.
2. API for Human time perspectives
For the date time of the fragment, the JDK8 new time and date API are defined by classes such as LocalDateTime (), Localdate (), localtime (), which are based on the ISO 8601 calendar system and are time and date definitions without a time zone.
Results:
In the new time and date API, the UTC offset is separate from the time zone concept, and offsetdatetime purely represents the UTC offset, using ISO 8601. If you only want to represent 2014, you can use year, if you want to represent 2014/5, you can use Yearmonth, if you want to represent only May, you can use month, if you want to represent 5/4, you can use MonthDay, where month is an enum type, If you want to get numbers that represent the month, do not use the Oridinal () method, because Oridinal () is the order in which the enum is defined, starting with 0, to get the number of months represented by the GetValue () method.
Results:
3. The operation of Time
Results:
Period and duration at first glance some difficult difference, period is the date difference, the Between () method accepts only localdate, does not represent the smaller unit than "Day". However duration is a time difference, the between () method can accept LocalDateTime (), Localdate (), localtime (), which do not represent larger units than "days".