Java-1 8 PDF
Java-1 8 PDF
Java-1 8 PDF
➤ The ability to write code (functions) as objects. Nothing new but the style has changed
➤ Lambda expressions in
➤ At the heart of functional programming is thinking about your problem domain in terms of
➤ About @FunctionalInterface
DIY NEXT
DIY
➤ java.util.function.Function<T, R>
➤ 1.8 replete with libraries with APIs taking parameters of type Function
DIY NEXT
DIY
➤ The most important core library changes are focused around the
Collection API and its new addition - streams.
Streams Collections
Streams does not allow modifying the Collections do not provide a rich API to
underlying data-structure. It provides process the data. The API(s) are rich in
rich API to process the data - filter, map, traversing, adding, removing, getting.
sort, reduce etc. The implementations may be different
DIY NEXT
DIY
DIY NEXT
DIY
➤ Try to process the stream again and see the exception you
get
DIY NEXT
DIY
DIY NEXT
DIY
Comparator<Employee> c1 = Comparator.comparing(f1);
Comparator<Dependent> c2 = Comparator.comparing(f2);
➤ It can be used for any object. Only the condition changes (the function
of comparing)
DIY
The things that differ between implementations of this pattern are the
➤ combine function.
DIY
➤ Putting functions together. Once again refer to the HealthData model and
check the fact that employees have health plans and health plan has a name
➤ We want to get all the states that offer comprehensive health plans
➤ Let us get the names of all dependents that are of age greater than 15 of all
given employees. Note that dependents are associated to Employee
➤ Code snippet 1 : check the age of the dependent and add the name of
dependent to the Set
➤ Code snippet 2 : This time you are using stream but still doing the same
thing. Note that what you are doing with legacy kind of code is a good
candidate for filter
➤ Code snippet 3: Use a) filter b) map c) for each. Note that using for each on
dependents again is a good candidate for flatMap
empty result
DIY NEXT
DIY
The “in IntegerBiFunction” function gets executed following the rule that if there are
several possible target types, the most specific is inferred
BinaryOperator
has min & max
functions
Just the annotation to make sure that you accidentally do not define
2 abstract methods in an interface that is supposed to be functional
DIY NEXT
DIY
Compilation error
Enhanced
super syntax
3. No rule 3. If the previous two rules don’t give us the answer, the
subclass must either implement the method or declare it abstract.
DIY NEXT
DIY
Kind Example
DIY NEXT
DIY
DIY
DIY
Partition by employee that has dependents and those that does not have
dependents.
DIY
DIY
➤ R is the result
DIY
➤ Get the Set of Employee last names grouped by Health Plan (Do it the neater way -
using groupingBy(keyExtractor, mapper)
➤ mapper will convert Employee to lastName of employee and collect them all in a
Set
➤ In java 1.7 we would concatenate string with a prefix & suffix while
running through the loop as shown in code
Lets discuss first few code snippets with respect to side-effects while
processing streams in Ch4App6RefactoringAndCustomCollectorsPart2.java
(Trainer Copy)
DIY NEXT
This returns a String (& not Optional) as the identity can be used to infer that there will
be some value. Even if null is passed identity, it is converted to String
➤ Code Snippet 3 : shows how to use Stream.reduce(U identity, BiFunction<? super String, U>,
BinaryOperator<U> combiner) - 3 arguments
Here the objective is to return a different type other than String. U represents that other
data type
DIY NEXT
DIY
Code Snippet 4
➤ Prefix & Suffix “[“ & “]” respectively and print the reduced
String
StringCombiner.java
➤ merge : The merge function plays the role of a Combiner that merges
the two containers
Ch4App6RefactoringAndCustomCollectorsPart3.java
Ch4App6RefactoringAndCustomCollectorsPart3.java
➤ Now the real fun - Go back to StringCombiner and put SOP in merge
function and tell me whether it executes at all in the very first place
Stay Tuned
Parallelism
stream, each thread will
create a new
container
1 2
3
4
MyStringCollector.java
In order for Stream to work “as-expected” with parallelism as well, we must create a custom
java.util.stream.Collector as expected by the Stream and implement the following methods
➤ supplier() : a factory method that returns the container of the accumulated objects
➤ combiner() : especially for parallelism to add the objects from one container (on the
left) and another container (on the right) as shown in figures of previous slide
➤ finisher() : a function that transforms the combined objects into one single String
Ch4App6RefactoringAndCustomCollectorsPart4.java
➤ Concurrency arises when two tasks are making progress at overlapping time
periods.
➤ Parallelism arises when two tasks are happening at literally the same time, such
as on a multicore CPU.
➤ Collection.parallelStream()
➤ Stream.parallel()
➤ Uses Forkjoin.commonPool()
➤ Data : small data sets wont yield much of benefit. There is overhead,
split, merge, context switch etc.
➤ Packing : Primitives are faster to operate upon with much less overhead
Under the hood, parallel streams back onto the fork/ join framework. The fork
stage recursively splits up a problem. Then each chunk is operated upon in
parallel. Finally, the join stage merges the results back together.
Pretty Simple
➤ With threading model, every time you want to write some data to socket,
you would block the thread that you’re running on.
➤ Take a look at following code which has callback in the form of lambdas
➤ With vert.x you implement designs that are essentially non-shared-state design
➤ All communication is done by sending messages over event bus which means that
you don’t need to protect any shared state - so no locks and no
synchronization
➤ For e.g : How will you pass the result of one future to the other
without the pyramid doom
DIY
➤ Create stream of CFs and execute them such that the results are joined and
one does not wait for the other. There can be more than 2 CFs
➤ Create one CF called cf1 with simple supplier task which takes 3 seconds
➤ cf3.join to get the results. Take the time stamp and see how much time it takes
➤ thenCompose function executes the CFs sequentially because cf2 may be dependent on the results of
cf1.
➤ How will the result of cf1 will be used (composed) by cf2, is upto the implementation of cf2 Supplier
➤ cf2 does not kick off till the time cf1 is not completed
➤ cf2 and cf1 may run in different threads but still cf2 will start only after cf1 is completed with its
results
Using CompletableFuture.allOf
➤ In addition, the spreadsheet reacts to any future changes in B1 and updates the
value in C1.
➤ The RxJava library is a port of these reactive ideas onto the JVM.
➤ Works with its own thread pool with number of threads equal to cores
Ch7App0FolkJoinPoolRecurisveTask.java
➤ An array of String to be
concatenated while converting
each element to uppercase
➤ The trySplit method provides the required behavior. try because it may
fail to split and return null
➤ Rich set of APIs for reading, writing, and manipulating files and
directories
➤ The file system API provides single line operations for creating files
➤ All the name elements in the path must exist, apart from the file name,
otherwise, we will get an IOException:
➤ Code Snippet 7: Tempfiles without prefix & suffix. Extension will be tmp
➤ File change notification : One way to do this is to poll the file system
looking for changes but this approach is inefficient — it does not scale to
applications that may have hundreds of open files or directories to monitor
➤ Register types of events you are interested in: file creation, file deletion, or
file modification
➤ Register a directory with the watcher for the events (create, delete,
modify). A WatchKey is returned
➤ Get the WatchKey from the queue and. The WatchKey provides the
filename
➤ Retrieve each pending event(s), reset the key and resume waiting for the
events
DIY NEXT
DIY
➤ The package groups together the related attributes and defines a view
of the commonly used ones.
DIY
➤ The basic attributes that are common to all file systems is provided by the
BasicFileAttributeView which stores all mandatory and optional visible file attributes.
➤ The attributes are kind of meta-data of the file. You can get
➤ Operating systems and several third party applications have a file search
function where a user defines search criteria
➤ Should you need to search for all .class files, find and delete .mov files or
find all files that haven’t been accessed in the last month, then FileVisitor
is the solution
➤ With FileVisitor, you can traverse the file tree to any depth and perform
any action on the files or directories found on any branch
➤ The return value at each stage is of type FileVisitResult and controls the
flow of the traversal
FileVisitResult is an enum of four possible return values for the FileVisitor interface
methods
DIY
➤ Basic I/O in Java is blocking -- meaning that it waits until it can complete
an operation
➤ When an event occurs on the selector -- when a line of input arrives, for
instance -- the selector "wakes up" and executes.
DIY
DIY
DIY NEXT
DIY
DIY NEXT
DIY
➤ When the state of the subject changes, its observers are notified.
➤ Using lambdas, you can do away with Concrete Observer classes and pass
lambda expression for e.g.
➤ Cascading Style Sheets (CSS) and regular expressions are commonly used
external DSLs
➤ Ideally, code written in a DSL reads like statements made within the problem
domain that it is reflecting.
➤ The Java SE 8 javac compiler has a new -profile option, which allows
the application to be compiled using one of the new supported profiles
➤ Usage
➤ The result of running jdeps on your Java app will allow you to see which
Compact Profile runtime you will need to be able to execute your
application
➤ A formal effort has been underway having the stated goal of providing a
much more modular Java platform.
➤ The class loader delegation model is the graph of class loaders that pass
loading requests to each other.
➤ Class loaders are created with a single delegation parent and looks for a
class in the following places:
➤ Cache
➤ Parent
➤ Self
➤ A class loader first determines if it has been asked to load this same class in
the past.
➤ If so, it returns the same class it returned last time (that is, the class stored
in the cache).
➤ The bootstrap class loader (also known as the primordial class loader) cannot be
instantiated by Java code.
➤ BootstrapClassLoader class loader loads the core system classes from the boot classpath,
which is normally the JAR files located in the jre/lib directory.
➤ The extension class loader (also known as the standard extensions class loader) is a
child of the bootstrap class loader. Its primary responsibility is to load classes from the
extension directories, normally located the jre/lib/ext directory. This provides the ability
to simply drop in new extensions, such as various security extensions, without requiring
modification to the user's classpath.
➤ The system class loader (also known as the application class loader) is the class loader
responsible for loading code from the path specified by the CLASSPATH environment
variable. By default, this class loader is the parent of any class loader created by the user.
This is also the class loader returned by the ClassLoader.getSystemClassLoader() method.
➤ Resolution : These exceptions are usually simple to fix. You can ensure
that the classpath being used is set as expected
MS Learning & Consulting Ch-12
Class Loading Common class loading issues & resolving them
At the time of compilation class B exists but then removed before execution
Once you understand the class loaders involved in the loading of the library, you can
resolve these types of problems by placing the library in an appropriate location.
This exception is thrown during the verification stage of the linking phase of
class loading.
The binary data can be malformed if the bytecodes have been changed -- if the major
or minor number has been changed.
This could occur if the bytecodes had been deliberately hacked, for example, or if an
error had occurred when transferring the class file over a network
The only way to fix this problem is to obtain a corrected copy of the bytecodes,
possibly by recompiling.
➤ About hot loading : Updating the byte code in the perm gen directly
using java.lang.instrumentation
➤ Very powerful mechanism as you do not have to redeploy on all the nodes
➤ Your product / framework with a custom class loader will check if class is available on
local classpath and if it was, it will be returned. No class loading from a peer node will
take place in this case.
➤ If class is not locally available, then a request will be sent to the originating node to
provide class definition.
➤ Originating node will send class byte-code definition and the class will be loaded on the
worker node.
➤ This happens only once per class - once class definition is loaded on a node, it will never
have to be loaded again.
➤ The in-memory computing platform
➤ The closures and tasks that you use for your computations may be of any
custom class, including anonymous classes.
➤ In Ignite, the remote nodes will automatically become aware of those classes,
and you won't need to explicitly deploy or move any .jar files to any remote
nodes.
➤ Such behavior is possible due to peer class loading (P2P class loading), a
special distributed ClassLoader in Ignite for inter-node byte-code exchange.
➤ With peer-class-loading enabled, you don't have to manually deploy your Java
or Scala code on each node in the grid and re-deploy it each time it changes
➤ It also was a game changer for translating dynamic languages into the
Java byte code format
➤ In other words, a call site (for e.g. if lookup is called from main() then
main method is acting as a call site)
➤ The lookup object can only access those targets that are accessible to the
call site.
➤ Call site is the method from where the Method Handle is created.
➤ This bootstrap method is executed the first time the JVM encounters this
call site during execution.
➤ Whenever the Java compiler translates a lambda expression into byte code, it
copies the lambda's body into a private method inside of the class in which the
expression is defined.
➤ The parameters of such a method are those of the functional interface that the
lambda expression implements.
➤ On its invocation, this call site requests the binding of a factory for an instance
of the functional interface.
➤ As arguments to this factory, the call site supplies any values of the lambda
expression's enclosing method which are used inside of the expression and a
reference to the enclosing instance, if required.
➤ This factory is then responsible for creating a class that implements the
functional interface and which invokes the appropriate method that contains
the lambda's body which, as described before, is stored in the original class.
➤ Any language that should be executed on the Java virtual machine needs to be translated to Java
byte code.
➤ And as the name suggests, Java byte code aligns rather close to the Java programming language.
➤ This includes the requirement to define a strict type for any value and before invokedynamic was
introduced, a method call required to specify an explicit target class for dispatching a method.
➤ Looking at the following JavaScript code, specifying either information is however not possible
when translating the method into byte code
function (foo)
foo.bar();
}
➤ Using an invokedynamic call site, it has become possible to delay the identification of the method's
dispatcher until runtime and furthermore, to rebind the invocation target, in case that a previous
decision needs to be corrected.
➤ Before, using the reflection API with all of its performance drawbacks was the only real alternative
to implementing a dynamic language
➤ Thread-Safe & Mutable : The Date and Calendar classes are not thread safe,
leaving developers to deal with the headache of hard to debug concurrency
issues and to write additional code to handle thread safety. On the contrary
the new Date and Time APIs introduced in Java 8 are immutable and thread
safe, thus taking that concurrency headache away from developers.
➤ API Design & Ease of Use : The Date and Calendar APIs are poorly
designed with inadequate methods to perform day-to-day operations. The new
Date/Time APIs is ISO centric and follows consistent domain models for date,
time, duration and periods. There are a wide variety of utility methods that
support the commonest operations.
➤ LocalDate.parse(“2015-02-20”);
➤ boolean notBefore =
LocalDate.parse("2016-06-12") .isBefore(LocalDate.parse(“2016-06-11")
);
➤ Working with Period
➤ Java 8 has added the toInstant() method which helps to convert existing Date and
Calendar instance to new Date Time API as in the following code snippet:
➤ LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
➤ LocalDateTime.ofInstant(calendar.toInstant(), ZoneId.systemDefault());