ForEach Method
- Java eight for each method is a utility function to it over a collection, such as list, set or map and stream.
- It is used to perform a given action on each of the element of the collection.
Meta Space
- Meta space Help us define process size.
- If meter space is not handled properly, it may bring down entire application and application server.
- Meta space was earlier called as PermGen space and was replaced in JDK8.
- The metadata data is now stored in a native memory called as “Meta space”.
- This memory is not a contagious Java Heap memory. It allows for improvements over Perm Gen Space in garbage collection, tuning, concurrent de allocation of meta data.
- Objects are created in eden space in heap memory.
- If objects survive garbage collection, then they are moved either in Survivor 1, one or survivor 2 space.
- If the objects survive another garbage collection, then they move to old generation space.
- Eden space, survival space 1, survival space 2 And old generation space are called in heap Space.
- Metadata space Takes memory from native memory and all meta data info is stored in meta Space.
- The advantage of meta space is that we have no more out of memory error Due to Perm Gen space not available.
- Perm Gen Is a part of Java Heap, Meta space Is not a part of heap. Meta space is a part of Native memory(process manager) Which is only limited by the host operating system.
- We can configure using -XX: MaxMetaSpace size Which sets the maximum Meta space size for your application.
- It consumes memory directly from operating system.
- We also need to monitor meta space along With heap size
Perm Gen
- Prem Gen is the memory area in heap that is used by JVM to store class and method objects.
- If our application loads, lots of classes Perm Gen Utilisation will be high.
- Perm Gen Also stores String intern storage.
- Size of Perm Gen Is configured using - XX MaxPermSize
- Typically, 250 6MB should be more than enough for PermGen space for most Of the applications.
- However, it is not unusual to see the error “java.lang.outofmemoryerror: PermGen Space” If you are loading unusual number of classes.
Lambda Function
- Earlier we had to create anonymous class to perform a single operation for an object.
- A separate class needs to be created and loaded every time.
- Now we can implement our class like a function.
- Lambda provides us with a concise code.
- We can change the implementation of an interface to one line by injecting it directly in the object.
- A lambda expression is used to write a lambda function.
- Lambda function enables functional programming
- The code is Readable and concise
- It is easier to use with API’s and libraries
- It enabled support for parallel processing
- We removed the anonymous class and replace it with a functional block of code.
- We remove the following
- Name of the function
- Return type
- Modifier
- Lambda expression is a short block of code Which takes in parameters and returns the value.
Streams
- Streams are used to process the elements in a collection.
- A collection is a group of elements Of similar type.
- Collection is used to represent group of data objects as single entity
- We can process data in the stream, using a filter and a map.
- We can add all object’s of collection to a stream using stream() Method.
- All the element stream related Classes Can be found in The Java.util package.
- Streams are also available In java.io Package, but that is used to handle I/O streams for reading files etc.
- Once we use the stream, we can’t reuse it.
- Stream provides methods to perform bulk operations easily
- The methods of stream may return a stream or may provide a terminal value.
- Bulk operations were difficult in for loop.
- Using Streaming we can perform bulk operations easily.
- Filter, Map, Flat map, Distinct, Limit are called as non-terminal methods as they are used to process data in a stream.
- Non-terminal methods always return a stream of objects. On this stream Then we apply terminal operations.
- Non-terminal methods return updated stream of objects on which we can apply terminal methods.
- Terminal methods execute just before completion of execution. For example, collect, count,min, Max, forEach, ToArray, toList,reduce.
- Terminal method’s are applied after non-terminal methods.
- Terminal method’s provide us with a result
- Terminal methods, we can use on stream directly.
- Before using terminal methods, we can also use non-terminal methods.
- Terminal operations, we can use directly on stream as well as after applying non-terminal operations.
- Methods of stream are as follows
- Reduce
- Reduce takes an initial value and perform the operation on pair of elements streams And then perform same operationof the result with the initial value provided
- reduce(0,(c,e)->c+e)
- Reduce provides a combined object from individual objects in a stream.
- The type of combined object Is same as type of individual objects in a stream.
- Reduce can be used to reverse a string where we keep appending the values in reverse order.
- Example
- Filter
- Filter is used to filter the data based on certain conditions and the result can be used to store In a collection are used for some other purpose for processing.
- Filter happens based on certain condition.
- Example
- Map
- In map, we get each and every element or object from collection. We apply some operation on each and every object in collection and result can be stored in another collection or we can use the data for some other purposes.
- Map is An intermediate operation.
- Map transforms The objects in a stream and result is stored in target collection.
- When we use filter with map, we filter First and then map.
- Example
- Sorted
- Sorted method can be used to sort elements in a stream.
- Sorted is used to sort the elements in a Stream.
- We can sort in reverse order by passing “Comparator.reverseOrder()” in sorted() method.
- Example
- Count
- Count is used to count the number of elements In a result stream that we get after operations are performed.
- Return the count of objects after processing is completed.
- Example
- Collect
- Collect is used to collect the data and store it into another collection.
- Distinct
- It is used to get unique data from the stream
- Example
- Foreach
- reads each and every Value from collection and returns, nothing.
- To read every element from stream and perform certain operations.
- Min
- It is used to find the minimum value in the stream
- To get minimum of collected objects.
- Example
- Max
- It is used to find the maximum value in the stream
- To get maximum of collected objects
- Example
- PartitionBy
- In partition by we partition a stream based on a condition.
- In partition, by the result is a map of Boolean key and list of stream values.
- Example
- GroupBy
- In group by We group based a stream based on the condition.
- In group by The result Is a map of object key, which is the base basis of grouping And list of stream values.
- Example
- FlatMap
- Flat map is used to process complex data in our collections.
- A complex data is a collection within a collection.
- When we want to process a collection, which has another collection in its data, we need flat map.
- For example, a collection may have employee records which may have a field which represents collection of phone, numbers, collection of emails, collection of addresses.
- Flat map returns a stream of that sub collection in main collection.
- Flat map is one to many operation it returns multiple objects that is a stream of objects.
- Example
- Collect
- Used to collect the objects in a collector using collector() method.
- toArray
- To copy objects to an array And return array we have toArray().
- toList
- To copy objects to a list and return that list.
- toMap
- anyMatch
- anyMatch Will return true If any object from the stream matches, the predicate supplied.
- Example
- allMatch
- allMatch Will return a Boolean Value, whether it is true or false if the passed Predicate matches all element in stream.
- Example
- noneMatch
- If the Predicate passed Is not matching with any of the elements in the stream, then it will return true else it will return false.
- Example
- findAny
- Find any will return any element from the stream.
- Example
- findFirst
- Find first will return first element from the stream.
- Example
- We always use a lambda expression in filter and map methods of the Stream.
- Intermediate operations in stream API are always lazy.
- Parallel Stream is a powerful feature of stream that enables pipelines to execute in parallel
- All collections, Support the parallelStream() Method that returns A parallel stream.
- Stream<String> parallelStream = stringlist.parallelStream().
- When a stream execute in parallel, the Java runtime divides the stream into multiple sub streams. The aggregate operations iterate over and process these sub streams In parallel and then combine the results.
- Example
- Collectors Class in stream API is used to perform various terminal reduction operations.
- Collectors class implement’s collector interface.
- Collector interface implements, Various useful reduction operations.
- Methods of collectors class are given here in official documentation.
Completable Future
- A Java future API was introduced in Java five and a future is used as a reference to the result of an Asynchronous computation.
- Future interface was added in Java 5 to serve as a result of asynchronous computation, But it did not have any methods to combine these computations or handle possible errors.
- In Java, eight, the Completable future class was introduced. Along with the future interface, it also implements The completion stage interface. This interface defines the contract for an Asynchronous computation step that can be combined with other steps.
- Completable future was introduced as a Java eight concurrency improvement.
- Completable future Is used for asynchronous programming In Java.
- Completable future Is at the Same time, a building block and a framework with different methods for composing, combining, Executing a computation steps and handling errors.
- Completable future class implement the future interface, so you can use it as a future implementation, but with additional completion logic.
- We can create an instance of this class with a no-arg constructor To present some future result, hand it out to the consumers and complete it at sometime in the future using complete method.
- The consumer may use the get method to block the current head until this result is provided.
- Writing a non-blocking code by running a task on a separate thread rather than the main application, thread.
- The main thread will be able to execute other tasks in parallel improving overall performance of program.
- There are certain limitations of future because of which Completable future Was introduced in Java 8
- Say we wrote a method that retrieves data from a remote server And choose to run it in a separate thread and return future.
- If the remote service is down, we cannot complete future manually using the latest data available.
- Future cannot perform further action until the result is available, and it doesn’t notify to us of its completion.
- It provides with a get method which is blogged until the result is available.
- Attaching a call back function is not possible
- Multiple futures cannot be chained together.
- Sometimes we will need to execute a long running task, and when the task is done, we need to send its result to another long running task.
- Multiple futures cannot be combined together
- Say we have 10 different future that we want to run in parallel and then Run some function after all of them completes.
- There is no exception handling in future API.
- All the above limitations create a requirement of Completable future
- It implements the future and completion stage interfaces and provides a huge set of methods for creating, changing and combining multiple futures. It also has a very comprehensive exception handling Support.
- We can manually complete a method using complete function.
- We can use getnow method to Temporarily return a value
- This helps to avoid blocking our get method
- It returns a default value, if result is not ready.
- Static methods, runAsync() And supplyAsync() Allow us to create a Completable future instance out of the runnable and supplier functional types respectively.
- If we don’t want to return something from task We use runAsync method Which takes the Runnable interface as input.
- If we want to return some result from background task we make use of supplyAsync Method which allows us to provide instance of a supplier as a lambda expression.
- Complete future with an encapsulated computation, logic
- Static methods, runAsync and supplyAsync Allow us to create a Completable future instance Out of runnable and supplier functional types Correspondingly.
- Both runnable and supplier are functional interface that allow passing their instances as lambda expressions.
- The runnable interface is the same old interface used in threads And it does not allow to return the value.
- The supplier interfere is the generic functional interface with a single method that has no arguments and returns a value of parameterised type.
- Supplier allows to provide an instance of the supplier as a lambda expression that does the calculation and returns the result.
- Possessing results of a asynchronous, computations
- The most generic way to process the result of a computation into feed is to use a function.
- The thenApply Method does exactly that.
- Access a function instance uses it to process the results and returns of future that holds a value returned by the function.
- If we do not want to return a value down the future chain, we can use instance of consumer function interface. It is a single method that takes a parameter and returns void.
- There is a method in Completable interface called as thenAccept Which accepts a consumer and passes with the result of the computation.
- The final future get call returns The instance of void type
- If we neither want to accept any computation, nor want to return some value at the end of the chain Then we can pass runnable lambda To thenRun method.
- Running multiple futures in Parallel
- When we need to execute multiple futures in parallel, we usually want to wait for all of them to execute and then process combined results.
- Handling errors
- For handling error In a chain of asynchronous computation Steps, Throw/catch, idiom had to be adopted in a similar fashion.
- Instead of catching an exception in a syntax block, the complete future Allows you to handle it in a handle method. This method receives two parameters, a result of a computation(if it finished successfully) and the Exception thrown(If the computation step did not complete normally)
- Asynchronous Methods
- API in Completable future class have two additional variants with the associated Post fix.
- These methods are usually intended for running a corresponding step of Execution in another thread.
- The methods without the sink post fix run the next execution stage using The same thread.
- The Async method without the executor argument Runs a step using the common fork/join pool Implementation of executor That is accessed with the fork join pool Common pool method.
- Async Method with an executive argument, runs a step using the passed executor.
- To apply call back, we use thenapply, thenaccept and thenrun methods.
- Thenapply takes input as a function interface
- Multiple thenapply methods can be chained
- Thenaccept and thenrun Method are used as a last call back as they do not return. Any result.
- Thenaccept Returns takes in a consumer and accept results of previous future and return a void.
- Thenrun method Simply takes a runnable And will execute it when ever previous future is completed.
- To run, call back in a different thread Use the following variant of above methods
- thenApplyAsync
- thenAcceptAsync
- thenReturnAsync
- If we are using two methods that return Completable future then result will be of a type Completable future with a nested Completable future.
- To get a flattened, Completable future From the above I.e top level Completable future Use thenCompose()
- Then compose is used to combine two futures while one future depends on other.
- We also have thenAcceptBoth
- Completable Future AllOf method
- Execute multiple futures in parallel weights for all of them to finish and then process their combined results
- Completable Future AnyOf method
- This returns values when any of the complete future completes.
- If you have future, that return results of different types then you won’t know the type of your final result
- Exception handling
- Exception is not propagated down the chain.
- It can be handled using then handle method
- Once exception occurs, chain is broken.
- Combining Futures
- The best part of the Completable future API is The ability to combine compatible instances in a chain of computation steps.
- The result of this changing is itself, a Completable future That allows further chaining and combining.
- This approach is in functional languages.
- Example
No comments:
Post a Comment