Java Lang Package:Object, String, StringBuffer, StringBuilder, and Wrapper Classes

The java.lang package is the core of the Java programming language. It contains classes and interfaces that are essential for developing Java applications. This package is automatically imported into every Java program, so developers do not need to explicitly include it.

Key Features of java.lang Package

The Object Class in Java

The Object class is the root class of the Java class hierarchy. Every class in Java directly or indirectly inherits from the Object class. It provides a set of methods that are fundamental to all Java objects.

Key Methods of the Object Class

Below are the methods of the Object class with detailed explanations and examples:

Method Description
boolean equals(Object obj) Checks if two objects are equal.
int hashCode() Returns the hash code of the object.
String toString() Returns a string representation of the object.
Class getClass() Returns the runtime class of the object.
Object clone() Creates and returns a copy of the object.
void finalize() Called by the garbage collector before object destruction.
void wait() Causes the current thread to wait until notified.
void wait(long timeout) Causes the current thread to wait for a specified time.
void wait(long timeout, int nanos) Causes the current thread to wait for a specified time and nanoseconds.
void notify() Wakes up a single thread waiting on the object's monitor.
void notifyAll() Wakes up all threads waiting on the object's monitor.

1. toString()

The toString() method returns a string representation of the object. By default, it returns a string in the format: ClassName@HashCode.

Example:


  public class ObjectToStringExample {
      public static void main(String[] args) {
          Object obj = new Object();
          System.out.println(obj.toString()); // Default implementation
      }
  }
        

Custom Implementation: You can override the toString() method in your class:


  public class Person {
      String name;
      int age;
  
      public Person(String name, int age) {
          this.name = name;
          this.age = age;
      }
  
      @Override
      public String toString() {
          return "Person{name='" + name + "', age=" + age + "}";
      }
  }
  
  public class ToStringExample {
      public static void main(String[] args) {
          Person person = new Person("Alice", 25);
          System.out.println(person.toString());
      }
  }
        

Output:


  Person{name='Alice', age=25}
        

2. equals(Object obj)

The equals() method compares two objects for equality. By default, it checks if two references point to the same object.

Example:


  public class EqualsExample {
      public static void main(String[] args) {
          Object obj1 = new Object();
          Object obj2 = new Object();
  
          System.out.println(obj1.equals(obj2)); // false
          System.out.println(obj1.equals(obj1)); // true
      }
  }
        

Custom Implementation: Override the equals() method to compare object fields:


  public class Person {
      String name;
  
      public Person(String name) {
          this.name = name;
      }
  
      @Override
      public boolean equals(Object obj) {
          if (this == obj) return true;
          if (obj == null || getClass() != obj.getClass()) return false;
          Person person = (Person) obj;
          return name.equals(person.name);
      }
  }
  
  public class CustomEqualsExample {
      public static void main(String[] args) {
          Person p1 = new Person("Alice");
          Person p2 = new Person("Alice");
          System.out.println(p1.equals(p2)); // true
      }
  }
        

3. hashCode()

The hashCode() method returns an integer value (hash code) that represents the object. It is used in hash-based collections like HashMap.

Example:


  public class HashCodeExample {
      public static void main(String[] args) {
          Object obj = new Object();
          System.out.println(obj.hashCode());
      }
  }
        

Custom Implementation: Ensure consistency with equals() when overriding:


  @Override
  public int hashCode() {
      return name.hashCode();
  }
        

4. getClass()

The getClass() method returns the runtime class of the object.

Example:


  public class GetClassExample {
      public static void main(String[] args) {
          Object obj = new Object();
          System.out.println(obj.getClass()); // class java.lang.Object
      }
  }
        

5. clone()

The clone() method creates a copy of the object. To use this method, the class must implement the Cloneable interface.

Example:


  public class Person implements Cloneable {
      String name;
  
      public Person(String name) {
          this.name = name;
      }
  
      @Override
      protected Object clone() throws CloneNotSupportedException {
          return super.clone();
      }
  }
  
  public class CloneExample {
      public static void main(String[] args) throws CloneNotSupportedException {
          Person person1 = new Person("Alice");
          Person person2 = (Person) person1.clone();
          System.out.println(person1.name.equals(person2.name)); // true
      }
  }
        

6. finalize()

The finalize() method is invoked by the garbage collector before an object is destroyed. It is rarely used.

Example:


  public class FinalizeExample {
      @Override
      protected void finalize() {
          System.out.println("Finalize method called");
      }
  
      public static void main(String[] args) {
          FinalizeExample example = new FinalizeExample();
          example = null;
          System.gc(); // Request garbage collection
      }
  }
        

Understanding Strings in Java

In Java, the String class represents a sequence of characters. Strings are immutable, meaning their value cannot be changed once created. Strings are extensively used in Java and are stored in a special memory area called the String Constant Pool (SCP).

