How to convert list to read-only list in Java?

 
By using Collections class we can convert List to read-only List. This can done by using Collections.unmodifiableList(list) function from Collections class. By this we can't add or remove any element from the List. Not only List we can make other Collection Objects like Map, Set also to read-only as like below.

Collections.unmodifiableMap(map);
Collections.unmodifiableSet(set);
Collections.unmodifiableSortedMap(sortedMap);
Collections.unmodifiableSortedSet(sortedSet);

Lets see small example how to convert list to read-only list.


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ReadOnlyList {

 public static void main(String[] args) {
  
  List<String> list = new ArrayList<String>();
  list.add("java");
  list.add("discover");
  list.add("threads");
  list.add("oops");
  list.add("servlet");
  
  System.out.println("LIST : "+list);
  
  // Removing "oops" from from list
  list.remove(3);
  
  System.out.println("LIST : "+list);
    
  // Making list to read-only
  list = Collections.unmodifiableList(list);

  // trying to removing "threds" from list
  list.remove(2);
    
  System.out.println("LIST : "+list);
 }
}


OUTPUT:


LIST : [java, discover, threads, oops, servlet]
LIST : [java, discover, threads, servlet]
Exception in thread "main" java.lang.UnsupportedOperationException


If we seen in above program we have added 5 values in list and we have removed 1 value "oops" from the list. Next we have converted list to read-only list by using unmodifiableList() method. Later when we try to remove "discover" value it throws UnsupportedOperationException because of read-only list. Even we can't add any value to this list. 




Daemon Thread in Java

 
Basically in Java there are 2 types of threads and they are Daemon Thread and non-Daemon Thread (User threads). Daemon threads are nothing but service provider for other threads to perform their task under same process like Garbage collection etc., Any Java thread can be a daemon thread and daemon threads life depends on user threads. It will be alive until all other threads are running and JVM will terminate daemon thread automatically once all other threads died. Some of the points to be remembered about daemon thread are 

  • Daemon threads are low priority threads. 
  • Daemon threads life depends on all other user threads (non-daemon threads) in same process.
  • Finally it provides only service to other user threads and nothing more than that.  
  • To specify the thread as daemon thread, just call the setDaemon method with the argument "true"  like  ( Thread.setDaemon(true) ).
  • Setting daemon should be done before starting the Thread, else it will throw IllegalThreadStateException exception. 
  • JVM will automatically exit the process once all user threads are completed and it won't wait for any Daemon thread to complete, no matter how many Daemon threads are running. 

Lets see small example with creating Daemon Thread and user threads under same process and lets see how its work.


public class DaemonThreadTest extends Thread{
 
 String daemonFlag = "";
 
 public DaemonThreadTest() { }
 
 public DaemonThreadTest(String daemonFlag) {
  this.daemonFlag = daemonFlag;
 }
 
