Java String - substring() Method Example

If you have to get a part of the original String i.e. substring in Java then you can use substring() method of the Java String class.

Java substring() method

There are two variants of the substring() method-

  • String substring(int beginIndex)- Returns a substring of this string where the substring begins with the character at the beginIndex and goes till the end of this string. Method throws IndexOutOfBoundsException if beginIndex is negative or larger than the length of this String object.
  • String substring(int beginIndex, int endIndex)- Returns a string that is a substring of this string. The substring begins at the specified beginIndex and ends at index endIndex - 1. IndexOutOfBoundsException is thrown if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.

    For this variant of substring() method remember that-

    • beginIndex- the beginning index, inclusive.
    • endIndex- the ending index, exclusive.

Java substring() method example

1. Using substring(int beginIndex) method to get a substring from the specified index.

public class SubStringExp {
  public static void main(String[] args) {
    String str = "This is a test String";
    String substr = str.substring(10);
    System.out.println("Substring is- " + substr);
  }
}
Output
Substring is- test String

Here extraction of substring starts from index 10 of the original string and extends till end of the String.

2- Using substring(int beginIndex, int endIndex) method to get a substring with in the given index range.

public class SubStringExp {
  public static void main(String[] args) {
    String str = "This is a test String";
    String substr = str.substring(10, 14);
    System.out.println("Substring is- " + substr);
  }
}
Output
Substring is- test

In the substring method, begin index is passed as 10 so extraction starts from that index. End index is 14 so extraction ends at index endIndex -1 = 13.

3- Using substring method along with other String class methods.

You can use substring method with other String class methods where start and end indices can be calculated using those methods. For example you have date in format dd-mm-yyyy and you want the year part then you can use lastIndexOf() method to get the start index for the substring() method to get the desired substring.

public class SubStringExp {
  public static void main(String[] args) {
    String str = "11-07-2019";
    String substr = str.substring(str.lastIndexOf('-') + 1);
    System.out.println("Substring is- " + substr);
  }
}
Output
Substring is- 2019

If you want to get the month part then you can use both indexOf() and lastIndexOf() methods to get the start index and end index respectively.

public class SubStringExp {
  public static void main(String[] args) {
    String str = "11-07-2019";
    String substr = str.substring(str.indexOf('-')+1, str.lastIndexOf('-'));
    System.out.println("Substring is- " + substr);
  }
}
Output
Substring is- 07

That's all for the topic Java String - substring() Method Example. If something is missing or you have something to share about the topic please write a comment.


You may also like

Search String in Another String in Java - indexOf, lastIndexOf, contains methods

If you want to check if given string is present in another string then in Java you have following options-

  1. Use indexOf() method to find the first occurrence of the specified character or substring. See example.
  2. Use lastIndexOf() method to get index within this string of the last occurrence of the specified character or substring. See example.
  3. Using contains() method in Java you can check if this string contains the specified substring or not. Returns true if substring is found false otherwise. See example.

Note that all of these methods do a case sensitive search so you may need to convert String and substring to similar case (lower or upper case) if you don’t want case to be a factor while searching.

Searching String using indexOf() method in Java

indexOf() method of the Java String class has 4 variants, two are used to search specified character and two are used to search specified substring.

  • int indexOf(int ch)- If found returns the index within this string of the first occurrence of the specified character, otherwise returns -1.
  • int indexOf(int ch, int fromIndex)- If found returns the index within this string of the first occurrence of the specified character, starting the search at the specified index. Returns -1 if character is not found.
  • int indexOf(String str)- If found returns the index within this string of the first occurrence of the specified substring, otherwise returns -1.
  • int indexOf(String str, int fromIndex)- If found returns the index within this string of the first occurrence of the specified substring, starting at the specified index. Returns -1 if substring is not found.
Searching for character in a string using indexOf() example
public class StringSearch {
  public static void main(String[] args) {
    String str = "This is a test String";
    // Search for first occurrence
    int index = str.indexOf('s');
    System.out.println("First occurrence of character 's' found at index " + index);
    // Search for first occurrence after specified index
    index = str.indexOf('s', 11);
    System.out.println("First occurrence of character 's' after index 11 found at index " + index);
  }
}
Output
First occurrence of character 's' found at index 3
First occurrence of character 's' after index 11 found at index 12
Searching for substring in a string using indexOf() Java example
public class StringSearch {
  public static void main(String[] args) {
    String str = "This is a test String";
    // Search for first occurrence
    int index = str.indexOf("test");
    if(index != -1) {
      System.out.println("First occurrence of substring test found at index " + index);
    }else {
      System.out.println("Substring not found ");
    }
    
    // Search for first occurrence after specified index
    index = str.indexOf("test", 6);
    System.out.println("First occurrence of substring test after index 6 found at index " + index);
  }
}
Output
First occurrence of substring test found at index 10
First occurrence of substring test after index 6 found at index 10

Searching String using lastIndexOf() method in Java

lastIndexOf() method of the Java String class has 4 variants, two are used to search specified character and two are used to search specified substring.
  • int lastIndexOf(int ch)- If found returns the index within this string of the last occurrence of the specified character, otherwise returns -1.
  • int lastIndexOf(int ch, int fromIndex)- If found returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index. Returns -1 if character is not found.
  • int lastIndexOf(String str)- If found returns the index within this string of the last occurrence of the specified substring, otherwise returns -1.
  • int lastIndexOf(String str, int fromIndex)- If found returns the index within this string of the last occurrence of the specified substring, searching backward at the specified index. Returns -1 if substring is not found.
