Advance Java

ThreadLocal Example with Java 8

Posted on Updated on

What is ThreadLocal in Java?

ThreadLocal is a specially provisioned functionality by JVM to provide an isolated storage space for threads only. like the value of instance scoped variable are bound to a given instance of a class only. each object has its only values and they can not see each other value. so is the concept of ThreadLocal variables, they are local to the thread in the sense of object instances other thread except for the one which created it, can not see it.

Like request, session and application scope of any Object, We can define a Thread Scope of any Object thus Object visibility would be only within the Thread and Every Thread has it execution life cycle, After a thread goes away, all of its copies of thread-local instances are subject to garbage collection (unless other references to these copies exist).

Although we usually create a Synchronize  Object for Thread safety in MultiThread application therefore only one Thread can be obtained a monitor to access shared Object Since shared Object is not thread safe.

In Java 8, A new method is introdued  to determine the initial value.

public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
    return new SuppliedThreadLocal<>(supplier);
}

Here, a simple ThreadLocal example of Java 8 is demonstrated that how each Thread gets own ThreadLocal copy of variable and value remain same even in Iteration process and each thread are executing separately on the ThreadLocal variable.

 

import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

/**
 * Created by MYPC on 5/29/2017.
 */
public class ThreadLocalExample {
    private static final AtomicInteger transactionId = new AtomicInteger(10000);
    private static final ThreadLocal threadLocal = ThreadLocal.withInitial(() -> transactionId.getAndIncrement());

    public static void main(String[] args) {

        // Thread 1 executing and getting same Transaction Id for all iteration
        new Thread(() -> IntStream.range(0, 3).forEach(val -> {
            System.out.println(Thread.currentThread().getName() + " > " + threadLocal.get());
        })).start();

        // Thread 2 executing and getting same Transaction Id for all iteration
        new Thread(() -> IntStream.range(0, 3).forEach(val -> {
            System.out.println(Thread.currentThread().getName() + " > " + threadLocal.get());
        })).start();
        // Thread 3 executing and getting same Transaction Id for all iteration
        new Thread(() -> IntStream.range(0, 3).forEach(val -> {
            System.out.println(Thread.currentThread().getName() + " > " + threadLocal.get());
        })).start();

    }
}
Execution Output :-

Thread-1 > 10001
Thread-1 > 10001
Thread-1 > 10001
Thread-0 > 10000
Thread-0 > 10000
Thread-0 > 10000
Thread-2 > 10002
Thread-2 > 10002
Thread-2 > 10002

Reading/Writing Files using FileChannel

Posted on

6db3a-download

There are multiple ways to reading/writing a file in Java. Usually, we used java.lang.IO package to read/write a file but as my last experience with copying a large file size (>256 MB ) into some other file location or on a network.

 

As we also tried to used java.lang.io package to get this job done but we were unable to copy the file in a Network location, there were performance issues.

http://stackoverflow.com/questions/1605332/java-nio-filechannel-versus-fileoutputstream-performance-usefulness

And finally, I got an alternative way to copy a file into a Network location  i.e FileChannel . its provide a better performance than InputStream/OutputStream.

Some interesting points about java.nio or FileChannel:-

  1. it’s a buffer-oriented, means- same Buffer is used to reading / writing so you can move back or forth in the Buffer as you need to.  usee flip() method to get the pointer to next position.
  2. It’s a non-blocking, i.e means a Thread request to reading data from Channel then only get what is currently available in a buffer, if data is not available then rather than blocking until data get available in buffer, Thread goes on and do something else in meantime. The same is true for non-blocking writing. A thread can request that some data be written to a channel, but not wait for it to be fully written. The thread can then go on and do something else in the mean time.
  3. Concurrent processing can be done in FileChannel which is safe for use.
  4. Channels can be read and written asynchronously.

