Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Sunday, 9 March 2025

"Mastering Power Set Generation: A Deep Dive into Recursion” from a Java ☕ programmer’s perspective

Motivation for the notes :

  1. Leetcode#78. Subsets 
  2. G4G Power Set 

There are broadly two approaches :

  1. Bit Masking (iterative) 😷{not focus of this blog}
  2. Backtracking (recursive) ⭐
    1. Include-Exclude paradigm : here we see two variants & why we should use one over other
    2. For-loop paradigm : prefer this (reason at the end)

Continue reading my latest blog compiled at notion.so by clicking here :  "Mastering Power Set Generation: A Deep Dive into Recursion” from a Java ☕ programmer’s perspective



Tuesday, 28 November 2023

Creating Immutable Custom Class in Java

 A frequent Java interview question is : 

How to create a Class which is immutable? 

Like any other question, the answer begins with the understandig what do we really mean by the underlying concept - in this case : immutablity !!! 

Making a class immutable entails ensuring two solemn contracts : 

  1. Class is closed for extension i.e it cannot be inherited. (why is that necessary? ans at bottom)
  2. Once the object is created, the state of fields cannot chage till its existence in JVM.
In other words, A variable/class of an immutable type may only be changed by re-assigning to that variable. When we wish to only modify some portion of an immutable, we are compelled to reassign the whole object.

Let's take Student class as an example. 




This class can be made Immutable in following way (observe the Student class carefully) : 



KEY TAKEAWAYS : 
  1. finalize class 
  2. set class mebers as "private" and "final
  3. Assign new object to instance variable by copying all values 
  4. remove all setters() 
  5. return duplicate(new object) in getters() instead of actual instance variable

Finally answer to the question : Why do we need to declare an Immutable class final? 

Well the question is quite debatable. 

There are several reasons why we need to declare a class as final to make it immutable.
  1. To prevent subclasses from overriding methods and changing the state of the object.
    • If a class is not final, a subclass could override a method and change the state of the object. This would violate the principle of immutability, which states that the state of an object cannot be changed once it is created.
  2. To ensure that the object is thread-safe.
    • Immutable objects are thread-safe because they cannot be changed by multiple threads at the same time. This is important for objects that are shared between multiple threads, such as objects in a cache.
  3. To improve performance.
    • The JVM can make some optimizations for immutable objects, such as caching the hash code of the object. This can improve the performance of applications that use immutable objects.
  4. To make the code more readable and easier to understand.
    • Immutable objects are easier to reason about because their state cannot change. This makes the code more readable and easier to understand.

~ Happy Coding ~

Saturday, 28 October 2023

Pictorial Guide to understand Access Modifier in Java

 

Access Modifiers in Java has been explained beautifully in blogs like this

But this blog aims to leave a pictorial memory in reader's mind. 

Usually, it is represented in tabular form like this ... 


But I wanted to present even more practical schematic diagram. 



Private

Default (aka package-private)


Protected


Public

 







Saturday, 28 January 2017

Understanding the immutable nature of java.lang.String

public class ImmutableStringDemo {

public static void main(String[] args) {

String sl = "First Name";  // a string literal
String so = new String("First Name"); // a string object
StringBuffer sb = new StringBuffer("First Name"); // a stringBuffer object


System.out.println("s1 = " + sl + " hashCode = "+ mimicObjectToString(sl));
sl += "Kumar"; // appended ,
System.out.println("s1 = " + sl + " hashCode = "+ mimicObjectToString(sl)+ "\n");
// if the output differs it means a new reference has been created during appending

System.out.println("so = " + so + " hashCode = "+ mimicObjectToString(so));
so += "Kumar";
System.out.println("so = " + so + " hashCode = "+ mimicObjectToString(so)+ "\n");

System.out.println("sb = " + sb + " hashCode = "+ mimicObjectToString(sb));
sb.append("Kumar");
System.out.println("sb = " + sb + " hashCode = "+ mimicObjectToString(sb)+ "\n");

System.out.println("Changed hashCode denotes different reference has been created, making it \"immutable\"");
}

public static String mimicObjectToString(Object o)
    {
        //prevent a NullPointerException by returning null if o is null
        String result = null;
        if (o !=null)
        {
            result = o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o));
        }
        return  result;
    }
}
 
Click here for running code : https://ideone.com/llyFaU  

Oracle docs defines StringBuffer as "A thread-safe, mutable sequence of characters"

Thursday, 2 October 2014

Exploring Integer - the wrapper class for primitive int

Try `==` and `equals()` for Integer



  1. public class IntegerClass {

  2. public static void main(String[] args) {

  3. Integer i1 = 11;
  4. Integer i2 = 11;
  5. if(i1 == i2){
  6. System.out.println("i1 == i2");
  7. }
  8. if(i1.equals(i2)){
  9. System.out.println("i1.equals(i2)");
  10. }
  11. /* * * * * * * * * * * * * * * * * * * * * */
  12. Integer i3 = 128;
  13. Integer i4 = 128;
  14. if(i3 == i4){
  15. System.out.println("i3 == i4");
  16. }else{
  17. System.out.println("i3 != i4");
  18. }
  19. /* * * * * * * * * * * * * * * * * * * * * */
  20. if(i3.equals(i4)){
  21. System.out.println("i3.equals(i4)");
  22. }else{
  23. System.out.println("!(i3.equals(i4))");
  24. }
  25. }
  26. }
Line 5 will be actually compiled as Iinteger.valueOf(11)
Thanks to compiler which actually autoboxes primitive values to corresponding wrapper classes.