 public void run() {
  if(daemonFlag.equals("daemon")){
   while(true){    
    try {
     System.out.println("Daemon Thread Running !!!");
     Thread.sleep(500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }else{
   for(int i=0;i<5;i++){
    try {
     System.out.println("User Thread Running !");
     Thread.sleep(500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }
 }
 
 public static void main(String args[]){
    
  DaemonThreadTest daemonThread = new DaemonThreadTest("daemon");
  DaemonThreadTest userThread1 = new DaemonThreadTest();
  DaemonThreadTest userThread2 = new DaemonThreadTest();
  
  // Setting Daemon thread;
  daemonThread.setDaemon(true);
  
  daemonThread.start();
  userThread1.start();
  userThread2.start();
 }
}


OUTPUT:


Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!

In above sample program we can see Daemon Thread we have set in infinite loop and user threads under looping for 5 times. One all other user thread complete Daemon Thread has be terminated automatically by JVM and process get completed. No more Daemon Thread is running. 

Executing Unix command through Java


In this tutorial we will see about executing Unix command through Java program and printing the output as same as Unix shell command printing. We can achieve by using Process class in Java. 

Process class provides the methods for performing 
standard input from the given process, 
performing standard output to the process, 
waiting for the process to complete its task, 
checking exit status of the process and 
destroying the process (normally its killing the process).

Constructor in Process class:
Process()

Method in Process class:
abstract InputStream getInputStream()
Used to get the standard input stream of sub-process.

abstract OutputStream getOutputStream()
Used to get the standard output stream of the sub-process.

abstract InputStream getErrorStream()
Used to get the standard error stream of the sub-process.

abstract void destroy()
Used to kill the sub-process.

abstract int exitValue()
Returns the exit value for the sub-process.

abstract int waitFor()
Makes current thread to wait, if necessary, until the process represented by this Process object has terminated.


Now lets see about how to execute Unix command using Process class in Java with simple example of listing folder and files from the current Folder. Second output will show you Error Stream result when we try to unzip a file.


import java.io.InputStream;

public class UnixCommandThroughJava {

 public static void main (String args[]) {
     
  String unixCommand = "ls -lh";
     InputStream in = null;
     
     try {
         StringBuilder commandResult = new StringBuilder();
         
         Process p = Runtime.getRuntime().exec(unixCommand, null);
         
         int returnVal = p.waitFor();
         
         if (returnVal == 0){ // no error           
             in = p.getInputStream();
         }else{     // If any error occurred 
             in = p.getErrorStream();
         }
         
         int readInt;
         while ((readInt = in.read()) != -1){
             commandResult.append((char)readInt);                
         }
         
         System.out.println("COMMAND : " + unixCommand + "\n\nOUTPUT : \n" + commandResult.toString());
          
         in.close();
     
     } catch (Exception e) {
         System.out.println("An exception occured while executing command " + unixCommand);
         e.printStackTrace();
     }
 }
}


OUTPUT:


Executing Unix command through Java


Executing Unix command through Java





Heap and Stack in Java

 

We are discussing few interview questions from our earlier tutorials and its a follow-up with same interview questions in Java. Questions are 

How memory managed in java? 
What is Heap and Stack memory? 
What will be stored in Heap and Stack?
Determine the size of Heap and Stack?
Stack vs Heap Pros and Cons?
When to use Heap and Stack?

This is one of the important questions which asked in most of the Java interviews and later interviewer may jump into asking question in Operating System(OS) level memory management also. Lets see above questions one by one and finally its a simple programs where we all can discuss about the memory allocated for it in Java.

How memory managed in Java?
Stack and Heap are the memories allocated by OS to JVM and they both are stored in the computer's RAM (Random Access Memory). 

What is Heap and Stack memory?
Stack:
It's a special region of computer's memory that stores temporary variables created by each functions. Stack uses "FILO" (First In Last Out) data structure, where its managed and optimized by CPU closely.

Heap:
Heap is a region of computer's memory that is not managed automatically by programmer, and is not as tightly managed by the CPU. It is a more free-floating region of memory.


What will be stored in Heap and Stack memory?
Stack:
Methods and the local variables are stored in stack. Also it is to be remembered that the variable references primitive or object references will be stored in Stack.  

Heap:
Objects and its instance variable are stored in Heap. In Java 6 due to "escape analysis" optimization, sometimes objects will be stores in Stack also.


Determine the size of Heap and Stack?
Stack:
Stack is usually pre-allocated and limited in size, because by definition it must be contiguous memory. Also depends on the language, compiler, operating system and architecture. 

Heap:
In general Heap will be dynamically allocated and constantly changing in size. 


Stack vs Heap Pros and Cons?
Stack:
Very fast in access.
Explicitly can't de-allocate variables allocated in Stack.
Memory fragmentation will not happen in Stack, since its managed efficiently by CPU.
Stack size is limited depending on OS.
If Stack runs out of memory, then this leeds to stack overflow could cause program to crash.

Heap:
Slower in access compared to Stack.
No limited on memory size which will be dynamically allocated. 
Heap could cause fragmentation problem, which occurs when memory on the heap is being stored as non-contiguous blocks. 

When to use Heap and Stack?
Its better to choice Stack when we use less memory or small amount of data in usage. Suppose if we don't know about the size or application uses large amount of memory like dynamic array or collections then we need to go for Heap. 


Lets discuss:


public class MyProgram {
 
 private static int value = 10;
 private String str = new String("Java Discover");
 private String name = "Heap and Stack";
 
 public void sayHello(){
  System.out.println("Hello, Java Discover !!!");
 }
 
 public static void main(String[] args) {
  
  String country = "India";
  
  MyProgram obj1;
  
  MyProgram obj2 = new MyProgram();
  obj2.sayHello();
 }
}



Lets comment on the memory usage on above program as what will be stored in Stack and Heap?





Actual use of interface in Java


We may come across with this interview question as "What is the actual use of interface in Java?". By this we may be thinking of, its an alternate for multiple interface which Java doesn't have and we can implement multiple interfaces in a Java class etc.,. Apart from these answers if we see in Object Oriented interface allows to use classes in different hierarchies by Polymorphism. Lets see simple example as how its works and interface used here



public interface Animal { 
 
 public int runningSpeed();
}

public class Horse implements Animal{

 @Override
 public int runningSpeed() {
  return 55;
 }
}

public class Zebra implements Animal{

 @Override
 public int runningSpeed() {
  return 40;
 }
}

public class AnimalsSpeed {
 
 public static void main(String[] args) {
  
  Animal a1 = new Horse();
  Animal a2 = new Zebra();
  
  System.out.println("Horse Speed "+a1.runningSpeed() + " mph");
  System.out.println("Zebra Speed "+a2.runningSpeed() + " mph");
  
 }
}

OUTPUT:

Horse Speed 55 mph
Zebra Speed 40 mph


If we see above example any number of classes, across class hierarchies could implement Animal interface in their own specific way. But still be used by some caller in a uniform way and by perspective of caller, it's just a Animal interface as we can see in AnimalsSpeed class. 

       Animal a1 = new Horse();
Animal a2 = new Zebra();

Welcome your comments for more use of interface in Java.




Using log4j API Logger


In each and every applications we will be seen logger to record the different types of logs like error, information, debug etc., In this tutorial we will see how to use Logger log4j API in our application and its usage. 



There are mainly 3 components like loggers, appenders and layouts. All these 3 components work together to enable developers to log messages according to message type and level and to control at run-time as how these messages are formatted and where they are stored. All these appender or logger settings will be made in the file called log4j.properties file. 

The advantage of using logger over System.out.print is to disable certain log statements while allowing others to print unhindered. This capability assumes that the logging space, that is, the space of all possible logging statements, is categorized according to some developer-chosen criteria. Loggers are named entities. Logger names are case-sensitive and they follow the hierarchical naming rule ie., "A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger." as example given below


log4j.rootCategory=DEBUG, CONSOLE, TESTING 

log4j.logger.org.apache.commons.validator=DEBUG, CONSOLE

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=WARN
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=- %-5p %m%n

log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=/user/local/logFile.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=DEBUG
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%15.15t] %-5p %c %x - %m%n

log4j.appender.TESTING=org.apache.log4j.RollingFileAppender
log4j.appender.TESTING.File=/user/local/application.log
log4j.appender.TESTING.Append=true
log4j.appender.TESTING.MaxFileSize=1024KB
log4j.appender.TESTING.MaxBackupIndex=10
log4j.appender.TESTING.layout=org.apache.log4j.PatternLayout
log4j.appender.TESTING.layout.ConversionPattern=[%d{EEE MMM d HH:mm:ss yyyy}] [%-5p] %c{1}.java(): %m%n


Set of possible logger levels are:
TRACE,
DEBUG,
INFO,
WARN,
ERROR and
FATAL

For more appenders and how to inclide in our project we can get it from the following link - http://logging.apache.org/log4j/1.2/manual.html

Now lets see simple example for how to start with the log4j API in our application with simple example to redirect all logs to a specified log file. For that first we need log4j.jar file (can use any latest version). I have used log4j-1.2.13.jar and we need to create log4j.properties file under classes directory.


log4j.rootLogger=INFO, file
 
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=D:\\logs\\application.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n



import java.util.Date;
import org.apache.log4j.Logger;

public class LogTest {

 static Logger logger = Logger.getLogger(LogTest.class.getName());
 
 public static void main(String[] args) {
  logger.info("Application starts .....................");
  
  long stime = new Date().getTime();
  
  try{
   logger.info("Process Started !!!");
   Thread.sleep(5300);
   logger.info("Process completed !!!");
  }catch (Exception e) {
   logger.error("Exception Occured : "+e.getMessage());
  }
  
  long etime = new Date().getTime();
  float diff = (float)(etime - stime)/1000;
  logger.info("Total time to complete ::: "+ diff +" second(s)");
  
  logger.info("Application Ends .......................");
 } 
}


OUTPUT:


log4j API Logger




File and Folder search through Java Code


Recently we can see most of the first round interview for experienced candidate will be written or programming test. One of the simple and easy programming question asked in interview is to search files and Folder from the given drive using java code.

Question:
Need to search File or Folder or both from the given root directory. 
Input parameters are File/Folder/Both and file to search and root directly.
Program should be run from command prompt. 
Need to use Java regular expression to match file or folder names.

By based on above conditions candidate need to write the code within an hour. In tutorial we will see a sample program for the above question.


import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileFolderSearch {
 
 private List<String> searchResult = new ArrayList<String>();
 private Pattern pattern;  
 private Matcher matcher; 

 public static void main(String[] args) {
  
  if(args.length < 3){
   System.err.println("Insufficient input. Please input search type and root folder");
   System.err.println("Example : FileFolderSearch <file/folder/both> <D:\\> <^*file*.j*> ");
   System.exit(0);
  }
  if(!(args[0].equalsIgnoreCase("file") || args[0].equalsIgnoreCase("folder") || args[0].equalsIgnoreCase("both"))){
   System.err.println("Invalid search type. Please enter file/folder/both");
   System.exit(0);
  }  
  File rFolder = new File(args[1]);
  if((!rFolder.isDirectory())){
   System.err.println("Invalid root folder or Folder not exisit !!!");
   System.exit(0);
  }
   
  String sType = args[0];
  String fileName = args[2];
  FileFolderSearch obj = new FileFolderSearch();
  obj.searchMyItems(rFolder, fileName, sType);
  obj.printSearchResult();
  
 }
 
 /**
  * Method to search files and folder from root directory 
  * @param target
  * @param fileName
  * @param sType
  */
 public void searchMyItems(File target, String fileName, String sType)     
    {     
        if(target != null && target.isDirectory()) {     
            File[] files = target.listFiles();  
            if (files != null) {  
                for(File file:files) {     
                        pattern = Pattern.compile(fileName);     
                        matcher = pattern.matcher(file.getName());     
                        if(matcher.find()){
                         if(sType.equalsIgnoreCase("both")){
                                searchResult.add(file.getAbsoluteFile().toString());
                         }else if(sType.equalsIgnoreCase("file") && (file.isFile()) ){
                          searchResult.add(file.getAbsoluteFile().toString());
                         }else if(sType.equalsIgnoreCase("folder") && (file.isDirectory()) ){
                          searchResult.add(file.getAbsoluteFile().toString());
                         }
                        }
                    if(file.isDirectory()){     
                     searchMyItems(file, fileName, sType);
                    }
                }     
            }  
        }     
    }    
 
 
 /**
  * Method used to search file/folder from the given root folder
  * @param sType
  * @param rFolder
  * @return
  */ 
 public void searchMyItems(String sType, File rFolder){
  try{
   File[] ff = rFolder.listFiles();
    for(int i=0;i<ff.length;i++){
     if(sType.equalsIgnoreCase("both") )
     if(new File(ff[i].getName()).isDirectory()){
      searchMyItems(sType, new File(ff[i].getName()));
     }
     System.out.println(ff[i].getName());  
    }
  }catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 /**
  * Method used to print all search result items
  * @param searchResult
  */
 public void printSearchResult(){
  
  // check for no. of search items stored in list.
  if(searchResult.size() == 0){
   System.out.println("Oops, NOT FOUND !!!");
   return;
  }
  
  // Print all search items
  for (Iterator<String> iterator = searchResult.iterator(); iterator.hasNext();) {
   String string = (String) iterator.next();
   System.out.println(string);
  }
  
  System.out.println("Total no. of items found : "+searchResult.size());
 }
}


OUTPUT:


File and Folder search through Java Code