Searching for character in a string using lastIndexOf() example
public class StringSearch {
  public static void main(String[] args) {
    String str = "This is a test String";
    // Search for last occurrence
    int index = str.lastIndexOf('s');
    System.out.println("Last occurrence of character 's' found at index " + index);
    // Search for last occurrence after specified index
    index = str.lastIndexOf('s', 11);
    System.out.println("Last occurrence of character 's' moving backward from index 11 found at index " + index);
  }
}
Output
Last occurrence of character 's' found at index 12
Last occurrence of character 's' moving backward from index 11 found at index 6
Searching for substring in a string using lastIndexOf() example
public class StringSearch {
  public static void main(String[] args) {
    String str = "test String to test";
    // Search for last occurrence
    int index = str.lastIndexOf("test");
    if(index != -1) {
      System.out.println("Last occurrence of substring test found at index " + index);
    }else {
      System.out.println("Substring not found ");
    }		
    // Search for last occurrence after specified index
    index = str.lastIndexOf("test", 6);
    System.out.println("Last occurrence of substring test moving backward from index 6 found at index " + index);
  }
}
Output
Last occurrence of substring test found at index 15
Last occurrence of substring test moving backward from index 6 found at index 0

Searching String using contains() method in Java

  • boolean contains(CharSequence s)- Returns true if and only if this string contains the specified sequence of char values, false otherwise.
CharSequence is an interface which is implemented by String, StringBuffer and StringBuilder so objects of these classes can be passed with contains() method.
public class StringSearch {
  public static void main(String[] args) {
    String str = "This is a test String";
    String str1= "test";
    if(str.contains(str1)) {
      System.out.println(str1 + " found in String");
    }else {
      System.out.println(str1 + "is not found in String");
    }
  }
}
Output
test found in String
If you do a search for “Test” false is returned as the search is case sensitive.
public class StringSearch {
  public static void main(String[] args) {
    String str = "This is a test String";
    String str1= "Test";
    if(str.contains(str1)) {
      System.out.println(str1 + " found in String");
    }else {
      System.out.println(str1 + " is not found in String");
    }
  }
}
Output
Test is not found in String

That's all for the topic Search String in Another String in Java - indexOf, lastIndexOf, contains methods. If something is missing or you have something to share about the topic please write a comment.


You may also like

Java String length() Method With Examples

To find length of a String you can use length() method of the Java String class. This method returns the count of characters in the String object including spaces.

Java String length() method examples

1. In the examples there are two strings and length of those String is calculated using length() method.

public class StringLength {
  public static void main(String[] args) {
    String str1 = "String length method";
    //separated by 4 spaces
    String str2 = "Hello    World";
    System.out.println("Length of str1- " + str1.length());
    System.out.println("Length of str2- " + str2.length());
  }
}
Output
Length of str1- 20
Length of str2- 14

2- Printing each character by iterating a String, using String’s length() method to limit the iteration.

public class StringLength {
  public static void main(String[] args) {
    String str = "Hello";
    for(int i = 0; i < str.length(); i++) {
      System.out.println(str.charAt(i));
    }
  }
}
Output
H
e
l
l
o

That's all for the topic Java String length() Method With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Why String is Immutable in Java

String in Java is immutable that brings us to the question why this decision to design String class as immutable. In this post we’ll see some of the reasons for this design decision.

Java String objects are immutable

Java String class is immutable which means once a String object is created it cannot be changed. When you use a String modification method like concatenation what actually happens is that a new String is created and returned that contains the result of the operation.

For example suppose there is String str-

String str = “Hello”;

That means str refers to the memory location where value "Hello" is stored.

String immutability

Now if you concatenate another value to this String and assign it to the same reference. Since original string can’t be modified because of String being immutable so this concatenation means a new String object is created with the modified value and str starts pointing to this new object.

str = str.concat(" World");
Java String immutable

As you can see str now refers to the modified object and old object is unreferenced and ready to be garbage collected.

Here is another example where concatenation is done but the returned modified string is not assigned to any variable.

public class StringLiteral {
  public static void main(String[] args) {
    String str = "Hello";
    str.concat(" World");
    System.out.println("Value- " + str);
  }
}
Output
Value- Hello

As you can see str is still referring to the original String object.

Why is String immutable in Java

Now when we have seen with examples, what does String is immutable actually means let’s go through the why part.

1- Reduce memory usage- To understand how does String being immutable results in reduced memory usage you’ll have to understand String pool in Java.

String is a special class in Java and also one of the most used too. That is why the concept of constant String pool is used to minimize memory usage.

Whenever any String literal is created (String enclosed in double quotes) JVM scans the String pool for any String having the same value, if found same reference is returned. So, new memory is not allocated for the same string, existing memory is used instead.

Let’s understand with an example. if three Strings are created as follows-

String str1 = “Hello”;
String str2 = “Hello”;
String str3 = “Hello”;

Then the same memory is referenced by all the three objects.

String Java

Now suppose the value of str1 is changed, if the original string itself is changed then what about the other two references. They will also start pointing to the changed value which is not correct. That is why making String immutable ensures that original object can’t be modified.

Pooling strings is possible because of String in Java being immutable and that is how this property contributes in reduced memory usage by Strings.

2- Thread safety- String in Java is immutable so that it can’t be modified once created which in turn means Strings are safe to be used in a multi-threaded environment with out any fear of change.

If a thread changes the value of the shared string even then a new String is created leaving the original as unchanged.

3- Hashcode caching- Another reason that can be given for why String is immutable in Java is that it enables hashcode to be cached for Strings.

Since string once created can’t be modified so the hashcode once calculated for any string can be cached and reused. It is not required to recalculate that hashcode. That makes it very efficient to use String as a key in a hash based data structure like HashMap.

That's all for the topic Why String is Immutable in Java. If something is missing or you have something to share about the topic please write a comment.
You may also like

Is Java String Thread Safe

In a multi-threaded environment shared object can be modified by any of the thread, in some scenarios you may want to ensure that the original object shared among the threads remain unchanged. That can be done by making that object immutable. Since String in Java is immutable by design so it is also thread safe thus a string object can be shared safely among many threads.

Java String immutability and thread safety

One important point to note is that even if String is immutable thus thread safe, reference to the String object is not thread safe.

If String object is passed to a thread and it is modified with in the thread then a new String is created and the reference is changed but the original String remains unchanged. We’ll clear this point with an example.

In the example string object is shared among three threads. While executing these threads, shared string object is modified by appending content to it. When all the threads are finished string object is printed again in the main thread to verify that it remains unchanged.