Below example demonstrated how to write into a file using FileChannel.


 import java.io.File;
        import java.io.FileNotFoundException;
        import java.io.IOException;
        import java.io.RandomAccessFile;
        import java.nio.ByteBuffer;
        import java.nio.channels.FileChannel;
        import java.nio.channels.WritableByteChannel;
        
        /**
         * Created by kumajye on 10/01/2017.
         */
        public class FileChannelTest {
            // This is a Filer location where write operation to be done.
            private static final String FILER_LOCATION = "C:\\documents\\test";
            // This is a text message that to be written in filer location file.
            private static final String MESSAGE_WRITE_ON_FILER = "Operation has been committed.";
        
            public static void main(String[] args) throws FileNotFoundException {
                // Initialized the File and File Channel
                RandomAccessFile randomAccessFileOutputFile = null;
                FileChannel outputFileChannel = null;
                try {
                    // Create a random access file with 'rw' permission..
                    randomAccessFileOutputFile = new RandomAccessFile(FILER_LOCATION + File.separator + "readme.txt", "rw");
                    outputFileChannel = randomAccessFileOutputFile.getChannel();
                    //Read line of code one by one and converted it into byte array to write into FileChannel.
                    final byte[] bytes = (MESSAGE_WRITE_ON_FILER + System.lineSeparator()).getBytes();
                    // Defined a new buffer capacity.
                    ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
                    // Put byte array into butter array.
                    buffer.put(bytes);
                    // its flip the buffer and set the position to zero for next write operation.
                    buffer.flip();
                    /**
                     * Writes a sequence of bytes to this channel from the given buffer.
                     */
                    outputFileChannel.write(buffer);
                    System.out.println("File Write Operation is done!!");
        
                } catch (IOException ex) {
                    System.out.println("Oops Unable to proceed file write Operation due to ->" + ex.getMessage());
                } finally {
                    try {
                        outputFileChannel.close();
                        randomAccessFileOutputFile.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
        
                }
        
            }
        
        }


How to Schedule Future Task Using java.util.Timer

Posted on Updated on

java.util.Timer

6db3a-downloadA java.util.Timer class provides a facility to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals. Timer class uses java.util.TaskQueue to add tasks at given regular interval and at any time there can be only one thread running the TimerTask.

TimerTask :-

java.util.TimerTask is an abstract class that implements Runnable interface and we need to extend this class to create our own TimerTask that can be scheduled using java Timer class.

Key points :-

  • java.util.Timer is a thread safe – means, multiple threads can share a single Timer object without the need for external synchronization.
  • This class schedules tasks for one-time execution, or for repeated execution at regular intervals.
  • All constructors start a timer thread.
  • This class does not offer real-time guarantees: it schedules tasks using the Object.wait(long) method.

Class Constructors :-

  • Timer() – Create a new Timer
  • Timer(boolean isDaemon) – Creates a new timer whose associated thread may be specified to run as a daemon.
  • Timer(String name) – Creates a new timer whose associated thread has the specified name.
  • Timer(String name, boolean isDaemon) – Creates a new timer whose associated thread has the specified name, and may be specified to run as a daemon.

Class Methods :-

  • cancel() – Terminates this timer, discarding any currently scheduled tasks.
  • purge() – Removes all cancelled tasks from this timer’s task queue.
  • schedule(TimerTask task,Date time) –  Schedules the specified task for execution at the specified time.
  • schedule(TimerTask task,Date firstTime,long period) – Schedules the specified task for repeated fixed-delay execution, beginning at the specified time.
  • schedule(TimerTask task,long delay) – Schedules the specified task for execution after the specified delay.
  • schedule(TimerTask task,long delay,long period) – Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay.
  • scheduleAtFixedRate(TimerTask task, Date firstTime, long period) – Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.
  • scheduleAtFixedRate(TimerTask task, long delay, long period) – Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.

Example :-

Here, we scheduled a non-repeated future task that will be print on a Console after the delay of 10 min. TimerTask is a task that can be scheduled for one-time or repeated execution by a Timer and it is a sub-class of Runnable Interface.


import java.util.Timer;
import java.util.TimerTask;
/**
 * Created by MYPC on 10/8/2016.
 */
public class FutureExecutionExample {
    public static void main(String[] args) {
        Timer t = new Timer();
        t.schedule(new TimerTask() {
                  @Override
                  public void run() {
                  // Execute given scheduled task after 10 min.
                  System.out.println(" Run specific task at given time." + System.currentTimeMillis());
               }
             }
         , 10 * 60 * 1000);  // 10 mins
    }
}


Let assume, we create a Timer to run every 2 seconds interval but the execution of Thread takes 3 seconds then Timer keeping adding a schedule task in queue and as soon as Thread execution get finished then, it’s notify to queue to execute next one.


Timer t = new Timer();
t.schedule(new TimerTask() {
       @Override
       public void run() {
           System.out.println(" Run specific task at given time." + System.currentTimeMillis());
           try {
               Thread.sleep(3000);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }

, 1000,2000);  // After 1 second given task will be executed and every 2 second given task execution repeat.
}


How to run external JAVA program by using ProcessBuilder

Posted on

java-logojava.lang.ProcessBuilder was introduced in Java 1.5 version, is used to create an Operating System Process. see Java API

Before going on example section, see ProcessBuilder attributes:-

 

Each ProcessBuilder instance manages a collection of process attributes. The start() method creates a new Process instance with those attributes. The start() method can be invoked repeatedly from the same instance to create new subprocesses with identical or related attributes.

Each process builder manages these process attributes:

  • a command, a list of strings which signifies the external program file to be invoked and its arguments, if any. Which string lists represent a valid operating system command is system-dependent. For example, it is common for each conceptual argument to be an element in this list, but there are operating systems where programs are expected to tokenize command line strings themselves – on such a system a Java implementation might require commands to contain exactly two elements.
  • an environment, which is a system-dependent mapping from variables to values. The initial value is a copy of the environment of the current process (see System.getenv()).
  • a working directory. The default value is the current working directory of the current process, usually the directory named by the system property user.dir.
  • a source of standard input. By default, the subprocess reads input from a pipe. Java code can access this pipe via the output stream returned by Process.getOutputStream(). However, standard input may be redirected to another source using redirectInput. In this case, Process.getOutputStream() will return a null output stream, for which:
    • the write methods always throw IOException
    • the close method does nothing
  • a destination for standard output and standard error. By default, the subprocess writes standard output and standard error to pipes. Java code can access these pipes via the input streams returned by Process.getInputStream() and Process.getErrorStream(). However, standard output and standard error may be redirected to other destinations using redirectOutput andredirectError. In this case, Process.getInputStream() and/or Process.getErrorStream() will return a null input stream, for which:
    • the read methods always return -1
    • the available method always returns 0
    • the close method does nothing
  • a redirectErrorStream property. Initially, this property is false, meaning that the standard output and error output of a subprocess are sent to two separate streams, which can be accessed using the Process.getInputStream() and Process.getErrorStream() methods.If the value is set to true, then:
    • standard error is merged with the standard output and always sent to the same destination (this makes it easier to correlate error messages with the corresponding output)
    • the common destination of standard error and standard output can be redirected using redirectOutput
    • any redirection set by the redirectError method is ignored when creating a subprocess
    • the stream returned from Process.getErrorStream() will always be a null input stream

Following example demonstrate how to run external Java program, Same way we can run any external program which must be set in OS environment.

Before running this program on your machine, make sure that JAVA_HOME must be set in your OS environment.


package com.itexpert.exam;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class JavaProcessBuilder {
/**
* Provide absolute JAVA file path
*/
private static final String JAVA_FILE_LOCATION = "D:\\Test.java";

public static void main(String args[]) throws IOException{
String command[] = {"javac",JAVA_FILE_LOCATION};
ProcessBuilder processBuilder = new ProcessBuilder(command);

Process process = processBuilder.start();
/**
* Check if any errors or compilation errors encounter then print on Console.
*/

if( process.getErrorStream().read() != -1 ){
print("Compilation Errors",process.getErrorStream());
}
/**
* Check if javac process execute successfully or Not
* 0 - successful
*/
if( process.exitValue() == 0 ){
process = new ProcessBuilder(new String[]{"java","-cp","d:\\","Test"}).start();
/** Check if RuntimeException or Errors encounter during execution then print errors on console
* Otherwise print Output
*/
if( process.getErrorStream().read() != -1 ){
print("Errors ",process.getErrorStream());
}
else{
print("Output ",process.getInputStream());
}

}
}

private static void print(String status,InputStream input) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(input));
System.out.println("************* "+status+"***********************");
String line = null;
while((line = in.readLine()) != null ){
System.out.println(line);
}
in.close();
}

}

