When to use LinkedHashMap.removeEldestEntry method

removeEldestEntry method exists only on subclasses of LinkedHashMap
removeEldestEntry always invoked after an element is inserted. Based on what this method returns following action will happen if method returns true based on some condition, then the oldest entry will be removed. if method always returns true then basically list will be empty. if method return false, then nothing will be deleted and map will behave like any other LinkedHashMap. after every put or putAll insertion, the eldest element will be removed, no matter what. The JavaDoc shows a very sensible example on how to use it:
Lets see an example of removeEldestEntry.
MapRemoveEntry Example
import java.util.LinkedHashMap;
import java.util.Map;

public class MapRemoveEntry {

	public static void main(String argv[]) {

		LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>() {
			private static final long serialVersionUID = 1L;

			protected boolean removeEldestEntry(Map.Entry<Integer,String> eldest) {
				return size() > 4;
			}
		};;
		

		map.put(0, "A");
		map.put(1, "B");
		map.put(2, "C");
		map.put(3, "D");
		map.put(4, "E");
		
		
		
		map.forEach((k,v) -> { System.out.println("key = " + k + " value = " + v);});
	}
}
If we run the above example we will get following output.
Terminal
Console
key = 1 value = B
key = 2 value = C
key = 3 value = D
key = 4 value = E
Reason is, method removeEldestEntry returns true when the map size is >4. That means when the map size is greater than 4 => the oldest entry will be removed. In this case oldest is the very first entry with (key=0, value=A).

Summary

Using removeEldestEntry we can control when to remove the most oldest entry from the map. This can be used for creating a cache.

About sealed classes and interfaces

Starting Java 17 we can now allow additional class modifiers like sealed, non-sealed etc. A sealed class or interface can be extended or implemented only by those classes and interfaces permitted to do so.
Earlier we had only two options, allow subclasses to inherit the parent class or interface or not at all. In the later case using Final class modifier. Using sealed we can take a more controlled middle path where the Parent Class or Interface can dictate the Sub classes which can inherit from the Class.
Following are the keywords related to sealed classes. sealed : only permitted classes can extend a sealed class/interface permits: used along with sealed and mentions the names of the child classes. non-sealed: if we want a specific class (inherited from a sealed class) to be inheritable we can open it up by marking it non-sealed.

Defining sealed class

Let's define a sealed class Tesla with 3 known subclasses that it can have.

sealed Tesla

Tesla
package java17.sealed;

public abstract sealed class Tesla permits Model3, ModelS, TeslaSUV{
	public abstract Integer maxRange();
	public String basePrice() {
		return "25000 USD";
	}
}

Now start implementing the subclasses possible. We implement Model3 and mark it final which will make the inheritance chance closed at this level.
Model3
//Subclass 1
public final class Model3 extends Tesla {
	@Override
	public Integer maxRange() {
		return 200;
	}
}
ModelS

//Subclass 2
public final class ModelS extends Tesla {
	@Override
	public Integer maxRange() {
		return 400;
	}
}
In this third case we want the TeslaSUV to be extendable so that it can be extended. That's why we will mark it with non-sealed.
TeslaSUV
//Subclass3 (non-sealed)
public non-sealed class TeslaSUV extends Tesla {
	@Override
	public Integer maxRange() {
		// TODO Auto-generated method stub
		return null;
	}
}

Style Two: Using member classes

We can also directly implement possible child classes that we want to allow as member classes without using permit. In the following example we are creating a sealed class BMWCars and three member classes.
BMWCars
package java17.sealed;

public sealed class BMWCars {

	public final class BMW3 extends BMWCars implements ElectricVehicle{

	}
	
	public final class BMWI extends BMWCars implements Vehicle {

	}
	
	public non-sealed class BMWJV extends BMWCars implements Vehicle {

	}

}

Rules for Defining Sealed Classes or Interfaces

Both Class and Interface can be marked with sealed. Inherited child classes can be marked with either final, sealed and non-sealed. Every permitted subclass must directly extend the sealed class. A permitted subclass may be non-sealed so that it is open for extension by unknown subclasses.

Summary

With introduction of sealed classes we can define the known subclasses of an abstract class. In other words now we can enforce extension of classes that is known in compile time. It allows us to have greater control of class proliferation and improve security.

Java record in details with example

With Java 14 we have a new way to represent data intensive objects with less boilerplate codes.
Consider the following object representing Address and containing 5 fields. Address:{ street: city: zip: state: country: }
following record AddressRecord will be able to represent above address information.
AddressRecord
package Java14;