public class StringThreadSafeExp implements Runnable {
  private String str;
  public StringThreadSafeExp(String str){
    this.str = str;
  }
  @Override
  public void run() {
    System.out.println("Executing Thread- " + Thread.currentThread().getName());        
    // Adding to String  
    str = str + " World";
    System.out.println("Modified String " + str);
  }

  public static void main(String[] args) {
    String str = "Hello";

    Thread t1 = new Thread(new StringThreadSafeExp(str));
    Thread t2 = new Thread(new StringThreadSafeExp(str));
    Thread t3 = new Thread(new StringThreadSafeExp(str));
    t1.start();
    t2.start();
    t3.start();
    // Wait for all threads to terminate
    try {
      t1.join();
      t2.join();
      t3.join();
    } catch (InterruptedException e) {    
      e.printStackTrace();
    }
    System.out.println("Original String is " + str);
  }
}
Output
Executing Thread- Thread-2
Executing Thread- Thread-1
Executing Thread- Thread-0
Modified String Hello World
Modified String Hello World
Modified String Hello World
Original String is Hello

As you can see each of thread, when it modifies the passed String gets reference to a new String object pointing to modified content, leaving the original string unchanged.

Immutability of Java String ensures that String once assigned a value can’t be modified. By using a StringBuffer object which is mutable you can verify what happens when a mutable object is shared among threads and modified.

public class StringThreadSafeExp implements Runnable {
  private StringBuffer sb;
  public StringThreadSafeExp(StringBuffer sb){
    this.sb = sb;
  }
  @Override
  public void run() {
    System.out.println("Executing Thread- " + Thread.currentThread().getName());        
    // Adding to String  
    sb.append(" World");
    System.out.println("Modified String " + sb);
  }

  public static void main(String[] args) {
    StringBuffer sb = new StringBuffer("Hello");

    Thread t1 = new Thread(new StringThreadSafeExp(sb));
    Thread t2 = new Thread(new StringThreadSafeExp(sb));
    Thread t3 = new Thread(new StringThreadSafeExp(sb));
    t1.start();
    t2.start();
    t3.start();
    // Wait for all threads to terminate
    try {
      t1.join();
      t2.join();
      t3.join();
    } catch (InterruptedException e) {    
      e.printStackTrace();
    }
      System.out.println("Original String is " + sb);
  }
}
Output
Executing Thread- Thread-0
Executing Thread- Thread-2
Executing Thread- Thread-1
Modified String Hello World World
Modified String Hello World
Modified String Hello World World World
Original String is Hello World World World

As you can see now the original StringBuffer object itself is modified as it is mutable.

That's all for the topic Is Java String Thread Safe. If something is missing or you have something to share about the topic please write a comment.


You may also like

Constant String Pool in Java

When a String object is created using string literal (value enclosed in double quotes) that String object is created in a part of memory known as constant string pool in Java. In this tutorial you’ll learn what is string pool in Java and how it optimizes memory when Strings are created.

For another feature added to make String in Java more space efficient check this post- Compact Strings in Java 9

Java constant String pool

There are two ways to create a String in Java-

  • Using String literal
  • Using new keyword

When you create a String using String literal, for example

String str = “hello”

Memory for this string is created in a memory area knows as string pool in Java. This String pool is part of the heap memory.

String pool Java

Now the question is why this String pool is required and how it optimizes memory usage? String is a special class in Java and one of the most used too. That is why the concept of constant String pool is used to minimize memory usage.

Whenever any String literal is created JVM scans the String pool for any String having the same value, if found same reference is returned. So, new memory is not allocated for the same string, existing memory is used instead.

Let’s understand with an example. if two Strings are created as follows-

String str1 = “Hello”;
String str2 = “Hello”;

Then the same memory is referenced by both the objects.

String pool in Java

You can also verify it using a Java program. In the example two Strings are created using string literals and then their references are compared using equality '==' operator.

public class StringLiteral {
  public static void main(String[] args) {
    String str1 = "Hello";
    String str2 = "Hello";
    // checking if memory reference is same
    if(str1 == str2){
      System.out.println("str1 and str2 are pointing to same memory reference");
    }else{
      System.out.println("str1 and str2 are not pointing to same memory reference");
    }
  }
}
Output
str1 and str2 are pointing to same memory reference

This efficient usage of memory through String pool is possible only because String is immutable in Java.

Creating String using new operator

When a String instance is created using new operator, memory for the new instance is created on the heap rather than in the String pool.

For example if three Strings are created as follows-

String str1 = “Hello”;
String str2 = “Hello”;
String str3 = new String(“Hello”);

str1 and str2 share the same reference in the constant string pool where as str3 references to a memory location on the heap.

Java String instance

You can also verify it using a Java program. In the example three Strings are created, two using string literals and one using new operator. Their references are compared using equality ‘==’ operator.

public class StringLiteral  {
  public static void main(String[] args) {
    String str1 = new String("Hello");
    String str2 = "Hello";
    String str3 = "Hello";
    // instance and literal
    if(str1 == str2) {
      System.out.println("str1 and str2 are pointing to same memory reference");
    }else{
      System.out.println("str1 and str2 are not pointing to same memory reference");
    }
    // instance and literal
    if(str1 == str3) {
      System.out.println("str1 and str3 are pointing to same memory reference");
    }else{
      System.out.println("str1 and str3 are not pointing to same memory reference");
    }
    // literal and literal
    if(str2 == str3) {
      System.out.println("str2 and str3 are pointing to same memory reference");
    }else{
      System.out.println("str2 and str3 are not pointing to same memory reference");
    }
  }
}
Output
str1 and str2 are not pointing to same memory reference
str1 and str3 are not pointing to same memory reference
str2 and str3 are pointing to same memory reference

If two instances having same value are created using new operator even then these two objects will be allocated different memory.

public class StringLiteral  {
  public static void main(String[] args) {
    String str1 = new String("Hello");
    String str2 = new String("Hello");
    if(str1 == str2) {
      System.out.println("str1 and str2 are pointing to same memory reference");
    }else{
      System.out.println("str1 and str2 are not pointing to same memory reference");
    }
  }
}
Output
str1 and str2 are not pointing to same memory reference

Java String interning

