I have put some code snippets for Java & I believe that all those will work for jdk1.5/1.6/1.7
Here I am planning to put the code snippets specific to Java8 & yes we can get numerous blogs/pages to learn about the new features of Java8, so I will not be writing about that here, will give just some samples here which may be helpful.
You can look below URLs to get quick information about Java8 stream features or others -
www.baeldung.com/java-8-streams
howtodoinjava.com/java-8-tutorial/
stackify.com/streams-guide-java-8/
Note :- You can read/study various pages online regarding tons of APIs & features in Java8 or other languages but its really difficult to keep all those syntax & different method names & signatures, at least I can't, on top of your head.
So just study various pages or books & get the idea about different features being provided by various technologies or
frameworks, rest we have google out there to help us on our quest to find the answers for our questions.
And, yes, I have seen, that there is no shortage of silly people who expect you to tell them syntax or write the code on paper when they themselves don't know a bit, never did proper programming.
It is really difficult to remember the APIs for Java like languages when their design/naming structure is not properly managed in some cases, one can see methods' names with no camel case, etc such issues in Java itself. We are told to follow some principles like SOLID & DRY but if we see these are themselves violated by such languages....why?
I can't understand.
===============================================================================================
Example 1: StringJoiner was introduced as part of Java8 to provide joining features. Though it doesn't seem to do anything special, it just avoids the extra coding to do joins of the strings by you. So do use if you feel it helpful.
import java.util.StringJoiner;
public class StringJoiners {
public static void main(String[] args) {
StringJoiner joinNames = new StringJoiner(",", "{", "}"); // passing comma(,) and curly-brackets as delimiter
// Adding values to StringJoiner
joinNames.add("Rahul");
joinNames.add("Raju");
System.out.println(joinNames);
// Creating StringJoiner with :(colon) delimiter
StringJoiner joinNames2 = new StringJoiner(":", "[", "]"); // passing colon(:) and square-brackets as delimiter
// Adding values to StringJoiner
joinNames2.add("Peter");
joinNames2.add("Raheem");
System.out.println(joinNames2);
// Merging two StringJoiner
StringJoiner merge = joinNames.merge(joinNames2); // while merging two string joiners, delimiter from the first joiner
// will be used while joining 2nd joiner to it.
System.out.println(merge);
}
}
Output :
{Rahul,Raju}
[Peter:Raheem]
{Rahul,Raju,Peter:Raheem}
===============================================================================================
Example 2 : If we have a huge array of numbers & we need to take some action on some numbers, then doing that in linear way will take much time.
Below is one example to achieve that efficiently using Fork & Join.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
* Below class will generate the sum of numbers which are less than 27000
* and divisible by 2.
* It uses the feature of Fork & Join to divide the array. Also as we may get
* an array will some random numbers at random positions in it & we need to take
* some actions as per some condition, so here using the feature of streaming
* for that.
*
*/
public class CustomRecursiveTask extends RecursiveTask<Integer> {
private static final long serialVersionUID = 1L;
private int[] arr;
private static final int THRESHOLD = 200;
public CustomRecursiveTask(int[] arr) {
this.arr = arr;
}
public static void main(String[] args) {
int size = 100000000;
int[] arr = new int[size];
for(int i = 1; i <= size; i++) {
arr[i-1] = i;
}
CustomRecursiveTask crt = new CustomRecursiveTask(arr);
System.out.println("Result : " + crt.compute());
}
/*
* This method is main method of activity & I myself don't
* understand it properly, how it is working exactly.
*/
@Override
protected Integer compute() {
if (arr.length > THRESHOLD) {
return ForkJoinTask.invokeAll(createSubtasks())
.stream()
.mapToInt(ForkJoinTask::join)
.sum(); //we can use reduce(0, Integer::sum) in place of sum() here;
} else {
int val = processing(arr);
return val;
}
}
private Collection<CustomRecursiveTask> createSubtasks() {
List<CustomRecursiveTask> dividedTasks = new ArrayList<>();
dividedTasks.add(new CustomRecursiveTask(
Arrays.copyOfRange(arr, 0, arr.length / 2)));
dividedTasks.add(new CustomRecursiveTask(
Arrays.copyOfRange(arr, arr.length / 2, arr.length)));
return dividedTasks;
}
private Integer processing(int[] arr) {
return Arrays.stream(arr)
.filter(a -> a%2 == 0 && a < 27000)
.map(a -> a * 10)
.sum();
}
}
Output : Result : 1822365000
===============================================================================================
Example 3 : How can we check the available date time features in Java8, there are many changes for this. Below is one sample -
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Set;
public class DateTimes {
public static void main(String[] args) {
LocalDate localDate = LocalDate.now();
System.out.println(localDate.toString());
LocalTime localTime = LocalTime.of(12, 20);
System.out.println(localTime.toString());
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.toString());
OffsetDateTime offsetDateTime = OffsetDateTime.now();
System.out.println(offsetDateTime.toString());
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
System.out.println(zonedDateTime.toString());
// Use below way to find the applicable ZoneId for your requirement & other available zones
Set<String> ids = ZoneId.getAvailableZoneIds();
}
}
Output :
2018-03-13
12:20
2018-03-13T23:31:01.887
2018-03-13T23:31:01.887+05:30
2018-03-13T23:31:01.887+05:30[Asia/Kolkata]
===============================================================================================
Example 4 : To sort the objects on the basis of some property of those objects. Like shown below, will be sorting the Employee1 objects on the basis of the names of the employees. Below are a few ways to sort the objects of Employee1 or Employee2, you can try to use anyone depending on your requirements & if you have rights to make any change in the class to make necessary changes. Code is self-explanatory, if need any explanation then please let me know.
import java.util.Arrays;
public class Sample1 {
public static void main (String[] ar){
Employee1[] employees = {
new Employee1("David"),
new Employee1("Naveen"),
new Employee1("Alex"),
new Employee1("Richard")};
Employee2[] employees2 = {
new Employee2("David"),
new Employee2("Naveen"),
new Employee2("Alex"),
new Employee2("Richard")};
System.out.println("Before Sorting Names: "+Arrays.toString(employees));
Arrays.sort(employees, (Employee1 a1, Employee1 a2) -> {return a1.name.compareTo(a2.name);});
System.out.println("After Sorting Names "+Arrays.toString(employees));
Arrays.sort(employees, employees[0]::nameCompare);
System.out.println("After Sorting Names "+Arrays.toString(employees));
Arrays.sort(employees, employees[0]::staticNameCompare);
System.out.println("After Sorting Names "+Arrays.toString(employees));
System.out.println("Before Sorting Names: "+Arrays.toString(employees2));
Arrays.sort(employees2);
System.out.println("After Sorting Names "+Arrays.toString(employees2));
}
}
class Employee1 {
String name;
Employee1(String name) {
this.name = name;
}
public int nameCompare(Employee1 a1, Employee1 a2) {
return a1.name.compareTo(a2.name);
}
public int staticNameCompare(Employee1 a1, Employee1 a2) {
return a1.name.compareTo(a2.name);
}
public String toString() {
return name;
}
}
class Employee2 implements Comparable<Employee2>{
String name;
Employee2(String name) {
this.name = name;
}
public int compareTo(Employee2 a2) {
return this.name.compareTo(a2.name);
}
public String toString() {
return name;
}
}
Output :
Before Sorting Names: [David, Naveen, Alex, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
Before Sorting Names: [David, Naveen, Alex, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
===============================================================================================
For comparing & sorting the objects in the collections, & you want to use Java8 then look once the comparator API in Java8 & look below URL to get better understanding -
howtodoinjava.com/java-8/using-comparator-becomes-easier-with-lambda-expressions-java-8/
===============================================================================================
Here I am planning to put the code snippets specific to Java8 & yes we can get numerous blogs/pages to learn about the new features of Java8, so I will not be writing about that here, will give just some samples here which may be helpful.
You can look below URLs to get quick information about Java8 stream features or others -
www.baeldung.com/java-8-streams
howtodoinjava.com/java-8-tutorial/
stackify.com/streams-guide-java-8/
Note :- You can read/study various pages online regarding tons of APIs & features in Java8 or other languages but its really difficult to keep all those syntax & different method names & signatures, at least I can't, on top of your head.
So just study various pages or books & get the idea about different features being provided by various technologies or
frameworks, rest we have google out there to help us on our quest to find the answers for our questions.
And, yes, I have seen, that there is no shortage of silly people who expect you to tell them syntax or write the code on paper when they themselves don't know a bit, never did proper programming.
It is really difficult to remember the APIs for Java like languages when their design/naming structure is not properly managed in some cases, one can see methods' names with no camel case, etc such issues in Java itself. We are told to follow some principles like SOLID & DRY but if we see these are themselves violated by such languages....why?
I can't understand.
===============================================================================================
Example 1: StringJoiner was introduced as part of Java8 to provide joining features. Though it doesn't seem to do anything special, it just avoids the extra coding to do joins of the strings by you. So do use if you feel it helpful.
import java.util.StringJoiner;
public class StringJoiners {
public static void main(String[] args) {
StringJoiner joinNames = new StringJoiner(",", "{", "}"); // passing comma(,) and curly-brackets as delimiter
// Adding values to StringJoiner
joinNames.add("Rahul");
joinNames.add("Raju");
System.out.println(joinNames);
// Creating StringJoiner with :(colon) delimiter
StringJoiner joinNames2 = new StringJoiner(":", "[", "]"); // passing colon(:) and square-brackets as delimiter
// Adding values to StringJoiner
joinNames2.add("Peter");
joinNames2.add("Raheem");
System.out.println(joinNames2);
// Merging two StringJoiner
StringJoiner merge = joinNames.merge(joinNames2); // while merging two string joiners, delimiter from the first joiner
// will be used while joining 2nd joiner to it.
System.out.println(merge);
}
}
Output :
{Rahul,Raju}
[Peter:Raheem]
{Rahul,Raju,Peter:Raheem}
===============================================================================================
Example 2 : If we have a huge array of numbers & we need to take some action on some numbers, then doing that in linear way will take much time.
Below is one example to achieve that efficiently using Fork & Join.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
* Below class will generate the sum of numbers which are less than 27000
* and divisible by 2.
* It uses the feature of Fork & Join to divide the array. Also as we may get
* an array will some random numbers at random positions in it & we need to take
* some actions as per some condition, so here using the feature of streaming
* for that.
*
*/
public class CustomRecursiveTask extends RecursiveTask<Integer> {
private static final long serialVersionUID = 1L;
private int[] arr;
private static final int THRESHOLD = 200;
public CustomRecursiveTask(int[] arr) {
this.arr = arr;
}
public static void main(String[] args) {
int size = 100000000;
int[] arr = new int[size];
for(int i = 1; i <= size; i++) {
arr[i-1] = i;
}
CustomRecursiveTask crt = new CustomRecursiveTask(arr);
System.out.println("Result : " + crt.compute());
}
/*
* This method is main method of activity & I myself don't
* understand it properly, how it is working exactly.
*/
@Override
protected Integer compute() {
if (arr.length > THRESHOLD) {
return ForkJoinTask.invokeAll(createSubtasks())
.stream()
.mapToInt(ForkJoinTask::join)
.sum(); //we can use reduce(0, Integer::sum) in place of sum() here;
} else {
int val = processing(arr);
return val;
}
}
private Collection<CustomRecursiveTask> createSubtasks() {
List<CustomRecursiveTask> dividedTasks = new ArrayList<>();
dividedTasks.add(new CustomRecursiveTask(
Arrays.copyOfRange(arr, 0, arr.length / 2)));
dividedTasks.add(new CustomRecursiveTask(
Arrays.copyOfRange(arr, arr.length / 2, arr.length)));
return dividedTasks;
}
private Integer processing(int[] arr) {
return Arrays.stream(arr)
.filter(a -> a%2 == 0 && a < 27000)
.map(a -> a * 10)
.sum();
}
}
Output : Result : 1822365000
===============================================================================================
Example 3 : How can we check the available date time features in Java8, there are many changes for this. Below is one sample -
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Set;
public class DateTimes {
public static void main(String[] args) {
LocalDate localDate = LocalDate.now();
System.out.println(localDate.toString());
LocalTime localTime = LocalTime.of(12, 20);
System.out.println(localTime.toString());
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.toString());
OffsetDateTime offsetDateTime = OffsetDateTime.now();
System.out.println(offsetDateTime.toString());
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
System.out.println(zonedDateTime.toString());
// Use below way to find the applicable ZoneId for your requirement & other available zones
Set<String> ids = ZoneId.getAvailableZoneIds();
}
}
Output :
2018-03-13
12:20
2018-03-13T23:31:01.887
2018-03-13T23:31:01.887+05:30
2018-03-13T23:31:01.887+05:30[Asia/Kolkata]
===============================================================================================
Example 4 : To sort the objects on the basis of some property of those objects. Like shown below, will be sorting the Employee1 objects on the basis of the names of the employees. Below are a few ways to sort the objects of Employee1 or Employee2, you can try to use anyone depending on your requirements & if you have rights to make any change in the class to make necessary changes. Code is self-explanatory, if need any explanation then please let me know.
import java.util.Arrays;
public class Sample1 {
public static void main (String[] ar){
Employee1[] employees = {
new Employee1("David"),
new Employee1("Naveen"),
new Employee1("Alex"),
new Employee1("Richard")};
Employee2[] employees2 = {
new Employee2("David"),
new Employee2("Naveen"),
new Employee2("Alex"),
new Employee2("Richard")};
System.out.println("Before Sorting Names: "+Arrays.toString(employees));
Arrays.sort(employees, (Employee1 a1, Employee1 a2) -> {return a1.name.compareTo(a2.name);});
System.out.println("After Sorting Names "+Arrays.toString(employees));
Arrays.sort(employees, employees[0]::nameCompare);
System.out.println("After Sorting Names "+Arrays.toString(employees));
Arrays.sort(employees, employees[0]::staticNameCompare);
System.out.println("After Sorting Names "+Arrays.toString(employees));
System.out.println("Before Sorting Names: "+Arrays.toString(employees2));
Arrays.sort(employees2);
System.out.println("After Sorting Names "+Arrays.toString(employees2));
}
}
class Employee1 {
String name;
Employee1(String name) {
this.name = name;
}
public int nameCompare(Employee1 a1, Employee1 a2) {
return a1.name.compareTo(a2.name);
}
public int staticNameCompare(Employee1 a1, Employee1 a2) {
return a1.name.compareTo(a2.name);
}
public String toString() {
return name;
}
}
class Employee2 implements Comparable<Employee2>{
String name;
Employee2(String name) {
this.name = name;
}
public int compareTo(Employee2 a2) {
return this.name.compareTo(a2.name);
}
public String toString() {
return name;
}
}
Output :
Before Sorting Names: [David, Naveen, Alex, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
Before Sorting Names: [David, Naveen, Alex, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
===============================================================================================
For comparing & sorting the objects in the collections, & you want to use Java8 then look once the comparator API in Java8 & look below URL to get better understanding -
howtodoinjava.com/java-8/using-comparator-becomes-easier-with-lambda-expressions-java-8/
===============================================================================================
Important : If you have watched above videos then you know that usage of lambda functions reduces the creation of extra classes. While you create anonymous classes then extra classes are generated for those, like shown in below images & it is same as shown in above videos.
So if you compile the above class & check your bin folder to check the class files generated then you will find 2 extra classes created for the above 2 anonymous classes but no class file is generated for lambda functions above, so this way you have less files created.
===============================================================================================
Check the below 1 code snippet & see this 1 simple looking snippet give a important lesson about what is purily eager & what is not. So execute the code snippet & check its results & see on which line you see the exception first. Lambda is evaluated lazily so till we ask it to execute it doesn't, even it will not check if the reference given is null or not but method reference does check the reference if it is null or not.
So you will get the proof when you do commenting & uncommenting of various lines marked below & observe the results.
Check the below 1 code snippet & see this 1 simple looking snippet give a important lesson about what is purily eager & what is not. So execute the code snippet & check its results & see on which line you see the exception first. Lambda is evaluated lazily so till we ask it to execute it doesn't, even it will not check if the reference given is null or not but method reference does check the reference if it is null or not.
So you will get the proof when you do commenting & uncommenting of various lines marked below & observe the results.