StringJoiner vs StringBuffer vs Collectors.Joining() Performance Test

In this article we are sharing the program to identify which is the best performance provider out of StringJoiner, StringBuffer, StringBuilder and Collectors.joining() while joining/appending String.

import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.Collectors;
public class PerformanceTest {
	public static void main(String[] args) {
		List<String> l = new ArrayList<>();
		for(int i=0;i<1000;i++) {
			l.add("12345"+i);
		}
		long start = System.currentTimeMillis();
		usingStringJoiner(l);
		long middle = System.currentTimeMillis();
		System.out.println("Time taken by StringJoiner : "+(middle - start));
		usingStringBuffer(l);
		long end = System.currentTimeMillis();
		System.out.println("Time taken by StringBuffer : "+(end-middle));
		usingCollectors(l);
		long end1 = System.currentTimeMillis();
		System.out.println("Time taken by Collectors.joining() : "+(end1 - end));
		usingStringBuilder(l);
		System.out.println("Time taken by StringBuilder : "+(System.currentTimeMillis() - end1));
	}
	
	private static void usingStringJoiner(List<String> list) {
		StringJoiner sj = new StringJoiner("|");
		list.stream().filter(code -> code != null).forEach(code -> sj.add(code));
		String s = sj.toString();
		System.out.println(s);
	}
	
	private static void usingStringBuffer(List<String> list) {
		StringBuffer buf = new StringBuffer();
		list.stream().forEach(code -> buf.append(code).append("|"));
		String output = buf.toString();
		if (output.endsWith("|")) {
			output = output.substring(0, output.length() - 1);
		}
		System.out.println(output);
	}
	
	private static void usingCollectors(List<String> list) {
		String str = list.stream().collect(Collectors.joining("|"));
		System.out.println(str);
	}
	
	private static void usingStringBuilder(List<String> list) {
		StringBuilder builder = new StringBuilder();
		list.stream().forEach(code -> builder.append(code).append("|"));
		String output = builder.toString();
		if (output.endsWith("|")) {
			output = output.substring(0, output.length() - 1);
		}
		System.out.println(output);
	}
}

Time taken by StringJoiner : 49
Time taken by StringBuffer : 2
Time taken by Collectors.joining() : 4
Time taken by StringBuilder : 3

If you observe the above statistics of StringJoiner and Collectors.joining(), StringJoiners are taking 49 milliseconds to complete the task where Collectors.joining() is taking only 4 milliseconds which is 45 milliseconds lesser. Here one point I would like to bring to your notice is, StringJoiner is used in the implementation of joining() in Collections. But, when I use StringJoiner externally, it is taking more time than how joining() performing.

public static Collector<CharSequence, ?, String> joining(
CharSequence delimiter, CharSequence prefix, CharSequence suffix) {
    return new CollectorImpl<>(
            () -> new StringJoiner(delimiter, prefix, suffix),
            StringJoiner::add, StringJoiner::merge,
            StringJoiner::toString, CH_NOID);
}

StringJoiner internally uses StringBuilder to store value.

/*
 * StringBuilder value -- at any time, the characters constructed from the
 * prefix, the added element separated by the delimiter, but without the
 * suffix, so that we can more easily add elements without having to jigger
 * the suffix each time.
 */
private StringBuilder value;

/* preparing StringBuiler object in StringJoiner */
private StringBuilder prepareBuilder() {
  if (value != null) {
    value.append(delimiter);
  } else {
    value = new StringBuilder().append(prefix);
  }
  return value;
}

StringBuilder has been used across all the methods of StringJoiner to perform various operations. There is one more option of using StringUtils.join() method to perform similar operation. I would like to suggest to use StringBuffer than StringUtils because it internally uses the StringBuffer only to store value.

Advertisement

How InOut parameter will work in java?

Objective:
Objective of this article is to explain How references will work in java or How InOut parameter will work in Java?

Explanation:
We studied in C language the importance of  pointers similarly we need to know how references are working in java. Without knowing how object references are working in java, we cant understand application flow properly.

Lets take one example in java related to references as well as InOut parameter in java.

