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





Difference between Comparator and Comparable interface in Java


Comparator and Comparable are two interfaces which used to implement Object sorting in Java. It used to sort Objects stored in any Collection classes like HashMap, HashTable, ArrayList etc., Whenever we implement Comparator interface then we need to implement compare (Object o1, Object o2) method and compareTo(Object o) method for Comparable interface. 
Going further we will discuss on differene between these 2 interface and lets see small example on how to use Comparator and Comprable interfaces. 

Difference:

  • Comparator interface used to compare any class Objects by compare (Object o1, Object o2) method, whereas Comparable interface to sort same class Objects by compareTo(Object o) method. 
  • Comparator defined in java.util package which says to use it as utility to sort Objects, while Comparable interface defined in java.lang package.
  • Comparable interface used to implement natural ordering of Object which used in Date, String and Wrapper classes in Java. If its a same class Objects then compareTo(Onject o) is a good practice to use it. 
  • Collections.sort(List) here objects will be sorted on the basis of CompareTo method in Comparable. Collections.sort(List, Comparator) here objects will be sorted on the basis of Compare method in Comparator.

Comparator Example:


import java.util.Comparator;

class Employee implements Comparator<Employee>{
 
 private String name;
 private int id;
 
 public Employee() {
 }
 
 public String getName() {
  return name;
 }
 public int getId() {
  return id;
 }
 public Employee(String name,int id){
  this.id=id;
  this.name=name;
 }
 
 // Sorting based on Employee Name
 @Override
 public int compare(Employee obj1, Employee obj2) {
     if(obj1.name.toString().compareTo(obj2.name.toString())>0){
      return 1;
     }else if(obj1.name.toString().compareTo(obj2.name.toString())<0){
      return -1;
     }else 
      return 0;     
 }
 
 // Sorting based on Employee Id
 /*@Override
 public int compare(Employee obj1, Employee obj2) {
  return obj1.id - obj2.id; 
 }*/
}



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

public class ComparatorTest  {

 public static void main(String[] args) {
  
  List <Employee>list = new ArrayList<Employee>();
  
  Employee e1 = new Employee("Raj",22);
  Employee e2 = new Employee("Anna",25);
  Employee e3 = new Employee("David",12);
  Employee e4 = new Employee("Steve",100);
  Employee e5 = new Employee("Jobs",220);
  Employee e6 = new Employee("Bond",13);
  
  list.add(e1);
  list.add(e2);
  list.add(e3);
  list.add(e4);
  list.add(e5);
  list.add(e6);
  
  Collections.sort(list, new Employee());
  
                   for (Employee contact : list) {
   System.out.println(contact.getName());
  }
 }
}


OUTPUT:


Anna
Bond
David
Jobs
Raj
Steve



Comparable Example:


public class Employee implements Comparable<Employee> {

 private String empId;
 private String empName;

 public Employee() {
 }
 
 public Employee(String empId, String empName){
  this.empId = empId;
  this.empName = empName;
 }
 
 public String getEmpId() {
  return empId;
 }
 
 public String getEmpName() {
  return empName;
 }

 @Override
 public int compareTo(Employee emp) {
  return this.empName.compareTo(emp.empName);
 }
}



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

public class CompratorTest {
 public static void main(String[] args) {
  
  List<Employee> arr = new ArrayList<Employee>();
  
  arr.add(new Employee("22","Raj"));
  arr.add(new Employee("25","Anna"));
  arr.add(new Employee("12","David"));
  arr.add(new Employee("100","Steve"));
  arr.add(new Employee("220","Jobs"));
  arr.add(new Employee("13","Bond"));
  
  //Object sort using Comparable
  Collections.sort(arr);

  Iterator<Employee> itr1 = arr.iterator();
  
  while (itr1.hasNext()) {
   Employee empobj = (Employee) itr1.next();
   System.out.println(empobj.getEmpName()+" \t\t "+empobj.getEmpId());
  }
 }
}


OUTPUT:


Anna    25
Bond    13
David    12
Jobs    220
Raj    22
Steve    100

Difference between Runnable and Callable interface in Java?

 

