Java Basics 8

Difference in String, String Buffer and String Builder?

In Java, String, StringBuffer, and StringBuilder are all used to represent and manipulate strings, but they have some key differences:

  • String is an immutable class, which means once a string object is created, its value cannot be changed. Any operation that modifies the string, such as concatenation or replacement, will create a new string object with the modified value. Because of this, strings are often used for cases where the string value will not change, such as string literals.
  • StringBuffer is also a mutable class, but it is thread-safe, which means that multiple threads can access a single StringBuffer object without causing any errors. However, the cost of thread-safety is added overhead, making StringBuffer slower than StringBuilder.
  • StringBuilder is a mutable class, and it is similar to StringBuffer, but it is not thread-safe. This means that it is faster than StringBuffer, but it should not be used in a multithreaded environment.

In summary:

  • String is immutable and can't be modified, it is safe to use in multithreading environment.
  • StringBuffer is mutable and thread-safe, but it may have performance overhead.
  • StringBuilder is mutable and not thread-safe but has better performance when compared to StringBuffer in single-threaded environment.

Situations:

  • If your string is not going to change use a String class because a String object is immutable.
  • If your string can change (example: lots of logic and operations in the construction of the string) and will only be accessed from a single thread, using a StringBuilder is good enough.
  • If your string can change, and will be accessed from multiple threads, use a StringBufferbecause StringBuffer is synchronous so you have thread-safety.

It's important to note that for simple string concatenation operations, using + operator or String.concat() method is more efficient than using StringBuffer or StringBuilder.


Why is string immutable? What does it mean?

In Java, a String is immutable because its value cannot be changed once it is created. When a String object is created, the value is stored in a character array, and the reference to that array is stored in the String object. Once the String object is created, the value stored in the character array cannot be modified.

This immutability has several advantages:

  • Security: Since the value of a String cannot be changed, it is safe to use in a multithreading environment. Multiple threads can access the same String object without causing any errors.
  • Memory Efficiency: When a String is modified, a new String object is created with the modified value. However, the original String object remains in memory, and it can be garbage collected if there are no references to it. This helps to prevent memory leaks.
  • Consistency: Because the value of a String cannot be changed, it can be used to represent values that should not change, such as file paths, URLs, and other constants.
  • Synchronization and concurrency: making String immutable automatically makes them thread safe thereby solving the synchronization issues.
  • Caching: when compiler optimizes your String objects, it sees that if two objects have same value and thus you need only one string object
  • Class loading: String is used as arguments for class loading. If mutable, it could result in wrong class being loaded (because mutable objects change their state).

However, immutability also has some disadvantages:

  • Performance: Modifying a String requires creating a new object, which can be slow for large strings or if the modification is done frequently.
  • Memory usage: Creating a new String object for each modification can use a lot of memory, especially for large strings or if the modification is done frequently.
  String a="stack";
  System.out.println(a);//prints stack
  a.setValue("overflow");
  System.out.println(a);//if mutable it would print overflow

To overcome those disadvantages, Java provides two other classes StringBuffer and StringBuilder which are mutable (able to change), but they are not thread-safe as well as less memory efficient.


Collections with all types?

java collections

List interface (contain duplicate elements)

  • List always Maintains insertion order
  • ArrayList class -- only supports object entries, not the primitive data types
  • LinkedList class – each element in a LinkedList is represented by a node, which contains a reference to the previous node and the next node in the list. It is an ordered collection of elements, allowing duplicate values.
  • A LinkedList has the following characteristics:
  • Vector

Set Interface(contains unique elements)

  • HashSet class -- general purpose collection for storing object
  • LinkedHashSet class -- insertion order
  • TreeSet class  -- sorting

Map interface

  • HashMap class -- makes absolutely no guarantees about the iteration order
  • LinkedHashMap class -- will iterate in the order in which the entries were put into the map
  • TreeMap class -- will iterate according to the "natural ordering" of the keys

Deque interface:

A Deque (double-ended queue) is a collection that allows elements to be inserted or removed from either end of the queue. Classes that implement the Deque interface includes ArrayDeque and LinkedList.

Others
PriorityQueue class
Hashtable class


The difference in Hash/tree/linked - map/set/vector.

All three classes implement the Map interface and offer mostly the same functionality. The most important difference is the order in which iteration through the entries will happen-

HashMap makes absolutely no guarantees about the iteration order. It can (and will) even change completely when new elements are added.

TreeMap will iterate according to the "natural ordering" of the keys according to their compareTo() method (or an externally supplied Comparator). Additionally, it implements the SortedMap interface, which contains methods that depend on this sort order.

LinkedHashMap will iterate in the order in which the entries were put into the map

List can contain duplicate elements whereas Set contains unique elements only.

TreeSet, LinkedHashSet, and HashSet in Java are three Set implementations in the collection framework and like many others, they are also used to store objects.  The main feature of TreeSet is sorting, LinkedHashSet is insertion order and HashSet is just a general purpose collection for storing objects.

HashSet is implemented using HashMap in Java while TreeSet is implemented using TreeMap. TreeSet is a SortedSet implementation that allows it to keep elements in the sorted order defined by either the Comparable or Comparator interface. Comparable is used for natural order sorting and Comparator for custom order sorting of objects, which can be provided while creating an instance of TreeSet