class Student{ 
     private Integer id; 
     private String name; 
     //setter and getter 
 } 
 class Main{ 
     public static void main(String arg…){ 
         Student s1=new Student(); 
         System.out.println(s1.getId()); 
         System.out.println(s1.getName()); 
         m1(s1); 
         System.out.println(s1.getId()); 
         System.out.println(s1.getName()); 
     } 
     public static void m1(Student s3){ 
         s3.setId(10); 
         s3.setName("ranga"); 
         s3=null;
     } 
 }

In the above program we used new keyword only one time so entire program will have only one student object created.

Once we create object s1 is pointing to that object and its id,name values initialize with null values like the below screenshot.

When we execute the below code, it will return with null value.

System.out.println(s1.getId());//null 
System.out.println(s1.getName());//null

When we call m1(s1); then Student s3=s1; then s3 reference also pointing to same object which is already referred by s1 reference. Look at the below image,

When we execute s3.setId(10); and s3.setName(“Ranga”); then s3 reference id value(null) override with 10 and name value(null) override with “Ranga”. Look at the below diagram,

When we do s3=null then it will lost the connection with that reference and m1 method execution is over because it doesn’t return anything because of it’s return type is void. Look at the below diagram,

The below diagram illustrates, that the previously setting s3 values are pointing to s1 because s3 lost connection with them.

Now it we print id and name of s1 reference, it will print id as 10 and name is “Ranga” because s1 is pointing to Student object which has the values of 10 and “Ranga”.

I hope this helped you to understand about references in Java. Let us know your thoughts. Happy Learning 🙂

Open browser with URL using Java program

Objective:
How to open browser with specific URL by using Java program? irrespective of Windows, Mac, Linux or Unix OS.

Introduction:
In this article we will learn how to write a program to open a browser with URL using Java program. First we need to find which OS we are running the program. This will help to run browser specific code on different OS. Also, this program gonna work in different Operating Systems like Windows, Mac, Linux and Unix. Below line of code will help to find the current OS,

String os = System.getProperty("os.name").toLowerCase();

Then we need to run the browser specific code based on identified OS.

For Windows:

Runtime rt = Runtime.getRuntime();
rt.exec("rundll32 url.dll, FileProtocolHandler " + url);

For Mac:

Runtime rt = Runtime.getRuntime();
rt.exec("open " + url);

For Linux/Unix:

Runtime rt = Runtime.getRuntime();
String[] browsers = { "epiphany", "firefox", "mozilla", "konqueror",
                                   "netscape", "opera", "links", "lynx" };

StringBuffer cmd = new StringBuffer();
for (int i = 0; i < browsers.length; i++) {
    if(i == 0)
       cmd.append(String.format("%s \"%s\"", browsers[i], url));
    else
       cmd.append(String.format(" || %s \"%s\"", browsers[i], url)); 
}
rt.exec(new String[] { "sh", "-c", cmd.toString() });

Look at the complete program in below

package com.tester.blog;

import java.io.IOException;

public class BrowserTest {
 static Runtime rt = Runtime.getRuntime();

 public static void main(String[] args) throws IOException {
  findOSAndOpenURL("https://www.javaisocean.com");
 }
 
 public static void findOSAndOpenURL(String url) throws IOException{
  String os = System.getProperty("os.name").toLowerCase();
  System.out.println("System OS running on : "+os);
  if(os.contains("windows")) 
    browseURLInWindows(url);
  else if(os.contains("mac"))
   browseURLInMac(url);
  else if(os.contains("unix") || os.contains("linux"))
   browseURLInLinux(url);
  else
   System.out.println("Not Found Matching OS");
 }

 public static void browseURLInWindows(String url) throws IOException{
  rt.exec("rundll32 url.dll, FileProtocolHandler " + url);
 }
 
 public static void browseURLInMac(String url) throws IOException{
  rt.exec("open " + url);
 }
 
 public static void browseURLInLinux(String url) throws IOException{
  String[] browsers = { "epiphany", "firefox", "mozilla", "konqueror",
                                   "netscape", "opera", "links", "lynx" };

  StringBuffer cmd = new StringBuffer();
  for (int i = 0; i < browsers.length; i++) {
      if(i == 0)
          cmd.append(String.format("%s \"%s\"", browsers[i], url));
      else
          cmd.append(String.format(" || %s \"%s\"", browsers[i], url)); 
  }
  rt.exec(new String[] { "sh", "-c", cmd.toString() });
 }
}