This process of sharing the memory is called interning in Java. In Java, string literals are "interned" so as to share unique instances, using the String.intern method. For String literals this process is implicit.

Explicitly using intern method

You can also intern a String by explicitly using intern method. That way you can even use the String pool for Strings created using new operator.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

public class StringLiteral  {
  public static void main(String[] args) {
    String str1 = "Hello";
    String str2 = new String("Hello");
    // created using intern
    String str3 = new String("Hello").intern();
    // str3 = str2.intern(); can be created this way too
    if(str1 == str2) {
      System.out.println("str1 and str2 are pointing to same memory reference");
    }else{
      System.out.println("str1 and str2 are not pointing to same memory reference");
    }
    
    if(str1 == str3) {
      System.out.println("str1 and str3 are pointing to same memory reference");
    }else{
      System.out.println("str1 and str3 are not pointing to same memory reference");
    }
    
    if(str2 == str3) {
      System.out.println("str2 and str3 are pointing to same memory reference");
    }else{
      System.out.println("str2 and str3 are not pointing to same memory reference");
    }
  }
}
Output
str1 and str2 are not pointing to same memory reference
str1 and str3 are pointing to same memory reference
str2 and str3 are not pointing to same memory reference

As you can see String str3 is created using intern method so it will use the String pool. Since there is already a String with same value in the pool so str3 uses the same reference that is why str1 and str3 have the same reference.

That's all for the topic Constant String Pool in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

Java StringJoiner Class With Method Examples

In Java 8 a new class StringJoiner has been added that can be used for joining the Strings using the specified delimiter. There is also an option to pass prefix and suffix to be added to the final joined String.

Read Also: Java String join() Method With Examples

Java StringJoiner class constructors

  • StringJoiner(CharSequence delimiter)- Constructs a StringJoiner with no characters in it, with no prefix or suffix, and a copy of the supplied delimiter.
  • StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix)- Constructs a StringJoiner with no characters in it using copies of the supplied prefix, delimiter and suffix.

Java StringJoiner examples

1. Constructing a String with colon ":" as delimiter.

public class JoinStrings {
  public static void main(String[] args) {
    // Specifying delimiter 
    StringJoiner sj = new StringJoiner(":");
    // adding values
    sj.add("Java");
    sj.add("Python");
    sj.add("Scala");
    System.out.println("Final String- " + sj.toString());
  }
}
Output
Final String- Java:Python:Scala

2. Constructing a String with colon "|" as delimiter, “[“ and “]” as prefix and suffix.

public class JoinStrings {
  public static void main(String[] args) {
    // Specifying delimiter and prefix, suffix 
    StringJoiner sj = new StringJoiner("|", "[", "]");
    // adding values
    sj.add("Java");
    sj.add("Python");
    sj.add("Scala");
    System.out.println("Final String- " + sj.toString());
  }
}
Output
Final String- [Java|Python|Scala]

Java StringJoiner methods

  • add(CharSequence newElement)- Adds a copy of the given CharSequence value as the next element of the StringJoiner value.
  • length()- Returns the length of the String representation of this StringJoiner.
  • merge(StringJoiner other)- Adds the contents of the given StringJoiner without prefix and suffix as the next element if it is non-empty.
  • setEmptyValue(CharSequence emptyValue)- Sets the sequence of characters to be used as default when it is empty.
  • toString()- Returns the current value as String

StringJoiner methods – setEmptyValue example

public class JoinStrings {
  public static void main(String[] args) {
    // Specifying delimiter and prefix, suffix 
    StringJoiner sj = new StringJoiner("|", "[", "]");
    System.out.println("Final String- " + sj.toString());
    //Default String
    sj.setEmptyValue("Default String");
    System.out.println("Final String- " + sj.toString());
    // adding values
    sj.add("Java");
    sj.add("Python");
    sj.add("Scala");
    System.out.println("Final String- " + sj.toString());
  }
}
Output
Final String- []
Final String- Default String
Final String- [Java|Python|Scala]

As you can see when a default String is added using setEmptyValue() method that is displayed. When elements are added using add() method then those values are displayed.

StringJoiner methods – merge example

public class JoinStrings {
  public static void main(String[] args) {
    // Specifying delimiter and prefix, suffix 
    StringJoiner sj1 = new StringJoiner("|", "[", "]");
    StringJoiner sj2 = new StringJoiner("-", "(", ")");
    // adding values
    sj1.add("Java");
    sj1.add("Python");
    sj1.add("Scala");
    System.out.println("StringJoiner 1- " + sj1.toString());
    sj2.add("Golang");
    sj2.add("Kotlin");
    sj2.add("Clojure");
    System.out.println("StringJoiner 2- " + sj2.toString());
    // merging sj2 to sj1
    sj1.merge(sj2);
    System.out.println("Merged String- " + sj1.toString());
    System.out.println("Merged String length- " + sj1.length());
  }
}
Output
StringJoiner 1- [Java|Python|Scala]
StringJoiner 2- (Golang-Kotlin-Clojure)
Merged String- [Java|Python|Scala|Golang-Kotlin-Clojure]
Merged String length- 41

When the StringJoiner objects are merged, if the other StringJoiner is using a different delimiter, then elements from the other StringJoiner are concatenated with that delimiter. Prefix and suffix of the StringJoiner object that is passed as parameter are discarded, delimiter of the calling StringJoiner are used.

That's all for the topic Java StringJoiner Class With Method Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Java StringBuilder With Method Examples

StringBuilder in Java is a mutable sequence of characters which means using this class you can create mutable strings (String that can be modified). The API provided by StringBuilder class is compatible with StringBuffer with one noticeable difference, with StringBuilder there is no guarantee of synchronization.

When StringBuffer is being used by a single thread it is recommended that StringBuilder be used instead of StringBuffer as it will be faster as there is no synchronization overhead.

Why is StringBuilder class required

You may be wondering why is StringBuilder or StringBuffer class required when String class is already there with an extensive API.

In the post String in Java we have already seen that String objects are immutable and their values cannot be changed after they are created. Because of this immutability property when you use a String modification method like concatenation what actually happens is that a new String is created and returned that contains the result of the operation. That may lead to creation of lots of intermediate String objects if String is modified several times which in turn means more memory being used for these intermediate objects.

