Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ********* file in java 8 ***********
- Learn to use Java 8 APIs along with Files.list() and DirectoryStream to list all files present in a directory, including hidden files, recursively.
- 1. List all files and sub-directories using Files.list()
- Files.list() method to list all file names and sub-directories in current directory.
- Files.list(Paths.get("."))
- .forEach(System.out::println);
- Output:
- .\filename1.txt
- .\directory1
- .\filename2.txt
- .\Employee.java
- 2. List only files inside directory using filter expression
- You can use filters to filter out sub-directories and print only file names, if you need it.
- Files.list(Paths.get("."))
- .filter(Files::isRegularFile)
- .forEach(System.out::println);
- Output:
- .\filename1.txt
- .\filename2.txt
- .\Employee.java
- To list files in a different directory, we can replace "." with the full path of the directory we desire.
- 3. List files and sub-directories with Files.newDirectoryStream()
- Java provides a more flexible way of traversing a directory content using Files.newDirectoryStream().
- Please note that if we’re working with a large directory, then using DirectoryStream actually make code faster.
- Files.newDirectoryStream(Paths.get("."))
- .forEach(System.out::println);
- Output:
- .\filename1.txt
- .\directory1
- .\filename2.txt
- .\Employee.java
- 4. List only files with Files.newDirectoryStream()
- To list out only files and excluding all directories from stream, use path filter as second argument.
- Files.newDirectoryStream(Paths.get("."), path -> path.toFile().isFile())
- .forEach(System.out::println);
- Output:
- .\filename1.txt
- .\filename2.txt
- .\Employee.java
- 5. List files of certain extention with Files.newDirectoryStream()
- You can change the path filter expression passed in second argument to get files of certain extension only.
- Files.newDirectoryStream(Paths.get("."),
- path -> path.toString().endsWith(".java"))
- .forEach(System.out::println);
- Output:
- .\Employee.java
- 6. Find all hidden files in directory
- To find all hidden files, you can use filter expression file -> file.isHidden() in any of above example.
- Or you can use this shortcut method.
- final File[] files = new File(".").listFiles(file -> file.isHidden());
- //or
- final File[] files = new File(".").listFiles(File::isHidden);
- In above examples, we learn to use java 8 APIs list or iterate files in directory recursively on various search criteria. Feel free to modify the code and play with it.
- ********** write a file **********
- Java 8 example to content into file. You may find examples of reading files using java 8 APIs in linked blog post.
- 1. Java 8 write to file using BufferedWriter
- BufferedWriter is used to write text to a character or byte stream. Before printing the characters, it stores the characters in buffer and print in bunches. Without buffering, each invocation of a print() method would cause characters to be converted into bytes that would then be written immediately to the file, which can be very inefficient.
- Java program to write content to file using Java 8 APIs is –
- //Get the file reference
- Path path = Paths.get("c:/output.txt");
- //Use try-with-resource to get auto-closeable writer instance
- try (BufferedWriter writer = Files.newBufferedWriter(path))
- {
- writer.write("Hello World !!");
- }
- 2. Write to file using Files.write()
- Using Files.write() method is also pretty much clean code.
- String content = "Hello World !!";
- Files.write(Paths.get("c:/output.txt"), content.getBytes());
- ********** String to date **********
- 1) Convert string to date in ISO8601 format
- By default, java dates are in ISO8601 format, so if you have any string which represent date in ISO8601 format then you can use LocalDate.parse() or LocalDateTime.parse() methods directly.
- String armisticeDate = "2016-04-04";
- LocalDate aLD = LocalDate.parse(armisticeDate);
- System.out.println("Date: " + aLD);
- String armisticeDateTime = "2016-04-04T11:50";
- LocalDateTime aLDT = LocalDateTime.parse(armisticeDateTime);
- System.out.println("Date/Time: " + aLDT);
- Output:
- Date: 2016-04-04
- Date/Time: 2016-04-04T11:50
- 2) Convert string to date in custom formats
- If you have dates in some custom format, then you need to put additional logic to handle formatting as well using DateTimeFormatter.ofPattern().
- String anotherDate = "04 Apr 2016";
- DateTimeFormatter df = DateTimeFormatter.ofPattern("dd MMM yyyy");
- LocalDate random = LocalDate.parse(anotherDate, df);
- System.out.println(anotherDate + " parses as " + random);
- ********** join array and String **********
- Java examples to join string array to produce single String. This code can be used to convert array to string in Java. We may need this information many times during development specially while parsing contents out of JSON or XML.
- 1. Join String Array – Java 8 String.join()
- String.join() method has two overloaded forms.
- Join multiple string arguments
- This method takes all strings in var-args format and all strings are passed as argument in the method. The return string is received by appending all strings delimited by argument separator.
- Method Syntax
- String join(CharSequence delimiter, CharSequence... elements)
- This method can be used to join multiple strings which are not yet in form of collection or array.
- String Join Example
- String joinedString = String.join(", ", "How", "To", "Do", "In", "Java");
- System.out.println(joinedString);
- Output:
- How, To, Do, In, Java
- Join array or list of strings
- Method Syntax
- String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
- This method is used to join array of strings or list of strings.
- Java program to join list of strings
- Java program to join list of strings
- List<String> strList = Arrays.asList("How", "To", "Do", "In", "Java");
- String joinedString = String.join(", ", strList);
- System.out.println(joinedString);
- Output:
- How, To, Do, In, Java
- Java program to join array of strings
- Java program to join array of strings
- String[] strArray = { "How", "To", "Do", "In", "Java" };
- String joinedString = String.join(", ", strArray);
- System.out.println(joinedString);
- Output:
- How, To, Do, In, Java
- 2. Java 8 StringJoiner for formatted output
- Using StringJoiner class, we can produce formatted output of joined string. This is specially useful while using lambda collectors.
- 2.1. Method Syntax
- It’s constructor takes three arguments – delimiter [mandatory], and optionally prefix and suffix.
- StringJoiner(CharSequence delimiter)
- StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
- 2.2. StringJoiner Example
- Run the example with similar input as above example to join multiple strings. We want to format the output as [How, To, Do, In, Java], then we can use below code:
- StringJoiner joiner = new StringJoiner(", ", "[", "]");
- joiner.add("How")
- .add("To")
- .add("Do")
- .add("In")
- .add("Java");
- Output:
- [How, To, Do, In, Java]
- 3. String list of string with Collectors.joining()
- While using Java 8 lambda, we can use Collectors.joining() to convert list to String.
- List<String> numbers = Arrays.asList("How", "To", "Do", "In", "Java");
- String joinedString = numbers
- .stream()
- .collect(Collectors.joining(", ","[","]"));
- System.out.println(joinedString);
- Output:
- [How, To, Do, In, Java]
- 4. Join String Array using StringUtils.join()
- The StringUtils class of the Commons Langs library has several join() methods that can be used to combine an array or list of strings into a single string.
- 4.1. Maven Dependency
- pom.xml
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.7</version>
- </dependency>
- 4.2. StringUtils.join() Example
- See given examples. First we are joining string array with empty string. In second example, we are joining array with comma.
- String[] strArray = { "How", "To", "Do", "In", "Java" };
- String joinedString = StringUtils.join(strArray);
- System.out.println(joinedString);
- String joinedString2 = StringUtils.join(strArray, ", ");
- System.out.println(joinedString2);
- Output:
- HowToDoInJava
- How, To, Do, In, Java
- Use above given examples to concatenate string array with in Java.
- ********** extract arithmetic **********
- Java 8 has brought many awesome features for java developers. Some of them I have already described in Comparator changes, Streams examples, Internal vs. external iterations, predicates, functional interfaces, default methods, lambda expressions and date and time API changes. All above changes were related to lambda expressions, which is the most attention grabber and somehow game changer as well.
- Apart from above changes, we got non-lambda expression changes as well. I already discussed about String.join() method in previous post. In this post, I am discussing about changes done in Math class to support exact arithmetic.
- Sections in this post:
- 1) (add|substract|multiply|increment|decrement|negate)Exact methods
- 2) floorMod and floorDiv methods
- 3) toIntExact method
- 4) nextDown method
- Let’s discuss them one by one.
- 1) (add|substract|multiply|increment|decrement|negate)Exact methods
- The Math class provides these new methods which throws "java.lang.ArithmeticException" exception every-time the result of operation overflows to max limit. All above methods takes arguments as either int or long primitives.
- e.g. Consider multiplication of 100000 * 100000. Normally done, it will give you a wrong return “silently” and in application runtime it’s your responsibility to check every time the max limit to avoid wrong calculations.
- In java 8, multiPlyExact method will do the job for you and will throw the exception if result overflow the max limit.
- //Normal multiplication
- System.out.println( 100000 * 100000 );
- //Using multiPlyExact
- System.out.println( Math.multiplyExact( 100000 , 100000 ));
- Output:
- 1410065408 //Incorrect result
- Exception in thread "main" java.lang.ArithmeticException: integer overflow
- at java.lang.Math.multiplyExact(Math.java:867)
- at java8features.MathematicalFuctions.main(MathematicalFuctions.java:8)
- The same thing will happen with other operations as well. e.g. add operation vs. addExact
- //Normal add operation
- System.out.println( Integer.MAX_VALUE + Integer.MAX_VALUE );
- //Using addExact
- System.out.println( Math.addExact( Integer.MAX_VALUE , Integer.MAX_VALUE ));
- Output:
- -2 //incorrect result
- Exception in thread "main" java.lang.ArithmeticException: integer overflow
- at java.lang.Math.addExact(Math.java:790)
- at java8features.MathematicalFuctions.main(MathematicalFuctions.java:11)
- 2) floorMod and floorDiv methods
- Java 8 has worked to solve a very long standing problem of integer remainders. Everybody knows that expression n % 2 is
- i) 0 : if number is even
- ii) 1 : if is odd
- What if number is negative. Above expression can/cannot return -1. If fact for negative numbers, result is unpredictable to me.
- System.out.println( 10 % 2 );
- System.out.println( 11 % 2 );
- System.out.println( -15 % 2 );
- System.out.println( -16 % 2 );
- Output:
- 0
- 1
- -1
- 0
- Now do the above mod operation with exact mathematics came with java 8.
- System.out.println( Math.floorMod(10 , 2) );
- System.out.println( Math.floorMod(11 , 2) );
- System.out.println( Math.floorMod(-15 , 2) );
- System.out.println( Math.floorMod(-16 , 2) );
- Output:
- 0
- 1
- 1
- 0
- Similarly another problem can be a getting the position of a hour hand of a clock. Let’s say current time is 10 O’clock. You made adjustment of n hours and now want to get it’s position. Formula is simple:
- Current Position = (position + adjustment) % 12
- It will work good if (position + adjustment) is computed to position number. But what if hour hand moved anti-clockwise such that (position + adjustment) becomes negative. Let’s check.
- System.out.println( (10+3) % 12 );
- System.out.println( (5+6) % 12 );
- System.out.println( (10-27) % 12 );
- Output:
- 1
- 11
- -5 //This is incorrect
- Now use the exact airthmatic method floorMod.
- System.out.println( Math.floorMod(10+3 , 12) );
- System.out.println( Math.floorMod(5+6 , 12) );
- System.out.println( Math.floorMod(10-27 , 12) );
- Output:
- 1
- 11
- 7 //This is correct
- Similar changes has been done in floorDiv() method.
- 3) toIntExact method
- This method is handy when you are trying to assign a long value to int type variable. Though this situation does not arrive easily but it may be required in some rare cases. Normal long to int conversion with cause incorrect data if long value is more than max int value. toIntExact() method will throw the exception if something like this happened.
- System.out.println( Long.MAX_VALUE );
- System.out.println( (int)Long.MAX_VALUE );
- System.out.println( Math.toIntExact(10_00_00_000) );
- System.out.println( Math.toIntExact(Long.MAX_VALUE) );
- Output:
- 9223372036854775807
- -1
- 100000000
- Exception in thread "main" java.lang.ArithmeticException: integer overflow
- at java.lang.Math.toIntExact(Math.java:1011)
- at java8features.MathematicalFuctions.main(MathematicalFuctions.java:46)
- 4) nextDown method
- This is also a noticeable new addition in java 8 kit. This is very helpful when you have a situation where you want to return a number less than n. And the number you computed for returning happens to be exactly n. Then you can use this method to find a number closest to n, still less than n.
- System.out.println( Math.nextDown(100) );
- System.out.println( Math.nextDown(100.365) );
- Output:
- 99.99999
- 100.36499999999998
- Please note that Math.nextUp() already existed since java 6. Only Math.nextDown() is added in java 8.
- ************** comparator in lambda ****************
- Comparator is used when we want to sort a collection of objects which can be compared with each other. This comparison can be done using Comparable interface as well, but it restrict you compare these objects in a single particular way only. If you want to sort this collection, based on multiple criterias/fields, then you have to use Comparator only.
- Quick Reference:
- //Compare by Id
- Comparator<Employee> compareById_1 = Comparator.comparing(e -> e.getId());
- Comparator<Employee> compareById_2 = (Employee o1, Employee o2) -> o1.getId().compareTo( o2.getId() );
- //Compare by firstname
- Comparator<Employee> compareByFirstName = Comparator.comparing(e -> e.getFirstName());
- //how to use comparator
- Collections.sort(employees, compareById);
- 1) Overview
- To demo the concept, I am using class Employee with four attributes. We will use it to understand various use cases.
- public class Employee {
- private Integer id;
- private String firstName;
- private String lastName;
- private Integer age;
- public Employee(Integer id, String firstName, String lastName, Integer age){
- this.id = id;
- this.firstName = firstName;
- this.lastName = lastName;
- this.age = age;
- }
- //Other getter and setter methods
- @Override
- public String toString() {
- return "\n["+this.id+","+this.firstName+","+this.lastName+","+this.age+"]";
- }
- }
- Additionally I have written one method which always return a list of Employees in unsorted order.
- private static List<Employee> getEmployees(){
- List<Employee> employees = new ArrayList<>();
- employees.add(new Employee(6,"Yash", "Chopra", 25));
- employees.add(new Employee(2,"Aman", "Sharma", 28));
- employees.add(new Employee(3,"Aakash", "Yaadav", 52));
- employees.add(new Employee(5,"David", "Kameron", 19));
- employees.add(new Employee(4,"James", "Hedge", 72));
- employees.add(new Employee(8,"Balaji", "Subbu", 88));
- employees.add(new Employee(7,"Karan", "Johar", 59));
- employees.add(new Employee(1,"Lokesh", "Gupta", 32));
- employees.add(new Employee(9,"Vishu", "Bissi", 33));
- employees.add(new Employee(10,"Lokesh", "Ramachandran", 60));
- return employees;
- }
- 2) Sort by first name
- Basic usecase where list of employees will be sorted based on their first name.
- List<Employee> employees = getEmployees();
- //Sort all employees by first name
- employees.sort(Comparator.comparing(e -> e.getFirstName()));
- //OR you can use below
- employees.sort(Comparator.comparing(Employee::getFirstName));
- //Let's print the sorted list
- System.out.println(employees);
- Output: //Names are sorted by first name
- [
- [3,Aakash,Yaadav,52],
- [2,Aman,Sharma,28],
- [8,Balaji,Subbu,88],
- [5,David,Kameron,19],
- [4,James,Hedge,72],
- [7,Karan,Johar,59],
- [1,Lokesh,Gupta,32],
- [10,Lokesh,Ramachandran,60],
- [9,Vishu,Bissi,33],
- [6,Yash,Chopra,25]
- ]
- 3) Sort by first name – ‘reverse order’
- What if we want to sort on first name but in revered order. It’s really very easy; use reversed() method.
- List<Employee> employees = getEmployees();
- //Sort all employees by first name; And then reversed
- Comparator<Employee> comparator = Comparator.comparing(e -> e.getFirstName());
- employees.sort(comparator.reversed());
- //Let's print the sorted list
- System.out.println(employees);
- Output: //Names are sorted by first name
- [[6,Yash,Chopra,25],
- [9,Vishu,Bissi,33],
- [1,Lokesh,Gupta,32],
- [10,Lokesh,Ramachandran,60],
- [7,Karan,Johar,59],
- [4,James,Hedge,72],
- [5,David,Kameron,19],
- [8,Balaji,Subbu,88],
- [2,Aman,Sharma,28],
- [3,Aakash,Yaadav,52]]
- 4) Sort by last name
- We can use similar code to sort on last name as well.
- List<Employee> employees = getEmployees();
- //Sort all employees by first name
- employees.sort(Comparator.comparing(e -> e.getLastName()));
- //OR you can use below
- employees.sort(Comparator.comparing(Employee::getLastName));
- //Let's print the sorted list
- System.out.println(employees);
- Output: //Names are sorted by first name
- [[9,Vishu,Bissi,33],
- [6,Yash,Chopra,25],
- [1,Lokesh,Gupta,32],
- [4,James,Hedge,72],
- [7,Karan,Johar,59],
- [5,David,Kameron,19],
- [10,Lokesh,Ramachandran,60],
- [2,Aman,Sharma,28],
- [8,Balaji,Subbu,88],
- [3,Aakash,Yaadav,52]]
- 5) Sort on multiple fields – thenComparing()
- Here we are sorting list of employees first by their first name, and then sort again the list of last name. Just as we apply sorting on SQL statements. It’s actually a very good feature.
- Now you don’t need to always use sorting on multiple fields in SQL select statements, you can sort them in java as well.
- List<Employee> employees = getEmployees();
- //Sorting on multiple fields; Group by.
- Comparator<Employee> groupByComparator = Comparator.comparing(Employee::getFirstName)
- .thenComparing(Employee::getLastName);
- employees.sort(groupByComparator);
- System.out.println(employees);
- Output:
- [3,Aakash,Yaadav,52],
- [2,Aman,Sharma,28],
- [8,Balaji,Subbu,88],
- [5,David,Kameron,19],
- [4,James,Hedge,72],
- [7,Karan,Johar,59],
- [1,Lokesh,Gupta,32], //These both employees are
- [10,Lokesh,Ramachandran,60], //sorted on last name as well
- [9,Vishu,Bissi,33],
- [6,Yash,Chopra,25]
- 5) Parallel sort (with multiple threads)
- You can sort the collection of objects in parallel using multiple threads as well. It is going to be very fast if collection is big enough having thousands of objects. For small collection of objects, normal sorting is good enough and recommended.
- //Parallel Sorting
- Employee[] employeesArray = employees.toArray(new Employee[employees.size()]);
- //Parallel sorting
- Arrays.parallelSort(employeesArray, groupByComparator);
- System.out.println(employeesArray);
- Output:
- [3,Aakash,Yaadav,52],
- [2,Aman,Sharma,28],
- [8,Balaji,Subbu,88],
- [5,David,Kameron,19],
- [4,James,Hedge,72],
- [7,Karan,Johar,59],
- [1,Lokesh,Gupta,32], //These both employees are
- [10,Lokesh,Ramachandran,60], //sorted on last name as well
- [9,Vishu,Bissi,33],
- [6,Yash,Chopra,25]
- That’s all for using lambda with Comparator to sort objects. Please share with all of us if you know more techniques around this concept.
- ************* regrax as predicates ************
- Learn to compile regular expression into java.util.function.Predicate. This can be useful when you want to perform some operation on matched tokens.
- Convert Regex to Predicate
- I have list of emails with different domain and I want to perform some operation only on email ids with domain name “example.com”.
- Now use Pattern.compile().asPredicate() method to get a predicate from compiled regular expression. This predicate can be used with lambda streams to apply it on each token into stream.
- import java.util.Arrays;
- import java.util.List;
- import java.util.function.Predicate;
- import java.util.regex.Pattern;
- import java.util.stream.Collectors;
- public class RegexPredicateExample {
- public static void main(String[] args) {
- // Compile regex as predicate
- Predicate<String> emailFilter = Pattern
- .compile("^(.+)@example.com$")
- .asPredicate();
- // Input list
- List<String> emails = Arrays.asList("alex@example.com", "bob@yahoo.com",
- "cat@google.com", "david@example.com");
- // Apply predicate filter
- List<String> desiredEmails = emails
- .stream()
- .filter(emailFilter)
- .collect(Collectors.<String>toList());
- // Now perform desired operation
- desiredEmails.forEach(System.out::println);
- }
- }
- Output:
- alex@example.com
- david@example.com
- Using Regex using Pattern.matcher()
- If you want to use good old Pattern.matcher(), then use below code template.
- public static void main(String[] args)
- {
- Pattern pattern = Pattern.compile("^(.+)@example.com$");
- // Input list
- List<String> emails = Arrays.asList("alex@example.com", "bob@yahoo.com",
- "cat@google.com", "david@example.com");
- for(String email : emails)
- {
- Matcher matcher = pattern.matcher(email);
- if(matcher.matches())
- {
- System.out.println(email);
- }
- }
- }
- Output:
- alex@example.com
- david@example.com
- *************** join string *****************
- SO far till java 7, we had String.split() method which can split a string based on some token passed as parameter. It returned list of string tokens as string array. But, if you want to join a string or create a CSV by concatenating string tokens using some separator between them, you have to iterate through list of Strings, or array of Strings, and then use StringBuilder or StringBuffer object to concatenate those string tokens and finally get the CSV.
- String concatenation (CSV) with join()
- Java 8 made the task easy. Now you have String.join() method where first parameter is separator and then you can pass either multiple strings or some instance of Iterable having instances of strings as second parameter. It will return the CSV in return.
- package java8features;
- import java.time.ZoneId;
- public class StringJoinDemo {
- public static void main(String[] args){
- String joined = String.join("/","usr","local","bin");
- System.out.println(joined);
- String ids = String.join(", ", ZoneId.getAvailableZoneIds());
- System.out.println(ids);
- }
- }
- Output:
- usr/local/bin
- Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8.....
- So next time you use java 8 and want to concatanate the strings, you have a handy method in your kit. Use it.
Add Comment
Please, Sign In to add comment