Runnable and Callable interface both are designed to represent task, which can be executed by any thread. Both does same task for the programmer with few difference between each other. In this tutorial we will see about difference between Runnable and Callable interface difference and when we need to use Runnable and Callable interface in our application. 

  • Runnable interface introduced in JDK 1.0, whereas Callable interface introduced in Java 5 release along with other major changes e.g. Generics, Enum, Static imports and variable argument method.
  • Since both are interface when we implement these interface we need to implement run() method from Runnable interface and call() method from Callable interface.
  • run() method didn't not return any value, whereas call() method returns Object where Callable interface is a generic parameterized interface and Type of value is provided at implementation. 
  • Callable interface can throw checked exception because it's call method throws Exception where as run() method has its limitation. 

Basically if our application needs to return any value from executor method then we need to for Callable interface than Runnable interface.

Bu keeping all these differences and usage between Runnalbe and Callable interface programmer need to be in a position to decide which interface he needs to choose for his application. 

As this is one of the important interview question asked in most of the interviews followed by multi-threading question and mostly asked in Banking domain Java interviews. 


Future and Callable in Java

 

In our previous tutorial we have see about Java Thread Pool with Executor Framework and simple example as how its works. By using same Thread pool we will see about Callable interface working in this tutorial. 

Normally we use Runnable interface to execute multi-threading in Java. Suppose if we need to get some output or return value from run() method then we can't use Runnable interface and it won't return any value.  In case if we expect threads to return a computed result then we can use java.util.concurrent.Callable interface. The Callable object allows to return values after completion of each Thread execution. The Callable object uses generics to define the type of object which is returned and we will see simple example below as how its works along with Future.

If we submit a Callable object to an Executor the framework returns an object of type java.util.concurrent.Future. This Future object can be used to check the status of a Callable and to retrieve the result from the Callable. On the Executor you can use the method submit to submit a Callable and to get a future. To retrieve the result of the future use the get() method. 


import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer> {
 
 private String name;
 
 public MyCallable(String name) {
  this.name = name;
 }
 
 @Override
 public Integer call() throws Exception {
  return name.length();
 } 
}


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class MyCallableTest {

 public static void main(String[] args) {
  
  String names[] = {"John", "David", "Steve", "Jobs", "Bill", "Gates", "Arnold"};
  
  // Thread pool size set as "5"
  ExecutorService executor = Executors.newFixedThreadPool(5);
  List<Future<Integer>> list = new ArrayList<Future<Integer>>();
     for (int i = 0; i < names.length; i++) {
       Callable<Integer> worker = new MyCallable(names[i]);
       Future<Integer> fur = executor.submit(worker);
       list.add(fur);
     }
     
     for (int i = 0; i < names.length; i++) {
      try {
       Future<Integer> future = list.get(i);
       System.out.println("NAME : ("+names[i] + ") - LENGTH : "+future.get());
   } catch (InterruptedException e) {
    e.printStackTrace();
   } catch (ExecutionException e) {
    e.printStackTrace();
   }
     }  
 }
}

OUTPUT:


NAME : (John) - LENGTH : 4
NAME : (David) - LENGTH : 5
NAME : (Steve) - LENGTH : 5
NAME : (Jobs) - LENGTH : 4
NAME : (Bill) - LENGTH : 4
NAME : (Gates) - LENGTH : 5
NAME : (Arnold) - LENGTH : 6

Java Thread Pool with Executor Framework

 

Java Thread pool manages the pool of threads which are under runnable state. Thread pools contains list of all Threads in queue which are waiting to get executed. Also Thread pool can be described as collection of Runnable Objects or instance. Thread pool will be constantly running and are checking the work query for new work or Thread to be added into the pool. If there are new work or Thread to be added into the pool and executed through Thread Pool. In Java Thread class itself provides a method, e.g. execute(Runnable r) to add a new Runnable object to the work queue and execute() method will take on executing each thread in the pool.

The Executor framework provides example implementation of the java.util.concurrent.Executor interface, e.g. Executors.newFixedThreadPool(int n) which will create n worker threads. The ExecutorService adds lifecycle methods to the Executor, which allows to shutdown the Executor and to wait for termination. Suppose if you want to use 1 thread pool with only 1 thread which executes several runnables you can use the Executors.newSingleThreadExecutor() method.


public class MyRunnableClass implements Runnable {

 private int value;

 MyRunnableClass(int value) {
  this.value = value;
 }