1. Immutability of Strings

Strings are immutable in Java, which means that once a String object is created, it cannot be modified. Any operation that appears to modify a string actually creates a new string.

Example:


  public class StringImmutability {
      public static void main(String[] args) {
          String str = "Hello";
          str.concat(" World");
          System.out.println(str); // Output: Hello (original string remains unchanged)
  
          String newStr = str.concat(" World");
          System.out.println(newStr); // Output: Hello World
      }
  }
        

2. What is SCP (String Constant Pool)?

The String Constant Pool (SCP) is a special memory area in Java's heap memory. It is used to store string literals. If a string literal is already in the pool, the reference to the existing literal is returned instead of creating a new object.

Example:


  public class SCPExample {
      public static void main(String[] args) {
          String str1 = "Java";
          String str2 = "Java";
          String str3 = new String("Java");
  
          System.out.println(str1 == str2); // true (same reference in SCP)
          System.out.println(str1 == str3); // false (new object in heap)
      }
  }
        

3. String Object Creation

Strings can be created in two ways:

Example:


  public class StringCreation {
      public static void main(String[] args) {
          // String literal
          String str1 = "Hello";
  
          // Using new keyword
          String str2 = new String("Hello");
      }
  }
        

Frequently Used String Methods in Java

The String class in Java provides numerous methods for manipulating and analyzing strings. Below are 25 frequently used methods with examples:

  1. length()

    Returns the length of the string.

    String str = "Hello";
        System.out.println(str.length()); // Output: 5
  2. charAt(int index)

    Returns the character at the specified index.

    String str = "Hello";
        System.out.println(str.charAt(1)); // Output: 'e'
  3. substring(int beginIndex)

    Returns a substring starting from the specified index.

    String str = "Hello World";
        System.out.println(str.substring(6)); // Output: "World"
  4. substring(int beginIndex, int endIndex)

    Returns a substring from beginIndex to endIndex (exclusive).

    String str = "Hello World";
        System.out.println(str.substring(0, 5)); // Output: "Hello"
  5. toUpperCase()

    Converts all characters to uppercase.

    String str = "hello";
        System.out.println(str.toUpperCase()); // Output: "HELLO"
  6. toLowerCase()

    Converts all characters to lowercase.

    String str = "HELLO";
        System.out.println(str.toLowerCase()); // Output: "hello"
  7. trim()

    Removes leading and trailing whitespace.

    String str = "  Hello  ";
        System.out.println(str.trim()); // Output: "Hello"
  8. equals(Object obj)

    Checks if two strings are equal.

    String str1 = "Hello";
        String str2 = "Hello";
        System.out.println(str1.equals(str2)); // Output: true
  9. equalsIgnoreCase(String anotherString)

    Checks if two strings are equal, ignoring case.

    String str1 = "hello";
        String str2 = "HELLO";
        System.out.println(str1.equalsIgnoreCase(str2)); // Output: true
  10. startsWith(String prefix)

    Checks if the string starts with the specified prefix.

    String str = "Hello World";
        System.out.println(str.startsWith("Hello")); // Output: true
  11. endsWith(String suffix)

    Checks if the string ends with the specified suffix.

    String str = "Hello World";
        System.out.println(str.endsWith("World")); // Output: true
  12. indexOf(int ch)

    Returns the index of the first occurrence of the character.

    String str = "Hello World";
        System.out.println(str.indexOf('o')); // Output: 4
  13. lastIndexOf(int ch)

    Returns the index of the last occurrence of the character.

    String str = "Hello World";
        System.out.println(str.lastIndexOf('o')); // Output: 7
  14. contains(CharSequence sequence)

    Checks if the string contains the specified sequence.

    String str = "Hello World";
        System.out.println(str.contains("World")); // Output: true
  15. replace(char oldChar, char newChar)

    Replaces all occurrences of a character.

    String str = "Hello World";
        System.out.println(str.replace('o', 'a')); // Output: "Hella Warld"
  16. replace(CharSequence target, CharSequence replacement)

    Replaces all occurrences of a substring.

    String str = "Hello World";
        System.out.println(str.replace("World", "Java")); // Output: "Hello Java"
  17. split(String regex)

    Splits the string into an array based on the specified regex.

    String str = "Hello World Java";
        String[] words = str.split(" ");
        for (String word : words) {
            System.out.println(word);
        }
        // Output: "Hello", "World", "Java"
  18. concat(String str)

    Concatenates the specified string to the end.

    String str1 = "Hello";
        String str2 = " World";
        System.out.println(str1.concat(str2)); // Output: "Hello World"
  19. toCharArray()

    Converts the string into a character array.

    String str = "Hello";
        char[] chars = str.toCharArray();
        for (char c : chars) {
            System.out.print(c + " ");
        }
        // Output: "H e l l o"
  20. valueOf(Object obj)

    Converts the given object to a string.

    int num = 10;
        System.out.println(String.valueOf(num)); // Output: "10"
  21. matches(String regex)

    Checks if the string matches the regex.

    String str = "12345";
        System.out.println(str.matches("\\d+")); // Output: true
  22. intern()

    Returns the canonical representation of the string.

    String str1 = new String("Hello").intern();
        String str2 = "Hello";
        System.out.println(str1 == str2); // Output: true
  23. repeat(int count)

    Repeats the string a specified number of times.

    String str = "Hi ";
        System.out.println(str.repeat(3)); // Output: "Hi Hi Hi "