Using StringBuilder or StringBuffer you can avoid this problem of creating several objects as these classes are mutable.

Important points about Java StringBuilder

Some of the important points about StringBuilder class.

  1. StringBuilder in Java provides much of the functionality of String class with one prominent deviation that StringBuilder is mutable.
  2. StringBuilder has an API compatible with StringBuffer except one design difference StringBuilder is not synchronized so it is not thread safe like StrinBuffer.
  3. Every StringBuilder is created with a capacity. As long as the length of the character sequence contained in the string builder does not exceed the capacity, it is not necessary to allocate a new internal buffer. If the internal buffer overflows, it is automatically made larger.

Java StringBuilder Constructors

There are four constructors in StringBuilder class.

  1. StringBuilder()- Constructs an empty string builder and an initial capacity of 16 characters.
    StringBuilder sb = new StringBuilder();
  2. StringBuilder(int capacity)- Constructs a string builder with no characters in it and an initial capacity specified by the capacity argument.
    StringBuilder sb = new StringBuilder(30);
  3. StringBuilder(CharSequence seq)- Constructs a string builder that contains the same characters as the specified CharSequence. Here CharSequence is an interface which is implemented by CharBuffer, Segment, String, StringBuffer, StringBuilder.
  4. StringBuilder(String str)- Constructs a string builder initialized to the contents of the specified string.
    StringBuilder sb = new StringBuilder("Hello");

Java StringBuilder method examples

append method

append method in StringBuilder class is overloaded so as to accept data of any type. This method appends the string representation of the given data type to existing buffer. The append method always adds these characters at the end of the buffer.

public class StringLiteral  {
  public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("Hello");
    sb.append(" ");
    //chaining several appends
    sb.append("World").append(" ").append(123);
    System.out.println("Appended String- " + sb.toString());
  }
}
Output
Appended String- Hello World 123

As you can see from the example append is used with both String and int as argument as it is overloaded for these data types. You can also chain several append methods as done in the example.

insert method

insert method is also overloaded in StringBuilder class so as to accept data of any type. This method is used to insert the string representation of the given data type to existing buffer. The insert method adds the characters at a specified point.

insert method takes two arguments first an integer indicating the position where characters are to be inserted in the buffer and second argument is the text to be inserted.

public class StringLiteral  {
  public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("Hello");
    sb.insert(5, " World");
    System.out.println("String after insert- " + sb);
  }
}
Output
String after insert- Hello World
length and capacity methods
  • capacity()- Returns the current capacity of the StringBuilder.
  • length()- Returns the number of characters in this sequence.
public class StringLiteral  {
  public static void main(String[] args) {
    StringBuilder sb = new StringBuilder(30);
    sb.append("Hello");
    System.out.println("Capacity of StringBuilder- " + sb.capacity());
    System.out.println("Length of StringBuilder- " + sb.length());
  }
}
Output
Capacity of StringBuilder- 30
Length of StringBuilder- 5

Here you can see that StringBuilder is created with the capacity as 30 so the capacity is displayed as 30 where as number of characters in the buffer is 5 so the length is displayed as 5.

reverse method
  • reverse()- Reverses the existing StringBuilder.
public class StringLiteral  {
  public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("Hello");
    System.out.println("Reversed- " + sb.reverse());
  }
}
Output
Reversed- olleH
replace method
  • replace(int start, int end, String str)- Replaces the characters in a substring of this sequence (start to end-1) with characters in the specified String.
public class StringLiteral  {
  public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("Hello");
    sb.replace(3, 5, "ena");
    System.out.println("String- " + sb);
  }
}
Output
String- Helena
delete and deleteCharAt methods
  • delete(int start, int end)- Removes the characters in a substring of this sequence. start which indicates the beginning index is inclusive where as end which indicates the ending index is exclusive.
  • deleteCharAt(int index)- Removes the char at the specified position in this sequence.
public class StringLiteral  {
  public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("Hello");
    sb.delete(1, 3);
    System.out.println("After deletion- " + sb);
    System.out.println("Length of StringBuilder- " + sb.length());
  }
}
Output
After deletion- Hlo
Length of StringBuilder- 3
public class StringLiteral  {
  public static void main(String[] args) {
    StringBuilder sb = new StringBuilder("Hello");
    sb.deleteCharAt(4);
    System.out.println("After deletion- " + sb);
    System.out.println("Length of StringBuilder- " + sb.length());
  }
}
Output
After deletion- Hell
Length of StringBuilder- 4

Reference: https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/StringBuilder.html

That's all for the topic Java StringBuilder With Method Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

React Fragments With Examples

In this tutorial we'll see what is React.Fragment and how to use it.

Why React Fragment

When you write a React component there is a constraint that the JSX expression the component will render should always be wrapped with in a single parent element. Which means trying to write a component as given below results in an error.

const HelloWorld = (props) => {
  return (
    <h2>{props.title}</h2>
    <p>{props.message.greeting} {props.message.name}</p>
  );
}

The error you get for this component will be something like this-

Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?

Most frequently <div> is used as a wrapper in such scenarios.

const HelloWorld = (props) => {
  return (
    <div>
      <h2>{props.title}</h2>
      <p>{props.message.greeting} {props.message.name}</p>
    </div>
  );
}

If I run this code and inspect it-

div as wrapper

With the React.Fragment you can get away with using such a wrapper when you need to return multiple elements. Here is the same component written using Fragment.

const HelloWorld = (props) => {
  return (
    <React.Fragment>
      <h2>{props.title}</h2>
      <p>{props.message.greeting} {props.message.name}</p>
    </React.Fragment>
  );
}

With that if you inspect the element, you can see that there is no wrapper now.

React.Fragment

React Fragment Usage

You may think what is the big deal? All Fragment did was to remove one extra <div>. Here are some reasons which should tell you the importance of React Fragments.

  1. With a big hierarchy when you break a component into several small components it does become a big deal actually. With using <div> as a wrapper you may end up with the rendered DOM having lot of nested <div> elements which are there just to wrap the elements rendered by the component. React.Fragment gives you a chance to get rid of such nested <div> elements.
  2. By removing such extra <div> elements, React.Fragment helps you in writing semantically correct HTML.
  3. Also helps you in shortening your rendered code which in turn takes less memory.