 @Override
 public void run() {
  int total = 0;
  for (int i = 1; i < value; i++) {
   total += i;
  }
  System.out.println(Thread.currentThread().getName() + " : " + total);  
 }
}


public class ThreadPoolTest {

 public static void main(String[] args) {
  // Thread pool size set as "5"
  ExecutorService executor = Executors.newFixedThreadPool(5);
  // Total 25 threads we are creating
  for (int i = 1; i <= 25; i++) {
   Runnable worker = new MyRunnableClass(i);
   executor.execute(worker);
  }
  executor.shutdown();
  System.out.println("All Threads finished...");
 }
}


OUTPUT:


pool-1-thread-1 : 0
pool-1-thread-1 : 15
pool-1-thread-1 : 21
pool-1-thread-1 : 28
pool-1-thread-1 : 36
pool-1-thread-1 : 45
pool-1-thread-1 : 55
pool-1-thread-1 : 66
pool-1-thread-1 : 78
pool-1-thread-1 : 91
pool-1-thread-1 : 105
pool-1-thread-1 : 120
pool-1-thread-1 : 136
pool-1-thread-1 : 153
pool-1-thread-1 : 171
pool-1-thread-1 : 190
pool-1-thread-1 : 210
pool-1-thread-1 : 231
pool-1-thread-1 : 253
pool-1-thread-1 : 276
pool-1-thread-1 : 300
All Threads finished...
pool-1-thread-3 : 3
pool-1-thread-4 : 6
pool-1-thread-2 : 1
pool-1-thread-5 : 10



Semaphore in Java

 

Semaphore is an important topic and used under Multi-threading in Java. Semaphore is mainly maintains a set of permits by acquire() and release(). Each acquire() will holds the block if permits are available and it performs the Thread operation and release() the block once it completed the operation. However, no actual permit objects are used; the Semaphore just keeps a count of the number available blocks and acts accordingly. 
We can Semaphore is as same as wait and notify where often used to restrict the number of threads than can access some (physical or logical) resource.
Below are the list of methods and constructors present in Semaphore class. 

Constructors:
There are 2 types of Constructors in Semaphore class 

Semaphore(int permits)

Semaphore(int permits, boolean fair)


Methods:

void acquire()

void acquire(int permits)

void acquireUninterruptibly()

void acquireUninterruptibly(int permits)

int availablePermits()

int drainPermits()

protected Collection<Thread> getQueuedThreads()

int getQueueLength()

boolean hasQueuedThreads()

boolean isFair()

protected void reducePermits(int reduction)

void release()

void release(int permits)

String toString()

boolean tryAcquire()

boolean tryAcquire(int permits)

boolean tryAcquire(int permits, long timeout, TimeUnit unit)

boolean tryAcquire(long timeout, TimeUnit unit)


Now we will simple example for using Semaphore in multi-threading. There are 2 different threads which prints even number by 1 thread and odd numbers by other thread. Numbers should be printed in sequential order like 1,2,3,4,5... etc., using Semaphore class. 



public class SemaphoreTest implements Runnable {
 
 private static int count = 1;
 private boolean flag;
 private static Semaphore even = new Semaphore(0);
 private static Semaphore odd = new Semaphore(1);
 
 public SemaphoreTest(boolean flag){
  this.flag = flag;
 }
 
 private void printEven(){
  while(true){
   try {
    even.acquire();
    System.out.println(Thread.currentThread().getName() + " : "+count++);
    Thread.sleep(100);
    odd.release();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
 private void printOdd(){
  while(true){
   try {
    odd.acquire();
    System.out.println(Thread.currentThread().getName() + "  : "+count++);
    Thread.sleep(100);
    even.release();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 
 @Override
 public void run() {  
  if(flag){
   printEven();
  }else{
   printOdd();
  }  
 }
 
 public static void main(String[] args) {
 
  Thread evenThread = new Thread(new SemaphoreTest(true), "EVEN-THREAD");
  Thread oddThread = new Thread(new SemaphoreTest(false), "ODD-THREAD");
  evenThread.start();
  oddThread.start();
 } 
}


OUTPUT:


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
ODD-THREAD  : 11
EVEN-THREAD : 12
ODD-THREAD  : 13
EVEN-THREAD : 14
ODD-THREAD  : 15