StringJoiner Here is an example:
StringJoiner joiner =newStringJoiner("/");
joiner.add("usr");
joiner.add("local");
joiner.add("bin");
This will give you a string like "usr/local/bin" which you can pass it to any program.
String.join()
String
colonSeparatedValue=String.join(":", "abc", "bcd", "def");
System.out.println("colon separated
String : "+colonSeparatedValue);
This will print the following String:
colon separated
String :abc:bcd:def
Write Custom FunctionalInterface to implement sorting and use in Stream API.
https://beginnersbook.com/2017/10/java-8-lambda-comparator-example-for-sorting-list-of-custom-objects/
explain parallelSort() in the Arrays class of java.util package
Question: explain the Consumer<T> interface?
Answer: generally to write Lambda expression we need to have functionalinterface in place.
What if, i dont have any functional interface written then I can use use Consumer interface.
I will write lambda expression and assign the implementation in Consumer interface and then call its accept() to execute the lambda expression.
https://www.google.com/amp/s/www.geeksforgeeks.org/java-8-consumer-interface-in-java-with-examples/amp/
1. forEach() Aggregate operations do not contain a method like
Iterator uses hasNext() and next() function to get the value.
2. forEach() is a method and it is introduced int 1.8 while Iterator is a interface.
3. forEach() Aggregate operations process elements from a stream, not directly from a collection.
Iterator process element from the original collections so parallel modification may throw exception.
4. You can specify lambda expressions as parameters for most aggregate operations. This enables you to customize the behavior of a particular aggregate operation.
What is return type of Collectors.toList() method?
As with most operations in the
Lets suppose we have List of Person objects, Person will have gender as MALE or FEMALE. now I want to get a map all person based on their gender as MALE and FEMALE.
For Example: map will have MALE as key and list of Person as value. similarly FEMALE as key and list of Person as value
OR
How to perform grouping in stream api.
How to get IntStream from stream of Person objects?
What is parallel stream in jdk 1.8?
is stream api lazy loaded?
All intermediate operations are lazy. An expression, method, or algorithm is lazy if its value is evaluated only when it is required. (An algorithm is eager if it is evaluated or processed immediately.) Intermediate operations are lazy because they do not start processing the contents of the stream until the terminal operation commences. Processing streams lazily enables the Java compiler and runtime to optimize how they process streams. For example, in a pipeline such as the
What is lambda expression interference in stream api?
References
https://beginnersbook.com/2017/10/java-8-arrays-parallel-sort-with-example/
Write Custom FunctionalInterface to implement sorting and use in Stream API.
https://beginnersbook.com/2017/10/java-8-lambda-comparator-example-for-sorting-list-of-custom-objects/
explain parallelSort() in the Arrays class of java.util package
Algorithm of parallel sorting:
1. The given array is divided into the sub arrays and the sub arrays are further divided into the their sub arrays, this happens until the sub array reaches a minimum granularity.
2. The sub arrays are sorted individually by multiple threads. The parallel sort uses Fork/Join Framework for sorting sub arrays parallelly.
3. The sorted sub arrays are merged.
1. The given array is divided into the sub arrays and the sub arrays are further divided into the their sub arrays, this happens until the sub array reaches a minimum granularity.
2. The sub arrays are sorted individually by multiple threads. The parallel sort uses Fork/Join Framework for sorting sub arrays parallelly.
3. The sorted sub arrays are merged.
Advantage of Parallel Sort Over Simple Sort:
The parallelSort() method uses the concept of multithreading which makes it much faster compared to the normal sort when there are lot of elements.
The parallelSort() method uses the concept of multithreading which makes it much faster compared to the normal sort when there are lot of elements.
Example 1: Sorting Primitive Data types with Parallel Sort
import java.util.Arrays; public class Example { public static void main(String[] args) { int numbers[] = {22, 89, 1, 32, 19, 5}; //Parallel Sort method for sorting int array Arrays.parallelSort(numbers); //converting the array to stream and displaying using forEach Arrays.stream(numbers).forEach(n->System.out.print(n+" ")); } }
Output:
1 5 19 22 32 89
Example 2: Parallel Sort by specifying the start and end index
We can also specify the start and end for the sorting, in this case the sub array starting from the start index and ending at the end index is sorted, the rest of the array is ignored and doesn’t get sorted.
import java.util.Arrays; public class Example { public static void main(String[] args) { int numbers[] = {22, 89, 1, 32, 19, 5}; /* Specifying the start and end index. The start index is * 1 here and the end index is 5. which means the the elements * starting from index 1 till index 5 would be sorted. */ Arrays.parallelSort(numbers, 1, 5); //converting the array to stream and displaying using forEach Arrays.stream(numbers).forEach(n->System.out.print(n+" ")); } }
Output:
22 1 19 32 89 5
Question: explain the Consumer<T> interface?
Answer: generally to write Lambda expression we need to have functionalinterface in place.
What if, i dont have any functional interface written then I can use use Consumer interface.
I will write lambda expression and assign the implementation in Consumer interface and then call its accept() to execute the lambda expression.
https://www.google.com/amp/s/www.geeksforgeeks.org/java-8-consumer-interface-in-java-with-examples/amp/
In JDK8, how many threads are spawned when i'm using parallelStream? For instance, in the code:
list.parallelStream().forEach(/** Do Something */);
If this list has 100000 items, how many threads will be spawned?
Also, do each of the threads get the same number of items to work on or is it randomly allotted?
Answer:
The Oracle's implementation[1] of parallel stream uses the current thread and in addition to that, if needed, also the threads that compose the default fork join pool
ForkJoinPool.commonPool()
, which has a default size equal to one less than the number of cores of your CPU.
That default size of the common pool can be changed with this property:
-Djava.util.concurrent.ForkJoinPool.common.parallelism=8
Difference between forEach() (Aggregate Operations from stream api) method and Iterator?1. forEach() Aggregate operations do not contain a method like
next
to instruct them to process the next element of the collection.Iterator uses hasNext() and next() function to get the value.
2. forEach() is a method and it is introduced int 1.8 while Iterator is a interface.
3. forEach() Aggregate operations process elements from a stream, not directly from a collection.
Iterator process element from the original collections so parallel modification may throw exception.
4. You can specify lambda expressions as parameters for most aggregate operations. This enables you to customize the behavior of a particular aggregate operation.
What is return type of Collectors.toList() method?
As with most operations in the
Collectors
class, the toList
operator returns an instance of Collector
, not a collection.Lets suppose we have List of Person objects, Person will have gender as MALE or FEMALE. now I want to get a map all person based on their gender as MALE and FEMALE.
For Example: map will have MALE as key and list of Person as value. similarly FEMALE as key and list of Person as value
OR
How to perform grouping in stream api.
The following example groups members of the collection
roster
by gender:Map<Person.Gender, List<Person>> byGender = roster .stream() .collect( Collectors.groupingBy(Person::getGender));
The
groupingBy
operation returns a map whose keys are the values that result from applying the lambda expression specified as its parameter (which is called a classification function). In this example, the returned map contains two keys, Person.
Gender.MALE
and Person.
Gender.FEMALE
. The keys' corresponding values are instances of List
that contain the stream elements that, when processed by the classification function, correspond to the key value. For example, the value that corresponds to key Person.
Gender.MALE
is an instance of List
that contains all male members.
How to group names of person on their gender from above example
The following example retrieves the names of each member in the collection
roster
and groups them by gender:Map<Person.Sex, List<String>> namesByGender = roster .stream() .collect( Collectors.groupingBy( Person::getGender, Collectors.mapping( Person::getName, Collectors.toList())));
The
groupingBy
operation in this example takes two parameters, a classification function and an instance of Collector
. The Collector
parameter is called a downstream collector. This is a collector that the Java runtime applies to the results of another collector. Consequently, this groupingBy
operation enables you to apply a collect
method to the List
values created by the groupingBy
operator. This example applies the collector mapping
, which applies the mapping function Person::getName
to each element of the stream. Consequently, the resulting stream consists of only the names of members.
How to retrieves the total age of members of each gender:
Map<Person.Sex, Integer> totalAgeByGender = roster .stream() .collect( Collectors.groupingBy( Person::getGender, Collectors.reducing( 0, Person::getAge, Integer::sum)));
The
reducing
operation takes three parameters:identity
: Like theStream.reduce
operation, the identity element is both the initial value of the reduction and the default result if there are no elements in the stream. In this example, the identity element is0
; this is the initial value of the sum of ages and the default value if no members exist.mapper
: Thereducing
operation applies this mapper function to all stream elements. In this example, the mapper retrieves the age of each member.operation
: The operation function is used to reduce the mapped values. In this example, the operation function addsInteger
values.
How retrieves the average age of members of each gender:
Map<Person.Sex, Double> averageAgeByGender = roster .stream() .collect( Collectors.groupingBy( Person::getGender, Collectors.averagingInt(Person::getAge)));
How to get IntStream from stream of Person objects?
IntStream ageStream = roster .parallelStream() .filter(p -> p.getGender() == Person.Sex.MALE) .mapToInt(Person::getAge);
What is parallel stream in jdk 1.8?
is stream api lazy loaded?
All intermediate operations are lazy. An expression, method, or algorithm is lazy if its value is evaluated only when it is required. (An algorithm is eager if it is evaluated or processed immediately.) Intermediate operations are lazy because they do not start processing the contents of the stream until the terminal operation commences. Processing streams lazily enables the Java compiler and runtime to optimize how they process streams. For example, in a pipeline such as the
filter
-mapToInt
-average
example described in the section Aggregate Operations, the average
operation could obtain the first several integers from the stream created by the mapToInt
operation, which obtains elements from the filter
operation. The average
operation would repeat this process until it had obtained all required elements from the stream, and then it would calculate the average.What is lambda expression interference in stream api?
Interference
Lambda expressions in stream operations should not interfere. Interference occurs when the source of a stream is modified while a pipeline processes the stream. For example, the following code attempts to concatenate the strings contained in the
List
listOfStrings
. However, it throws a ConcurrentModificationException
:try { List<String> listOfStrings = new ArrayList<>(Arrays.asList("one", "two")); // This will fail as the peek operation will attempt to add the // string "three" to the source after the terminal operation has // commenced. String concatenatedString = listOfStrings .stream() // Don't do this! Interference occurs here. .peek(s -> listOfStrings.add("three")) .reduce((a, b) -> a + " " + b) .get(); System.out.println("Concatenated string: " + concatenatedString); } catch (Exception e) { System.out.println("Exception caught: " + e.toString()); }
This example concatenates the strings contained in
listOfStrings
into an Optional<String>
value with the reduce
operation, which is a terminal operation. However, the pipeline here invokes the intermediate operation peek
, which attempts to add a new element to listOfStrings
. Remember, all intermediate operations are lazy. This means that the pipeline in this example begins execution when the operation get
is invoked, and ends execution when the get
operation completes. The argument of the peek
operation attempts to modify the stream source during the execution of the pipeline, which causes the Java runtime to throw a ConcurrentModificationException
.
What is stateful lambda expression?
Avoid using stateful lambda expressions as parameters in stream operations. A stateful lambda expression is one whose result depends on any state that might change during the execution of a pipeline. The following example adds elements from the
List
listOfIntegers
to a new List
instance with the map
intermediate operation. It does this twice, first with a serial stream and then with a parallel stream:List<Integer> serialStorage = new ArrayList<>(); System.out.println("Serial stream:"); listOfIntegers .stream() // Don't do this! It uses a stateful lambda expression. .map(e -> { serialStorage.add(e); return e; }) .forEachOrdered(e -> System.out.print(e + " ")); System.out.println(""); serialStorage .stream() .forEachOrdered(e -> System.out.print(e + " ")); System.out.println(""); System.out.println("Parallel stream:"); List<Integer> parallelStorage = Collections.synchronizedList( new ArrayList<>()); listOfIntegers .parallelStream() // Don't do this! It uses a stateful lambda expression. .map(e -> { parallelStorage.add(e); return e; }) .forEachOrdered(e -> System.out.print(e + " ")); System.out.println(""); parallelStorage .stream() .forEachOrdered(e -> System.out.print(e + " ")); System.out.println("");
The lambda expression
e -> { parallelStorage.add(e); return e; }
is a stateful lambda expression. Its result can vary every time the code is run. This example prints the following:Serial stream: 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 Parallel stream: 8 7 6 5 4 3 2 1 1 3 6 2 4 5 8 7
The operation
forEachOrdered
processes elements in the order specified by the stream, regardless of whether the stream is executed in serial or parallel. However, when a stream is executed in parallel, the map
operation processes elements of the stream specified by the Java runtime and compiler. Consequently, the order in which the lambda expression e -> { parallelStorage.add(e); return e; }
adds elements to the List
parallelStorage
can vary every time the code is run. For deterministic and predictable results, ensure that lambda expression parameters in stream operations are not stateful.
Note: This example invokes the method
synchronizedList
so that the List
parallelStorage
is thread-safe. Remember that collections are not thread-safe. This means that multiple threads should not access a particular collection at the same time. Suppose that you do not invoke the method synchronizedList
when creating parallelStorage
:List<Integer> parallelStorage = new ArrayList<>();
The example behaves erratically because multiple threads access and modify
parallelStorage
without a mechanism like synchronization to schedule when a particular thread may access the List
instance. Consequently, the example could print output similar to the following:Parallel stream: 8 7 6 5 4 3 2 1 null 3 5 4 7 8 1 2
References
https://beginnersbook.com/2017/10/java-8-arrays-parallel-sort-with-example/
0 comments :
Post a Comment