External Java Program source code below:-


public class Test {
public static void main(String args[]){
System.out.println("Hello, How are you !!!");
}
}


Output if Compilation done successfully


************* Output ***********************
Hello, How are you !!!

Suppose, if we pass incorrect file “Test1” through command[] object which does not exist in your given path then-


************* Compilation Errors***********************
avac: file not found: D:\Test1.java
Usage: javac 
use -help for a list of possible options

Suppose, if any compilation errors exist in Java file then-


************* Compilation Errors***********************
:\Test.java:3: error: cannot find symbol
		System.out.printlna("Hello, How are you !!!");
		          ^
  symbol:   method printlna(String)
  location: variable out of type PrintStream
1 error

Thanks !!

How to Implement JMS with Tomcat – Durable Subscription Example

Posted on Updated on

java-logoIn this A Durable Subscription Example, we will see how to implement JMS with Tomcat.  read What is JMS in previous article.

Tomcat doesn’t supports JMS itself but using some external library ( ActiveMQ ) we can accomplish it. here we use JMS vendor – ActiveMQ

so, before getting started, download couple of libraries and put it into Tocat/lib directory and Project classpath.

or Copy and paste below Maven Dependencies in your pom.xml file:-

 <dependency>
 <groupId>commons-logging</groupId>
 <artifactId>commons-logging</artifactId>
 <version>1.2</version>
 </dependency>
 <dependency>
 <groupId>org.apache.activemq</groupId>
 <artifactId>activemq-all</artifactId>
 <version>5.11.1</version>
 </dependency>