public record AddressRecord(String street, String city, Integer zip, String state, String country) {

}
We can instantiate AddressRecord record instance by passing the parameter values. Also system will generate the getter methods. The JVM will generate the getter methods for us. like, street() city() zip() state() country()
AddressRecordDemo
package Java14;

public class AddressRecordDemo {

	public static void main (String arg[]) {
		
		AddressRecord address1 = new AddressRecord("1044 Main Street", "Livermore", 94550, "CA", "USA");
		
		System.out.println(address1.street());
		System.out.println(address1.city());
		System.out.println(address1.state());
	}
}
Record can be very useful when we want to write DTO objects which is to carry or represent information. Following are some of the properties/rules that record have.
Rules for record

    How to check if a Java object is final

    final modifier can be applied at class level. If a Class is marked final it cannot be extended.
    Sample final Class
    
    final class MyCustomClass {
    	
    }

    Using java.lang.reflect.Modifier

    Using java.lang.reflect.Modifier,, We can check if a class is final though java.lang.reflect.Modifier.isFinal() method. MyCustomClass.class.getModifiers() will provide an integer number representing the class modifier. For example for the above class it prints 16. Now the value returned from the getModifiers() can be decoded with method Modifier.isFinal();
    JavaReflectionModifiers
    import java.lang.reflect.Modifier;
    
    public class JavaReflectionModifiers {
    
    	public static void main(String[] args) {
    		
                     //prints 16
    		System.out.println(MyCustomClass.class.getModifiers());
    		
                     //returns true
    		Modifier.isFinal(MyCustomClass.class.getModifiers());
    
    	}
    
    }
    
    
    final class MyCustomClass {
    	
    }

    More Examples

    Examples
    package Java14;
    
    import java.lang.reflect.Modifier;
    
    public class JavaReflectionModifiers {
    
    	public static void main(String[] args) {
    		
    		System.out.println(MyCustomClass.class.getModifiers());
    		
    		//prints true
    		System.out.println(Modifier.isFinal(MyCustomClass.class.getModifiers()));
    		
    		//prints true
    		System.out.println(Modifier.isFinal(String.class.getModifiers()));
    		
    		//prints false
    		System.out.println(Modifier.isFinal(Number.class.getModifiers()));
    
    	}
    
    }
    
    
    final class MyCustomClass {
    	
    }

    Can Java record be extended?

    Java record introduced in java 14. It provides a way to reduce boiler plate code while defining data classes. record is final implicitly and cannot be extended.
    For example in the following record MobilePhone, we cannot extend it.
    record MobilePhone
    record MobilePhone(String brand, String modelName, Number osVersion, boolean canFlip) {
    
    }
    Java records are implicitly final it can be confirmed by the following code. Which checks if the java.lang.Class for the object have final modifier or not.
    RecordFinalTest
    package Java14;
    
    import java.lang.reflect.Modifier;
    
    public class RecordFinalTest {
    
    	public static void main(String[] args) {
    		
    		MobilePhone phone1 = new MobilePhone("Samsung", "Galaxy1", 1, false);
    
    		//false
    		System.out.println(Modifier.isFinal(phone1.getClass().getModifiers()));
    		
    		//false
    		System.out.println(Modifier.isFinal(MobilePhone.class.getModifiers()));
    
    	}
    
    }
    
    For more details about record in Java please check the following references.

    References

    How to create double linked list in Java

    In Double Linked List we have each node pointing to the previous and next node. Here we will see how to create a custom Double Linked List in java.
    Some properties of linked list is that, it has a node that can contain some value and then each node is linked to next node and also previous node. That's why we can traverse the linked list sequentially given we know the starting (head) node or last (tail) node.
    Custom Linked List
    class MyLinkedList<E> {
    
    	/* first points to head of the list */
    	public Node<E> first = null;
    
    	/* last points to tail of the list */
    	public Node<E> last = null;
    
    	/**
    	 * Add item to tail (end) of the List
    	 * 
    	 * @param item
    	 * @return
    	 */
    	public boolean add(E item) {
    		Node<E> newNode = new Node<E>(last, item, null);
    
    		if (last == null) {
    			// last points to the new node created
    			first = newNode;
    		} else {
    			last.next = newNode;
    		}
    		// update last so that it points to the new node
    		last = newNode;
    		return true;
    	}
    
    	static class Node<E> {
    		public E value;
    		public Node<E> next;
    		public Node<E> prev;
    
    		Node(Node<E> prev, E element, Node<E> next) {
    			this.value = element;
    			this.next = next;
    			this.prev = prev;
    		}
    	}
    
    }
    In the above implementation we have defined the main class MyLinkedList and inside it we defined a generic static class Node. Each Node object can hold a value and has links to previous (prev) and next nodes.
    Create Instance of MyLinkedList
    //create instance
    MyLinkedList<Integer> list = new MyLinkedList<Integer>();
    
    //add values 1,2,3,4,5
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    Print the content of the node
    //Get the first node (head node) and then print it by traversing all nodes
    MyLinkedList.Node<Integer> node = list.first;
    while (node != null) {
    	System.out.println("Content of Node: " + node.value);
    	node = node.next;
    }
    Terminal
    Output
    Content of Node: 1
    Content of Node: 2
    Content of Node: 3
    Content of Node: 4
    Content of Node: 5

    About sealed classes and interfaces

    Starting Java 17 we can now allow additional class modifiers like sealed, non-sealed etc. A sealed class or interface can be extended or implemented only by those classes and interfaces permitted to do so. Following are the keywords related to sealed classes.
    New Keywords
      Earlier we had only two options, allow subclasses to inherit the parent class or interface or not at all. In the later case using Final class modifier. Using sealed we can take a more controlled middle path where the Parent Class or Interface can dictate the Sub classes which can inherit from the Class.

      Defining sealed class (Two Styles)

      Style One: Using permit keyword

      using the class modifiers sealed and permits we can create sealed classes. In the example bellow we are Defining abstract sealed class Tesla which permits three known subclasses Model3, ModelS and TeslaSUV.
      Tesla
      package java17.sealed;
      
      public abstract sealed class Tesla permits Model3, ModelS, TeslaSUV{
      	public abstract Integer maxRange();
      	public String basePrice() {
      		return "25000 USD";
      	}
      }
      
      //Subclass 1
      public final class Model3 extends Tesla {
      	@Override
      	public Integer maxRange() {
      		return 200;
      	}
      }
      
      //Subclass 2
      public final class ModelS extends Tesla {
      	@Override
      	public Integer maxRange() {
      		return 400;
      	}
      }
      
      //Subclass3 (non-sealed)
      public non-sealed class TeslaSUV extends Tesla {
      	@Override
      	public Integer maxRange() {
      		// TODO Auto-generated method stub
      		return null;
      	}
      }
      
      

      Style Two: Using member classes

      In the following example we are creating a sealed class BMWCars and three member classes.
      BMWCars
      package java17.sealed;
      
      public sealed class BMWCars {
      
      	public final class BMW3 extends BMWCars implements ElectricVehicle{
      
      	}
      	
      	public final class BMWI extends BMWCars implements Vehicle {
      
      	}
      	
      	public non-sealed class BMWJV extends BMWCars implements Vehicle {
      
      	}
      
      }
      

      Rules for Defining Sealed Classes or Interfaces

      Both Class and Interface can be marked with sealed. Inherited child classes can be marked with either final, sealed and non-sealed. Every permitted subclass must directly extend the sealed class. A permitted subclass may be non-sealed so that it is open for extension by unknown subclasses.

      Summary

      With introduction of sealed classes we can define the known subclasses of an abstract class. In other words now we can enforce extension of classes that is known in compile time. It allows us to have greater control of class proliferation and improve security.

      Generating Random Number in Java

      This article summarizes different ways to use the Random() class in java to generate bounded or unbounded random numbers. It also shows another important feature of the class that is using seed to generate same set of random numbers.
      java.util.Random used used to generate bounded or unbounded random numbers. It supports specifying a seed which is used to set the internal state of the pseudorandom number generator. Random(): creates new random generator Random(long seed): creates new random generator using specified seed
      Unbounded generate 5 random numbers
      Following code prints 5 random numbers unbounded without any seed
      public static void generateRadom() {
      	System.out.println("\nPrinting 10 Random Numbers");
      	Random generator = new Random();
      	for (int i = 0; i < 5; i++) {
      		System.out.print(generator.nextInt() + " ");
      	}
      }
      Invocation 1
      Printing 5 Random Numbers -1937915077 75383412 -901884443 1725835531 1371480362
      Invocation 2
      Printing 5 Random Numbers -1261854044 328673857 -1787159304 446964878 -283294822
      Notice that in both the invocations the generated numbers are different. This is because we have not set any seed in the Random Class.
      Random Bounded Number
      Following method will generate 5 random numbers between 0 and 99
      public static void generateRadomBounded() {
      	System.out.println("\nPrinting 5 Random Numbers Between 0 and 99");
      	Random generator = new Random();
      	for (int i = 0; i < 5; i++) {
      		System.out.print(generator.nextInt(100) + " ");
      	}
      }
      Invocation 1
      Printing 5 Random Numbers Between 0 and 99 25 95 13 60 67
      Invocation 2
      Printing 5 Random Numbers Between 0 and 99 17 10 21 96 15
      Generate Random number bounded with a seed
      Bellow function will generate bounded 5 random numbers but since we are setting a seed, if the seed is same on multiple invocation then each invocation will generate the same set of random numbers.
      public static void generateRadomWithSeed(long seed) {
      	System.out.println("\nPrinting 5 Random Numbers Between 0 and 99 with seed");
      	Random generator = new Random(seed);
      	for (int i = 0; i < 5; i++) {
      		System.out.print(generator.nextInt(100) + " ");
      	}
      }
      Invocation 1
      Printing 5 Random Numbers Between 0 and 99 with seed 4 62 52 3 58 67
      Invocation 2
      Printing 5 Random Numbers Between 0 and 99 with seed 4 62 52 3 58 67
      Summary
      • If we want to generate the same set of random numbers, we can set seed.
      • Test cases can use seed to make sure it gets same set of random numbers.
      • We can have bounded or unbounded random numbers.

      Java Threads Print Alternative Odd Even Numbers

      This article shows how to print Even and Odd numbers alternatively using Java. It uses Two Java threads and a Class with two methods to print even numbers and odd numbers respectively.

      What we are trying to achieve

      We want to print even and odd numbers alternatively but using two threads. Essentially it is the interaction between two threads utilizing the wait() and notify() methods. One thread completes a task (printing a single even number) then it is put on wait state so that the other thread can get a chance to do its job (printing odd number) and this goes on until we are done with printing a set of numbers determined by max.
      How it will work
      • Print Class (Print.java) with two synchronized methods even() and odd() which print even or odd numbers respectively.
      • Each method is synchronized so that two threads cannot execute them concurrently.
      • Each method first calls notifyAll() to so that other threads that are waiting can be wake up.
      • It then prints a number (even or odd) and then calls the wait() method on the current thread so it goes to waiting state.

      Java Code

      Print.java
      This Class essentially has two synchronized methods. The constructor of this class takes a max number as a parameter. This max number is the limit to which the numbers will be printed. It has two synchronized methods to print even and odd numbers alternatively.
      class Print {
        int max;
      
        public Print(int max) {
          this.max = max;
        }
      
        public synchronized void even() throws InterruptedException {
          for (int i = 0; i <= max; i++) {
            notifyAll();
            if (i % 2 == 0)
              System.out.println(Thread.currentThread().getName() + ":: " + i);
            wait();
          }
        }
      
        public synchronized void odd() throws InterruptedException {
          for (int i = 0; i <= max; i++) {
            notifyAll();
            if (i % 2 != 0)
              System.out.println(Thread.currentThread().getName() + ":: " + i);
            wait();
          }
        }
      }
      Threads.java
      Here we are creating an instance of Print class and creating two Threads. From the first thread, we are calling print.even() method, from the second thread we are calling print.odd() method.
      Print print = new Print(10);
      
      //Thread to print even numbers
      Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
          try {
            print.even();
          } catch (InterruptedException e) {
          }
        }
      });
      
      //Thread to print odd numbers
      Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
          try {
            print.odd();
          } catch (InterruptedException e) {
          }
        }
      });
      
      t1.setName("Even Thread");
      t2.setName(" Odd Thread");
      
      t1.start();
      t2.start();
      Console Output
      Even Thread:: 0
      Odd Thread:: 1
      Even Thread:: 2
      Odd Thread:: 3
      Even Thread:: 4
      Odd Thread:: 5
      Even Thread:: 6
      Odd Thread:: 7
      Even Thread:: 8
      Odd Thread:: 9
      Even Thread:: 10
      Conclusion
      • From the odd() or even () method we have to first call notify or notifyAll() first.
      • Both odd() or even() method should be synchronized otherwise calling notifyAll() or wait() will throw exception

      Java Thread States

      A thread in Java at any point of time exists in any one of the 6 states. This article give a quick introduction of different Thread states and respective methods which results in threads state change.
      Following are the states of a Java Thread
      • New: Thre thread is just created by using start() method on the tread
      • Runnable: Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as a processor.
      • Blocked: A thread in the blocked state is waiting for a monitor lock
      • Waiting: A thread is in the waiting state due to calling one of the following methods:
        Object.wait() with no timeout
        Thread.join() with no timeout
        LockSupport.park
      • Timed Waiting: A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:Thread.sleep (long)
        Object.wait (long)
        Thread.join (long)
        LockSupport.parkNanos
        LockSupport.parkUntil
      • Terminated: The thread has completed execution