Here are few examples where you end up writing semantically wrong HTML because of this constraint of wrapping JSX elements.

1. Suppose you want to show some data in a table and you break that code into two components Table and Columns.

Table.js
import Columns from "./Columns";
const Table = () => {
  return (
    <table>
      <tr><Columns></Columns></tr>
    </table>
  )
}
export default Table;
Columns.js
const Columns = () => {
  return (
    <div>
      <td>First Column</td>
      <td>Second Column</td>
    </div>
  )
}

export default Columns;

Here you can see that <div> is used to wrap multiple <td> elements. With that you get <div> in between <tr> and <td> which is not semantically correct HTML.

By using Fragment you can get rid of this unnecessary div.

<React.Fragment>
  <td>First Column</td>
  <td>Second Column</td>
</React.Fragment>
React Fragment example

2. In this another example we have to show a list of products. There are separate components for Products and ProductItems.

Products.js
import ProductItem from "./ProductItem";

const INIT_PRODUCT_CATALOG = [
  { id: 1, name: 'Laptop', price: 455.50 },
  { id: 2, name: 'Mouse', price: 15.89 },
  { id: 3, name: 'USB', price: 10.00 },
  { id: 4, name: 'HDD', price: 55.50 },
];
const Products = () => {
  return (
    <ul>
      {INIT_PRODUCT_CATALOG.map((val, key) => <ProductItem key={key} item={val} />)}
    </ul>
  );
}

export default Products;
ProductItem.js
const ProductItem = (props) => {
  return (
    <div>
      <li>------Next Product--------</li>
      <li>{props.item.id}</li>
      <li>{props.item.name}</li>
      <li>{props.item.price}</li>
   </div>
  )
}

export default ProductItem;

Here you can see that <div> is used to wrap multiple <li> elements. With that you get <div> in between <ul> and <li> which is not semantically correct HTML. By using Fragment you can get rid of this unnecessary div.

<React.Fragment>
    <li>------Next Product--------</li>
    <li>{props.item.id}</li>
    <li>{props.item.name}</li>
    <li>{props.item.price}</li>
</React.Fragment>

Fragment short syntax

There is a shorter syntax for declaring fragments which looks like empty tags <></>. With empty tags you don't need to import React and no need to write <React.Fragment>, here is the previous example where <React.Fragement> is replaced with empty tags.

<>
    <li>------Next Product--------</li>
    <li>{props.item.id}</li>
    <li>{props.item.name}</li>
    <li>{props.item.price}</li>
</>

One drawback of using empty tags is that you can’t use keys with them.

Key with Fragments

With Fragment you can pass a key attribute, that may be required when you map a collection to an array of fragments. Fragment with a key is called a Keyed Fragment. Note that, key is the only attribute that can be passed to Fragment.

const INIT_PRODUCT_CATALOG = [
    { id: 1, name: 'Laptop', price: 455.50 },
    { id: 2, name: 'Mouse', price: 15.89 },
    { id: 3, name: 'USB', price: 10.00 },
    { id: 4, name: 'HDD', price: 55.50 },
];
const Products = () => {
    return (
        <ul>
            {INIT_PRODUCT_CATALOG.map((item) => <React.Fragment key={item.id} >
                    <li>{item.id} {item.name} {item.price}</li>
                </React.Fragment>
            )}
        </ul>
    );
}

export default Products;

That's all for the topic React Fragments With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

What is In-place Algorithm

An in-place algorithm is an algorithm that doesn’t use any extra space to transform the input. It uses the same space used by input data and modify the data with in that space itself to produce the output. However a small amount of extra storage space is allowed for auxiliary variables.

Sorting algorithms like Bubble sort, Selection Sort, Insertion Sort are in-place sorting algorithms.

Merge sort is an example of not in-place or out-of-place sorting algorithm.

Here is code snippet of bubble sort showing how the input array itself is used to produce output. With in the input array after comparing elements, swapping is done if required. Only extra space it uses is the temp variable.

int[] arr = {61, 34, 10, 0, 15, 112, 53, 78, 39, 45};
int n = arr.length;
for(int i = 0; i < n; i++){
  for(int j = 0; j < (n - i - 1); j++){
    if(arr[j] > arr[j+1]){
        int temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp; 
    }
  }
}

Another simple example of in-place algorithm is reversing the array.

int[] arr = {61, 34, 10, 0, 15, 112, 53, 78, 39, 45};
int n = arr.length;
for (int i = 0; i < n / 2; i++) {
  int temp = arr[i];
  arr[i] = arr[n - 1 - i];
  arr[n - 1 - i] = temp;
}

That's all for the topic What is In-place Algorithm. If something is missing or you have something to share about the topic please write a comment.


You may also like

Stable and Unstable Sorting Algorithms

While reading about different sorting algorithms you would have come across the terms stable sorting algorithms and unstable sorting algorithms. In this post we’ll see what is the difference between stable and unstable sorting algorithms.

Stable sorting algorithm

A sorting algorithm is said to be stable if the order of the same values in the output remains the same as in input array.

stable sorting algorithm

This is an example of stable sorting, element 12 appears twice at index 5 and at index 7. In the output array after sorting is done the order is maintained 12 which was at index 5 appears first and 12 which was at index 7 appears later.

Unstable sorting algorithm

In an unstable sorting algorithm the ordering of the same values is not necessarily preserved after sorting.

Unstable sorting algorithm

Here you can see that the ordering for the same element 12 is not maintained after sorting.

Stability with key, value pair

Application of stability becomes more important when we have key value pairs where keys can be duplicated.

For example suppose records with timestamps are stored in an array as they arrive, so the records are in order of the timestamp in the array. Now you want to sort on cities. If an unstable sort is used to do so the records for each city may not necessarily be in order by timestamp after the sort.

Difference between stable and unstable

Stable and Unstable sorting algorithms

Sorting algorithms which are considered stable are- Insertion sort, Merge Sort, Bubble Sort