Next, add the resource below to conf/server.xml:

<GlobalNamingResources>
 <Resource name="ConnectionFactory" auth="Container"
 type="org.apache.activemq.ActiveMQConnectionFactory" description="JMS
 Connection Factory " factory="org.apache.activemq.jndi.JNDIReferenceFactory"
 brokerurl="tcp://localhost:61617"
 brokerName="ActiveMQBroker"
 useEmbeddedBroker="false"/>

 <Resource name="jms/topic/ITExpertsTopic" auth="Container"
 type="org.apache.activemq.command.ActiveMQTopic" factory="org.apache.activemq.jndi.JNDIReferenceFactory"
 physicalName="APP.JMS.TOPIC" />

 <Resource name="jms/queue/ITExpertsQueue" auth="Container"
 type="org.apache.activemq.command.ActiveMQQueue" factory="org.apache.activemq.jndi.JNDIReferenceFactory"
 physicalName=" APP.JMS.QUEUE" />

 </GlobalNamingResources>

Next, add this code to context.xml:

<ResourceLink global="jms/ConnectionFactory" name="jms/ConnectionFactory" type="javax.jms.ConnectionFactory"/>
<ResourceLink global="jms/topic/ITExpertsTopic" name="jms/topic/ITExpertsTopic" type="javax.jms.Topic"/>
<ResourceLink global="jms/queue/ITExpertsQueue" name="jms/queue/ITExpertsQueue" type="javax.jms.Queue"/>

Next, We need to add ActiveMQ props into tomcat class path:

set JAVA_OPTS=-Dwebconsole.type=properties -Dwebconsole.jms.url=”tcp://localhost:61617″ -Dwebconsole.jmx.url=”service:jmx:rmi:///jndi/rmi://localhost:1099/ jmxrmi”

Below are code snippet of A Durable Subscription Example :-

MessageProducerClient.Java