StringBuffer and StringBuilder in Java

What is StringBuffer?

StringBuffer is a mutable sequence of characters. It is used when you need to modify strings frequently, such as in a loop or with a large amount of data. It is synchronized, making it thread-safe, but this comes at a performance cost.

StringBuffer Methods

What is StringBuilder?

StringBuilder is similar to StringBuffer but it is not synchronized, which means it is faster than StringBuffer when used in a single-threaded environment. It is also mutable, and often used in cases where thread safety is not required.

StringBuilder Methods

Difference Between String, StringBuffer, and StringBuilder

Feature String StringBuffer StringBuilder
Immutability Immutable (Cannot be changed) Mutable (Can be modified) Mutable (Can be modified)
Thread-Safety Not thread-safe Thread-safe (Synchronized) Not thread-safe
Performance Slower due to immutability Slower (Thread-safe) Faster (Not thread-safe)
Use Case Best for constant, unchanging strings Best when working in multi-threaded environments Best when working in single-threaded environments

Conclusion

String is immutable and slower for concatenation operations. If you need a mutable sequence of characters, use StringBuffer for thread-safety or StringBuilder when performance is a higher priority in single-threaded scenarios.

Wrapper Classes in Java

Wrapper classes in Java are used to represent the primitive data types as objects. Every primitive type has a corresponding wrapper class in Java:

1. Convert String to Wrapper Class and Vice Versa

You can convert a String to its corresponding wrapper class and vice versa. Here's how:

Convert String to Wrapper Class

To convert a String to a wrapper class object, you can use the valueOf() method of the wrapper class.


    String str = "123";
    Integer intObj = Integer.valueOf(str);  // String to Integer Wrapper
    System.out.println(intObj);  // Output: 123
          

Convert Wrapper Class to String

To convert a wrapper class object to a String, you can use the toString() method of the wrapper class or the String.valueOf() method.


    Integer intObj = 123;
    String str = intObj.toString();  // Wrapper Integer to String
    System.out.println(str);  // Output: "123"
          

2. Convert String to Primitive and Vice Versa

Converting between String and primitive types can be done using parsing methods for primitive types.

Convert String to Primitive

To convert a String to a primitive type, use the parse methods of the respective wrapper class.


    String str = "123";
    int intValue = Integer.parseInt(str);  // String to int
    System.out.println(intValue);  // Output: 123
          

Convert Primitive to String

To convert a primitive type to a String, use the String.valueOf() method or simply concatenate with an empty string.


    int num = 123;
    String str = String.valueOf(num);  // int to String
    System.out.println(str);  // Output: "123"
          

3. Convert Wrapper Class to Primitive and Vice Versa

Wrapper classes can be converted to primitive types using xxxValue() methods, and primitives can be converted to wrapper classes using auto-boxing or the valueOf() method.

Convert Wrapper Class to Primitive

To convert a wrapper class object to its corresponding primitive type, use the xxxValue() method, where xxx is the name of the primitive type.


    Integer intObj = 123;
    int intValue = intObj.intValue();  // Wrapper to primitive
    System.out.println(intValue);  // Output: 123
          

Convert Primitive to Wrapper Class

To convert a primitive to a wrapper class object, you can either use auto-boxing or the valueOf() method.


    int num = 123;
    Integer intObj = Integer.valueOf(num);  // Primitive to Wrapper
    System.out.println(intObj);  // Output: 123
          

Auto-boxing and Unboxing

Java automatically converts between primitive types and wrapper classes, a feature known as auto-boxing (primitive to wrapper) and unboxing (wrapper to primitive).


    int num = 123;
    Integer intObj = num;  // Auto-boxing (primitive to wrapper)
    
    int unboxedValue = intObj;  // Unboxing (wrapper to primitive)
    System.out.println(unboxedValue);  // Output: 123
          

Summary

In summary, converting between String, Wrapper classes, and primitive types is straightforward using methods such as valueOf(), parseInt(), toString(), and the xxxValue() methods. Java also provides auto-boxing and unboxing for automatic conversion between primitive types and wrapper classes.