Sorting algorithms which are not considered stable are- Selection sort, Shellsort, Quicksort, Heapsort

That's all for the topic Stable and Unstable Sorting Algorithms. If something is missing or you have something to share about the topic please write a comment.


You may also like

Stable or Unstable Number Java Program

In this post we’ll see a Java program to check whether the number is stable or not. A stable number is a number in which each digit occurs the same number of time. For example 1010, 3355, 2020, 794479, in these numbers you can see that the frequency of each digit is same in the number.

An unstable number is a number in which each digit does not occur the same number of time, for example 1011, 3356, 404, 794419.

Check number Stable or Unstable Java Program

Create an array of length 10 for digits 0 to 9. This array is used to store frequency of each digit. In the while loop frequency of each digit is calculated and stored in the array.

When an integer array is created by default it will have 0 as value for each index. For some of the indices you will have values after calculating frequencies other will remain as 0. For example if 4422 is passed as number index 2 and 4 of the array will have value 2 all the other indices will have value 0.

In the for loop you discard all the elements with value as 0. Also a HashSet is used to store non-zero values. Note that HashSet stores only unique values so add() method of the HashSet returns false if same value is added again. This feature of the add() method of HashSet is used here; basically you have to check that the frequency of all the digits of the number is same if it is a stable number. So any time add() method returns true (after the first element is added) that means frequency is not same for all the digits thus an unstable number.

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class StableorUnstable {

  public static void main(String[] args) {
    System.out.println("Please enter a number : ");
    Scanner sc = new Scanner(System.in);
    int inputNum = sc.nextInt();
    boolean flag = isStable(inputNum);
    if(flag) {
      System.out.println(inputNum + " is a stable number");
    }else {
      System.out.println(inputNum + " is an unstable number");
    }
  }
	
  private static boolean isStable(int num) {
    int[] digitFreq = new int[10];
    int mod = 0;
    Set numSet = new HashSet<>();
    while(num != 0){
      mod = num % 10;
      digitFreq[mod]++;			
      num = num/10;
    }
    int firstAdd = 0;
    boolean addFlag;
    for(int i = 0; i < 9; i++) {
      // discard array elements with 0 values
      if(digitFreq[i] == 0)
        continue;
      firstAdd++;
      // if same number is added again add method returns false
      addFlag = numSet.add(digitFreq[i]);
      if(firstAdd > 1 && addFlag)
        return false;
    }
    return true;
  }
}
Output
Please enter a number : 
4422
4422 is a stable number

Please enter a number : 
794419
794419 is an unstable number

That's all for the topic Stable or Unstable Number Java Program. If something is missing or you have something to share about the topic please write a comment.


You may also like

Spring Bean Lifecycle Callback Methods

In Spring framework it is the Spring container that is responsible for instantiating beans, setting bean properties, wiring dependencies and managing the complete bean lifecycle from its instantiation to the time bean is destroyed.

Spring bean lifecycle callbacks

To interact with the container’s management of the bean lifecycle, in order to customize the nature of a bean, Spring Framework provides a number of interfaces which can be categorized into following categories-

  • Lifecycle Callbacks
  • ApplicationContextAware and BeanNameAware
  • Other Aware Interfaces

Spring bean lifecycle callback methods

Spring framework provides callback methods that can be configured to be called-

  1. After the bean is initialized i.e. post initialization call back methods.
  2. Before the bean is destroyed i.e. pre destruction call back methods.

In Spring bean lifecycle post initialization call back methods are-

  • The InitializingBean callback interface provides a method afterPropertiesSet() that can be used for initialization work.
  • Methods annotated with @PostConstruct
  • Custom init() method

In Spring bean lifecycle pre destruction call back methods are-

  • The DisposableBean callback interface provides a method destroy() which lets a bean get a callback when the container that contains it is destroyed.
  • Methods annotated with @PreDestroy
  • Custom destroy() method

Spring bean lifecycle callback methods execution order

If multiple lifecycle callbacks are configured for the same bean then different initialization methods are called as follows-

  1. Methods annotated with @PostConstruct
  2. afterPropertiesSet() as defined by the InitializingBean callback interface
  3. A custom configured init() method

Destroy methods are called in the following order:

  1. Methods annotated with @PreDestroy
  2. destroy() as defined by the DisposableBean callback interface
  3. A custom configured destroy() method

Callbacks for ApplicationContextAware and BeanNameAware interfaces is invoked after setting of bean properties but before an initialization callback such as InitializingBean or a custom init-method.

Following image shows the call back method flow after the bean is instantiated.

spring bean lifecycle instantiation

Following image shows the call back method flow before the bean is destroyed.

bean lifecycle destruction callback

InitializingBean and DisposableBean callback interfaces

The org.springframework.beans.factory.InitializingBean interface has a single method afterPropertiesSet(). By implementing this method you provide a post initialization call back method that let bean perform initialization work after the container has set all necessary properties on the bean.

The org.springframework.beans.factory.DisposableBean interface has a single method destroy(). By implementing this method you provide a pre destruction call back method that is called when the container that contains the bean is destroyed.

As per Spring docs it is not recommended to use the InitializingBean and DisposableBean callback interfaces as it unnecessarily couples the code to Spring. Using annotations @PostConstruct and @PreDestroy or custom init() and destroy() methods should be preferred.

InitializingBean and DisposableBean interfaces example

In the example there is a class OrderServiceImpl which has a dependency on Store. OrderServiceImpl class implements InitializingBean and DisposableBean interfaces and provides the callback methods.

public interface OrderService {
  public void buyItems();
}
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

public class OrderServiceImpl implements OrderService, InitializingBean, DisposableBean {
  private IStore store;
  @Autowired
  public OrderServiceImpl(IStore store){
    this.store = store;
  }
  // post initialization callback
  public void afterPropertiesSet() throws Exception {
    System.out.println("In afterPropertiesSet method for bean initialization work");
  }
  // pre destruction callback
  public void destroy() throws Exception {
    System.out.println("In destroy() method, cleaning up resources");
  }
  public void buyItems() {
    store.doPurchase();
  }
}
public interface IStore {
  public void doPurchase();
}
public class RetailStore implements IStore {
  public void doPurchase() {
    System.out.println("Doing purchase from Retail Store");
  }
}
XML Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd">
    
  <context:annotation-config />
  <!-- Store bean -->
  <bean id="store" class="com.knpcode.springproject.service.RetailStore" />

  <!-- OrderServiceImpl bean with store bean dependency -->
  <bean id="orderBean" class="com.knpcode.springproject.service.OrderServiceImpl" />
