Thursday, March 2, 2017

A Few Hidden Treasures in Java 8 --StringJoiner and String.join()

In day-to-day programming, it is quite common to join the Strings. Suppose if you have array or list elements. Let us say 
{“January”, February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} 
and you want to join them by comma to produce another String  
“JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER”
There is no easy way to do in java. Let us try with programmatically this.
import java.util.Arrays;
import java.util.List;
public class Manager {
 public static void main(String[] args) {
  List months = Arrays.asList("January", "February", "March", "April",
  "May", "June", "July", "August","September", "October", "November", "December");
  for(Object month:months){
   System.out.print(month.toString().toUpperCase() + ", ");
  }
 }
}
Output: JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER,
If you observe the output of the above program there is one stupid comma present in the output.
We need to iterate through array or list and then use a StringBuilder to append a comma after each element
and finally we need to remove the last comma because we don't want a comma after the last element
import java.util.Arrays;
import java.util.List;
public class Manager {
 public static String join(List list, String delimeter) {
  StringBuilder builder = new StringBuilder();
  boolean firstPosition = true;
  for (Object item : list) {
   if (firstPosition) {
    firstPosition = false;
   } else {
    builder.append(delimeter);
   }
   GUava.append(item.toString().toUpperCase());
  }
 return builder.toString();
}
 public static void main(String[] args) {
  List months = Arrays.asList("January", "February", "March", "April", 
  "May", "June", "July", "August","September", "October", "November", "December");
  System.out.println(join(months, ","));
 }
}
Output: JANUARY,FEBRUARY,MARCH,APRIL,MAY,JUNE,JULY,AUGUST,SEPTEMBER,OCTOBER,NOVEMBER,DECEMBER
Like Javascript Array.join() we dont have any readymade API in java before java 8 .We need to depend on 3rd party APIs like  Apache Commons ,Google Guava .Before going to discuss java 8 join method and String.join method will see few examples with Apache commons and Guava .

Apache commons StringUtils.join() method:

import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
public class Manager{
 public static void main(String[] args) {
  List months = Arrays.asList("January", "February", "March", "April",
 "May", "June", "July", "August", "September", "October", "November", "December");
  System.out.println(StringUtils.join(months, "|"));
 } 
}
Output:January|February|March|April|May|June|July|August|September|October|November|December
For more details about StringUtils.join() method, I'd really recommend taking a closer look: http://commons.apache.org/lang/api-3.1/org/apache/commons/lang3/StringUtils.html

Guava Joiner :

import java.util.Arrays;
import java.util.List;
import com.google.common.base.Joiner;
public class Manager{
 public static void main(String[] args) {
  List months = Arrays.asList("January", "February", "March", "April",
 "May", "June", "July", "August", "September", "October", "November", "December");
  System.out.println(Joiner.on(",").join(months));
 } 
}
For more details about Guava Joiner I'd really recommand taking a closer look : https://google.github.io/guava/releases/16.0/api/docs/index.html?com/google/common/base/Joiner.html

How to use String.join() method:

There are two overloaded join methods in String class,
public static String join(CharSequence delimiter,CharSequence... elements)
Returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter.
For example,
 String message = String.join("-", "Java", "is", "cool"); // message returned is: "Java-is-cool"
Note that if an element is null, then "null" is added.
Parameters:
delimiter - the delimiter that separates each element
elements - the elements to join together.
Returns: a new String that is composed of the elements separated by the delimiter
Throws: NullPointerException - If delimiter or elements is null

public static String join(CharSequence delimiter, Iterable elements)
Returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter.
For example,
 List strings = List.of("Java", "is", "cool");
 String message = String.join(" ", strings); //message returned is: "Java is cool"
 Set strings = new LinkedHashSet<>(List.of("Java", "is", "very", "cool"));
 String message = String.join("-", strings);//message returned is: "Java-is-very-cool"
Note that if an individual element is null, then "null" is added.
Parameters:
delimiter - a sequence of characters that is used to separate each of the elements in the resulting String
elements - an Iterable that will have its elements joined together.
Returns: a new String that is composed from the elements argument
Throws: NullPointerException - If delimiter or elements is null
Let's see Example for String.join() method
import java.util.Arrays;
import java.util.List;
public class Manager{
 public static void main(String[] args) {
  String join = String.join("|", "January", "February", "March", "April",
  "May", "June", "July", "August", "September", "October", "November", "December");
  System.out.println(join);
  List months = Arrays.asList("January", "February", "March", "April",
  "May", "June", "July", "August","September", "October", "November", "December");
  String joiner = String.join(",", months);
  System.out.println(joiner);
 }
}
OutPut:
January|February|March|April|May|June|July|August|September|October|November|December
January,February,March,April,May,June,July,August,September,October,November,December

How to use StringJoiner class in java:

StringJoiner is part of java.util packege.it is avaiable from java 8 onwards.
Here is what the new Java class says Here.
StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix.
There are two constructors available from StringJoiner class
public StringJoiner(CharSequence delimiter)
public StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
One is taking delimiter and other one allowing a prefix and suffix values .
import java.util.StringJoiner;
public class Manager {
 public static void main(String[] args) {
  StringJoiner joiner = new StringJoiner(",");
  String join = joiner.add("January").add("February").add("March")
    .add("April").add("May").toString();
  System.out.println(join);
 }
}
OutPut : January,February,March,April,May
import java.util.StringJoiner;
public class Manager {
 public static void main(String[] args) {
  StringJoiner joiner = new StringJoiner(",","[","]");
  String join = joiner.add("January").add("February").add("March")
    .add("April").add("May").toString();
  System.out.println(join);
 }
}
OutPut : [January,February,March,April,May]
Lets look at the StringJoiner methods once
public StringJoiner add(CharSequence newElement)
public StringJoiner merge(StringJoiner other)
public int length()
public String toString()
public StringJoiner setEmptyValue(CharSequence emptyValue)

But the real missing thing from the StringJoiner, A method to add multiple elements at once to the joiner. Every time i want to join,I have a list,set,or Iterable StringUtils from the comons lang or Guava or String.join() saperate methods.But it is missing from the StringJoiner.
String join = String.join(", ", list);
String join = Joiner.on(", ").join(list);
String join = StringUtils.join(list,",")
StringJoiner has no equivalent method. You have to add the elements one by one using add(CharSequence)!
StringJoiner joiner = new StringJoiner(", ");
 for (String str : list) {
   joiner.add(str);
 }
String join = joiner.toString();

Other why to join the String in java 8 using lambdas:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StringUtilsManager {
 public static void main(String[] args) {
  List months = Arrays.asList("January", "February", "March", "April",
  "May", "June", "July", "August", "September", "October", "November", "December");
  String join = months.stream()
 .map(String::toUpperCase)
 .collect(Collectors.joining(", "));
  System.out.println(join);
 }
}
Output: JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER

That's all about StringJoiner and String.join method in java 8.If your not using java 8 you can use 3rd party APIs like Guava,or Apache common lang (StringUtils.join) for the same purpose .
If you find any other ways to join the String please update your comments below .


No comments:

Post a Comment