package com.itexperts.jms;
/**
 * 
 * @author #Ajay
 *
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.activemq.broker.BrokerService;

public class MessageProducerClient {

 public static Properties getProp() {
 Properties props = new Properties();
 props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
 "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
 props.setProperty(Context.PROVIDER_URL, "tcp://localhost:61617");
 return props;
 }

 public static void initBroker() throws Exception {
 BrokerService broker = new BrokerService();
 // configure the broker
 broker.addConnector("tcp://localhost:61617");
 broker.start();
 }

 public static void main(String args[]) {

 Connection connection = null;
 try {
 initBroker();
 InitialContext jndiContext = new InitialContext(getProp());
 ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext
 .lookup("ConnectionFactory");
 connection = connectionFactory.createConnection();
 connection.setClientID("durable");
 Session session = connection.createSession(false,
 Session.AUTO_ACKNOWLEDGE);
 Destination destination = session
 .createTopic("jms/topic/ITExpertsTopic");
 MessageProducer producer = session.createProducer(destination);
 TextMessage msg = session.createTextMessage();
 msg.setText("Hello, This is JMS example !!");
 BufferedReader reader = new BufferedReader(new InputStreamReader(
 System.in));
 while (true) {
 System.out
 .println("Enter Message to Topic or Press 'Q' for Close this Session");
 String input = reader.readLine();
 if ("Q".equalsIgnoreCase(input.trim())) {
 break;
 }
 msg.setText(input);
 producer.send(msg);
 }
 } catch (JMSException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 } catch (NamingException e) {
 e.printStackTrace();
 } catch (Exception e) {
 e.printStackTrace();
 } finally {
 try {
 if (connection != null) {
 connection.close();
 }
 } catch (JMSException e) {
 e.printStackTrace();
 }
 }

 }
}

MessageReceiverClient.Java


package com.itexperts.jms;

import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;

import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 
 * @author #Ajay
 *
 */
public class MessageReceiverClient {
 protected static final String url = "tcp://localhost:61617";

 public static void main(String args[]) {

 TopicConnection connection = null;
 try {
 ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(
 url);
 connection = factory.createTopicConnection();
 connection.setClientID("durable");
 connection.start();
 MessageConsumer consumer = null;
 Session session = connection.createTopicSession(false,
 Session.AUTO_ACKNOWLEDGE);
 Topic topic = session.createTopic("jms/topic/ITExpertsTopic");
 consumer = session.createDurableSubscriber(topic, "mySub");
 // consumer.setMessageListener(new ReceiverListener());

 // System.out.println(" Waiting for Message ...");
 // while(true){
 // Thread.sleep(1000);
 // }
 while (true) {
 TextMessage message = (TextMessage) consumer.receive();
 System.out.println(message.getText());
 }
 } catch (Exception e) {
 e.printStackTrace();
 } finally {
 try {
 if (connection != null) {
 connection.close();
 }
 } catch (JMSException e) {
 e.printStackTrace();
 }
 }

 }

}

Compile and run these two Java files separately in two command prompt.

Here you will see how durable topics works when a Sender/Producer send a bunch of messages while  Subscriber/ Receiver is not yet active.

Step 1: Compile and run MessageProducerClient.Java file. Send some message to durable using command prompt.

Step 2: Compile and run MessageReceiverClient.Java file. When you run this file then all messages that are retain on Destination Durable Topic get started consuming and print on console.

 

What is JMS – Java Message Service

Posted on Updated on

java-logoIn this tutorial, we will see the overview of JMS and it’s implementations. JMS was developed by Sun Microsystems that allows a Java programming language to communicate with other messaging systems. Mostly JMS enables in distributed application where two or more Software Components or Applications pointing to same Destination( i.e Queue/Topic/Durable) in the way to communicating to each other by sending or reading the message subsequently.

Suppose, A component sends a message to a destination, and the recipient can retrieve the message from the destination. However, the sender and the receiver do not have to be available at the same time in order to communicate. In fact, the sender does not need to know anything about the receiver; nor does the receiver need to know anything about the sender. The sender and the receiver need to know only which message format and which destination to use. In this respect, Durable Topic can be helpful which retains the messages while the Subscriber is not active. Once the Subscribers get activated then messages can be received from durable.

What is JMS?

Java message service enables loosely coupled communication between two or more systems. It provides reliable and asynchronous form of communication. There are two types of messaging models in JMS.

Point-to-Point Messaging Domain

Applications are built on the concept of message queues, senders, and receivers. Each message is send to a specific queue, and receiving systems consume messages from the queues established to hold their messages. Queues retain all messages sent to them until the messages are consumed by the receiver or expire. Here there is only one consumer for a message. If the receiver is not available at any point, message will remain in the message broker (Queue) and will be delivered to the consumer when it is available or free to process the message. Also receiver acknowledges the consumption on each message.