</beans>
You can use the following class with main method to read the configuration and call the bean method.
public class App {
  public static void main( String[] args ){
    // create context using configuration
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");
    OrderService order = context.getBean("orderBean", OrderServiceImpl.class);
    order.buyItems();
    context.close();
  }
}
Output
10:58:24.120 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
10:58:24.128 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
10:58:24.156 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'store'
10:58:24.187 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderBean'
10:58:24.287 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'orderBean' via constructor to bean named 'store'
In afterPropertiesSet method for bean initialization work
Doing purchase from Retail Store
In destroy() method, cleaning up resources

As you can see from the output first beans are instantiated and dependencies are wired after that afterPropertiesSet() callback method is called. When the container is closed at that time destroy() method is called on the bean.

Custom init and destroy methods in Spring bean lifecycle

You can also configure custom init and destroy callback methods using init-method and destroy-method attributes of the element. For example

<bean id="orderBean" class="com.knpcode.springproject.service.OrderServiceImpl" 
	      init-method="initMethod" destroy-method="destroyMethod" />
Default init and destroy methods

You can also configure custom init and destroy callback methods globally to be called for all the beans defined with in element. That way you don't need to configure init and destroy attributes with each bean definition. At the same time you do need to have same method name for post initialization and pre destruction in each bean class. For example-

<beans default-init-method="init" default-destroy-method="destroy">
  <bean id="orderBean" class="com.knpcode.springproject.service.OrderServiceImpl" 
    <property name="store" ref="storeBean" />
  </bean>
  <bean>.....</bean>
  ....
  ....
</beans>

@PostConstruct and @PreDestroy annotations in Spring bean lifecycle

A method annotated with @PostConstruct is considered a post initialization method where as a method annotated with @PreDestroy is considered a predestruction method.

Spring bean lifecycle callback methods example

In this example we’ll see use of all the three initialization and disposable methods that way you can check the order in which these methods are called.

Note that for using @PostConstruct and @PreDestroy annotations javax annotation API is needed. We need to add dependency for this explicitly Java 9 onward.

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

Here is a class which has all the types of initialization and disposable methods.

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class OrderServiceImpl implements OrderService, InitializingBean, DisposableBean {
  private IStore store;
  @Autowired
  public OrderServiceImpl(IStore store){
    this.store = store;
  }
  // post initialization callback
  public void afterPropertiesSet() throws Exception {
    System.out.println("In afterPropertiesSet method for bean initialization work");
  }
  // pre destruction callback
  public void destroy() throws Exception {
    System.out.println("In destroy() method, cleaning up resources");
  }
  public void initMethod() {
    System.out.println("call init method");
  }
  public void destroyMethod() {
    System.out.println("call destroy method");
  }
  @PostConstruct
  public void initAnnotationMethod() {
    System.out.println("call init method for post construct");
  }
  @PreDestroy
  public void destroyAnnotationMethod() {
    System.out.println("call destroy method for pre destroy");
  }
  public void buyItems() {
    store.doPurchase();
  }
}
Output
call init method for post construct
In afterPropertiesSet method for bean initialization work
call init method
Doing purchase from Retail Store
call destroy method for pre destroy
In destroy() method, cleaning up resources
call destroy method

As you can see first the methods annotated with @PostConstruct and @PreDestroy annotations are called. After that afterPropertiesSet() and destroy() methods are called and at the last custom configured init() and destroy() methods are called.

Aware interfaces in Spring framework

In Spring framework there are many Aware callback interfaces that let beans indicate to the container that they require a certain infrastructure dependency.

Some of the most important Aware interfaces are-

  • ApplicationContextAware- This interface has setApplicationContext() method which injects the ApplicationContext dependency into the bean. Using this ApplicationContext reference beans can programmatically manipulate the ApplicationContext that created them.
  • BeanNameAware- This interface has setBeanName() method. Class that implements the org.springframework.beans.factory.BeanNameAware interface is provided with a reference to the name defined in its associated object definition.
  • BeanFactoryAware- By implementing this interface bean will be injected with the declared BeanFactory. Using it you can get the bean definition and its attributes.
  • ServletConfigAware- This interface is valid only in in a web-aware Spring ApplicationContext and injects the Current ServletConfig the container runs in.
  • ServletContextAware- This interface is valid only in in a web-aware Spring ApplicationContext and injects the Current ServletContext the container runs in.

Spring Aware interfaces example

In the following example bean class implements ApplicationContextAware, BeanNameAware and BeanFactoryAware interfaces.

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ExampleBean implements ApplicationContextAware, BeanNameAware, BeanFactoryAware{

  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    System.out.println("In setBeanFactory method");
    // Getting another bean and calling its method
    OrderService orderService = (OrderService)beanFactory.getBean("orderBean");
    orderService.buyItems();		
  }

  public void setBeanName(String name) {
    System.out.println("In setBeanName method");
    System.out.println("Bean's name- " + name);		
  }

  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println("In setApplicationContext");
    OrderService orderService = (OrderService)applicationContext.getBean("orderBean");
    orderService.buyItems();
  }
}
Output
In setBeanName method
Bean's name- exampleBean
In setBeanFactory method
14:33:52.227 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderBean'
14:33:52.300 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'orderBean' via constructor to bean named 'store'
call init method for post construct
In afterPropertiesSet method for bean initialization work
call init method
Doing purchase from Retail Store
In setApplicationContext
Doing purchase from Retail Store
Doing purchase from Retail Store
call destroy method for pre destroy
In destroy() method, cleaning up resources
call destroy method

That's all for the topic Spring Bean Lifecycle Callback Methods. If something is missing or you have something to share about the topic please write a comment.


You may also like