Publish/Subscribe Messaging Domain

Applications send message to a message broker called Topic. This topic publishes the message to all the subscribers. Topic retains the messages until it is delivered to the systems at the receiving end. Applications are loosely coupled and do not need to be on the same server. Message communications are handled by the message broker; in this case it is called a topic. A message can have multiple consumers and consumers will get the messages only after it gets subscribed and consumers need to remain active in order to get new messages.

 

Message can be consumed either two ways:-

  • Synchronously: A subscriber or a receiver explicitly fetches the message from the destination by calling the receive method. The receive method can block until a message arrives or can time out if a message does not arrive within a specified time limit.
  • Asynchronously: A client can register a message listener with a consumer. A message listener is similar to an event listener. Whenever a message arrives at the destination, the JMS provider delivers the message by calling the listener’s onMessage method, which acts on the contents of the message.

Building Block of JMS Application are:-

The JMS API Programming Model

Diagram of the JMS API programming model: connection factory, connection, session, message producer, message consumer, messages, and destinations

First we need to create a connection object using the ActiveMQConnectionFactory factory object. Then we create a session object.  Using the session object we set the message broker (Queue) and create the message sender object.

Below are some JMS Implementation in JAVA:-

How to sort Map by key and value in Java.

Posted on Updated on

java-logo

I believe, you have the knowledge of Map data structure  nevertheless sorting over Map’s Keys and Values is also most tricky and frequently asked interview question today. Since we know that Map does not guarantee any sorting order but we can do it by some additional programming logic ( it’s not recommended to sort over large dataset because feeding the data into Map and sort it again adding extra cost )

Although construction of Map is used to array of Entry Object containing Key and Value  object and a KeySet() represents a group of unique key data structure but not sorted and similarly values() represents a group of Value elements but also not sorted way.

Below, given a program that demonstrated how to sort Map’s Element by Key or Values.


package com.it.experts.map.sort;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class MapSorts {
   
    Map<String,String> map = new HashMap<String,String>();
    //SortedMap<String,String> map = new TreeMap(new MyCompatator());
    public static void main(String args[]){
       
    	MapSorts p = new MapSorts();
       
        p.map.put("g","f");
        p.map.put("z","u");
        p.map.put("e","z");
        p.map.put("c","e");
        p.map.put("b","b");
       
        //p.map=p.customKeySort(p.map); // default sorting 
        //p.map=p.customValueSort(p.map); // custom sorting by value
        p.map= p.customKeySort(p.map); // custom sorting by key
        Iterator it = p.map.keySet().iterator();
        while(it.hasNext()){
            String key = it.next();
            System.out.println(key+" >> "+p.map.get(key));
        }
       
    }

   
   
    public  Map<key,Val> DefaultKeySort(Map<key,Val> map){
       
        List keys = new ArrayList(map.keySet());
        Collections.sort(keys);
        Map sortedMap = new LinkedHashMap();
        for(Object key: keys){
            sortedMap.put(key, map.get(key));
        }
        return sortedMap;
       
    }
   
    public  Map<key,Val> customValueSort(Map<key,Val> map){
       
        List<Entry<key, Val>> Val = new ArrayList<Entry<key, Val>>(map.entrySet());
        Collections.sort(Val,new Comparator<Entry<key, Val>>() {

            @Override
            public int compare(Entry<key, Val> o1, Entry<key, Val> o2) {
                return o1.getValue().compareTo(o2.getKey());
            }
        });
        Map sortedMap = new LinkedHashMap();
        for(Map.Entry<key, Val> entity: Val){
            sortedMap.put(entity.getKey(), entity.getValue());
        }
        return sortedMap;
       
    }
   
   
    public  Map<key,Val> customKeySort(Map<key,Val> map){
       
        List list = new ArrayList(map.keySet());
        Collections.sort(list,new Comparator() {

            @Override
            public int compare(key o1, key o2) {
                return o1.compareTo(o2);
            }
        });
        Map sortedMap = new LinkedHashMap();
        for(key k: list){
            sortedMap.put(k, map.get(k));
        }
        return sortedMap;
       
    }}


I hope it will be helpful.