February 8, 2024

Spring Boot Hello World Application

In this tutorial we’ll see how to create your first Spring Boot Hello World web application using Eclipse and Maven.

Creating Maven project

In Eclipse select File-New-Maven Project to create a Maven project.

In the “New Maven Project” window check “Create a simple project (skip archetype selection)” and click Next.

Spring Boot Project

In the next window provide Group Id and Artifact Id values and click Finish.

  • GroupId- This is an Id of project's group. This ID uniquely identifies the group that may have many sub-projects. For example com.knpcode.spring may contain other projects related to Spring.
  • ArtifactId- This is an Id of the project. This ID uniquely identifies a project, for example SpringXML. GroupId + ArtifactId defines the artifact's location with in the repository for example com.knpcode.spring.SpringXML
Maven artifact

That will create a Maven project structure. You may need to change the Java version as Maven Project may add Java SE5 as default, you can do it using build path property or add it in the pom.xml while adding Spring Boot dependencies. Note that Spring Boot 3.x requires Java 17 as a minimum Java version so ensure that you have at least that version of Java installed.

If you are adding Java version in the properties section of pom.xml then right click your project and select Maven-Update project to update Java version for your project.

Adding Spring Boot dependencies

Open the created pom.xml to add dependencies related to Spring Boot so that the modified pom.xml looks as given below-

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
    <groupId>com.knpcode</groupId>
    <artifactId>SpringBootProject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringBootProject</name>
    <description>SpringBootProject</description>
    <properties>
     <java.version>17</java.version>
    </properties>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.4</version>  
    <relativePath />
  </parent>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
    </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>
  • First starter that is added in the parent section of the POM is a special starter spring-boot-starter-parent that provides useful Maven defaults. This parent starter also provides a dependency-management section so that you don't need to provide version tags for dependencies. Each release of Spring Boot provides a curated list of dependencies that it supports. You don't need to provide version for any of these dependencies in your build configuration, as Spring Boot manages that for you. Note that You can still specify a version and override Spring Boot’s recommendations if you need to do so. In our configuration, Spring Boot version is 3.2.4 so Spring Boot gets the dependencies which support this version.
  • Since we are developing a web application, we add a spring-boot-starter-web dependency, that adds the necessary dependencies required for creating a Spring web application.
  • Third thing to add is the spring-boot-maven-plugin to our pom.xml. This plugin provides many convenient features-
    • It helps to create an executable jar (über-jar), which makes it more convenient to execute and transport your service.
    • It also searches for the public static void main() method to flag the class having this method as a runnable class.

With these dependencies added Spring Boot takes care of getting the required jar dependencies, even an embedded web server (Tomcat in this case) because of the starter web dependency.

Classes for web application

We’ll add a simple controller for our web application. Maven compiles sources from src/main/java so create a package at that location and add the controller in that package. I created com.knpcode.springbootproject as base package and com.knpcode.springbootproject.controller package for Controller classes.

package com.knpcode.springbootproject.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {
  @GetMapping(value="/{name}")
  public String showGreeting(@PathVariable("name") String name) {
    return "Hello " + name;
  }
}
  • Class is annotated using @RestController annotation which tells Spring that this class is ready for use by Spring MVC to handle web requests and it indicates that resulting string should be written directly into the response body, we don't want to render views.
  • At method level @GetMapping annotation is used which is short cut for @RequestMapping(method = RequestMethod.GET). This annotation provides routing information. It tells Spring that any HTTP request with the /{name) path should be mapped to the showGreeting method.
  • @PathVariable annotation lets you retrieve the parameter from the request path.

Application class with main method

Here is an application class with the components.

package com.knpcode.springbootproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FirstSpringBootApp {
  public static void main(String[] args) {
    SpringApplication.run(FirstSpringBootApp.class, args);
  }
}
@SpringBootApplication is a convenience annotation that adds all of the following annotations-
  1. @Configuration annotation tags the class as a source of bean definitions for the application context.
  2. @EnableAutoConfiguration tells Spring Boot to enable auto configuration so that beans are created automatically based on classpath settings, other beans, and various property settings. For example starter spring-boot-starter-web adds Tomcat and Spring MVC so the auto-configuration assumes that you are developing a web application and sets up Spring accordingly which includes setting up a DispatcherServlet.
  3. @ComponentScan tells Spring to look recursively for other components, configurations and services inside this package and register them.

The main method is the application entry point which delegates to Spring Boot’s SpringApplication class by calling run. SpringApplication class starts Spring, which in turn, starts the embedded Tomcat web server and also bootstraps this HelloWorld application. You need to pass FirstSpringBootApp.class as an argument to the run method to tell SpringApplication which is the primary Spring component.

Running the application

You can run this Spring Boot Hello World application as a stand alone Java application or create an executable jar.

1. You can run it as a stand alone Java application by running the class with the main method (FirstSpringBootApp.java) from Eclipse IDE itself.

Right click FirstSpringBootApp.java – Run As – Java Application

2. Dependency spring-boot-starter-parent also provides a run goal that you can use to start the application. Type mvn spring-boot:run from the root project directory to start the application.

From the output on the console you can see that web server is configured, WebApplicationContext is initialized and all that is done automatically.

2019-07-19 13:26:25.989  INFO 14944 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-07-19 13:26:26.040  INFO 14944 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-07-19 13:26:26.042  INFO 14944 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-07-19 13:26:26.223  INFO 14944 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-07-19 13:26:26.224  INFO 14944 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2412 ms
2019-07-19 13:26:26.589  INFO 14944 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-07-19 13:26:26.897  INFO 14944 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-07-19 13:26:26.910  INFO 14944 --- [           main] com.knpcode.app.FirstSpringBootApp       : Started FirstSpringBootApp in 3.83 seconds (JVM running for 16.239)

You can access the application by opening http://localhost:8080/knpCode

Here /KnpCode is the value for the name parameter.

Spring boot hello world app

Creating executable jar

For creating a completely self-contained executable jar file run mvn package from the command line

F:\knpcode\Spring_WorkSpace\SpringBootProject>mvn package

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building SpringBootProject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-jar-plugin:3.1.2:jar (default-jar) @ SpringBootProject ---
[INFO] Building jar: F:\knpcode\Spring_WorkSpace\SpringBootProject\target\SpringBootProject-0.0.1-SNAPSHOT.jar
[INFO]

To run application using the created jar, use the java -jar command, as follows-

java -jar target\SpringBootProject-0.0.1-SNAPSHOT.jar

That's all for the topic Spring Boot Hello World Application. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 7, 2024

Multithreading in Java Tutorial

You would have seen a lot of examples of multi-tasking where computer programs are handling more than one task at a time. For example- You can start a player and play songs while working on any editor and have a document of 100 pages getting printed at the same time. This is an example where separate processes are running concurrently. Same way with in the same program you can have several tasks running like in a song player you can start playing a song and at the same time click on "add song" button to add more songs to your playlist. With in a program these separate running tasks are called threads and this concept of dividing a program into separate sub-tasks to make it faster and more responsive is called multi-threading.

Multithreading in Java

Java is one of the first programming language to provide in-built support for multi-threading programming.

In Java multithreading the main class is Thread class, any thread in Java is an object of Thread class and the code that is executed by the thread is provided in the run() method of the Thread class. You will need to override the run() method and provide the required functionality.

Refer How to Create And Start Thread in Java to see the ways thread can be created in Java.

When a Java application starts you start with just one thread, called the Main Thread in Java. This thread has the ability to create additional threads, which can perform specific tasks. You will have to divide your application in such a way that separate sub-tasks can be performed by separate threads rather than main thread performing all the tasks.

Multithreading Java Example

Here is a Java program that shows creating a thread by implementing Runnable interface and also shows the main thread. Once you call the start() method of the thread you have created, it executes the run() method and displays the name of the thread. Once that thread is terminated control again goes to main thread whose name is also displayed.

class AnotherThread implements Runnable{
  @Override
  public void run() {
    System.out.println("run method of Another thread --" 
      + Thread.currentThread().getName());	
  }	
}

public class ThreadDemo {
  public static void main(String[] args) {
    Thread thread = new Thread(new AnotherThread(), "AnotherThread");
    thread.start();
    System.out.println("Main thread " + Thread.currentThread().getName());
  }
}
Output
Main thread main
run method of Another thread –AnotherThread

Life cycle of a thread in Java multithreading

In Java multithreading a thread can go through many states of existence. Once you call start() method on a thread it is in a runnable state. Once it starts running it can be suspended and the control given to another thread. A suspended thread can again resume its operation. A thread can also be in blocked state if it is waiting for a shared resource. Once thread has finished its operation it is terminated.

Refer Life Cycle of a Thread (Thread States) in Java to know more about thread states in Java.

Difference between thread and process

As stated in the beginning itself, in concurrent programming there are two types of multitasking-

  • Process based multitasking.
  • Thread based multitasking.

Though this tutorial is about multithreading in Java, for better understanding you should know the difference between thread and process in Java.

Thread Vs Process in Java
  1. A process has a self-contained execution environment. A process has its own run-time resources like memory space. Threads exist within a process — every process has at least one. Threads share the process's resources, including memory and open files.
  2. Processes are heavyweight tasks running in their own allocated memory space. Threads are lightweight spawned with in a process and share its memory.
  3. Processes are independent units with their own separate resources so inter-process communication is expensive. Threads share the resources with in a process so inter-thread communication is easy but at the same time require special attention to safe guard shared resources among threads.
  4. Context switching from one process to another is time-consuming as it is time consuming to save the state of the running process. Context switching among threads is not that time consuming.
multithreading in Java

That's all for the topic Multithreading in Java Tutorial. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 6, 2024

Java Stream distinct() With Examples

Java Stream distinct() method is used to get the distinct elements of the stream. It means this method filters out the duplicate elements.

Syntax of the distinct method

Syntax of the distinct() method in the Java Stream API is as given below-

Stream<T> distinct()

  1. Method returns a new stream consisting of the distinct elements.
  2. For element comparison distinct() method uses the equals() method.
  3. distinct() method is a stateful intermediate operation which means it may incorporate state from previously seen elements when processing new elements.
  4. If there are duplicate elements in an ordered stream the element appearing first in the encounter order is preserved. For unordered streams, no stability guarantees are made.

Java Stream distinct() examples

1. Using distinct() method to remove duplicate elements from a List of integers.

import java.util.List;

public class DistinctDemo {

  public static void main(String[] args) {
    // Till Java 8
    //List<Integer> myList = Arrays.asList(11, 1, 9, 1, 4, 11, 17);
    // From Java 9
    List<Integer> myList = List.of(11, 1, 9, 1, 4, 11, 17);
    myList.stream().distinct().forEach(System.out::println);
  }
}
Output
11
1
9
4
17

2. Same way from a List of strings also you can remove duplicates by using distinct() method.

import java.util.List;
import java.util.stream.Collectors;

public class DistinctDemo {

  public static void main(String[] args) {
    // Till Java 8
    //List<String> myList = Arrays.asList("Ram", "Madan", "Jack", "Ram", "Jack");
    // From Java 9
    List<String> myList = List.of("Ram", "Madan", "Jack", "Ram", "Jack");
    List<String> listWithNoDuplicates = myList.stream()
                           .distinct()
                           .collect(Collectors.toList());
    System.out.println(listWithNoDuplicates);
}
Output
[Ram, Madan, Jack]

3. Removing duplicates from a List of custom objects. Student class used is as given below.

public class Student {
  private int rollNo;
  private String name;
  private String stream;
  private int marks;
  Student(int rollNo, String name, String stream, int marks){
    this.rollNo = rollNo;
    this.name = name;
    this.stream = stream;
    this.marks = marks;
  }
  public int getRollNo() {
    return rollNo;
  }
  public void setRollNo(int rollNo) {
    this.rollNo = rollNo;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  public String getStream() {
    return stream;
  }
  public void setStream(String stream) {
    this.stream = stream;
  }
  public int getMarks() {
    return marks;
  }
  public void setMarks(int marks) {
    this.marks = marks;
  }
  @Override
  public String toString() {
    return "Roll Number: " +  getRollNo() + " Name: " + getName();
  }
  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + rollNo;
    return result;
  }
  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    Student other = (Student) obj;
    if (name == null) {
      if (other.name != null)
        return false;
    } else if (!name.equals(other.name))
      return false;
    if (rollNo != other.rollNo)
      return false;
    return true;
  }
}

As you can see hashCode() and equals() methods are also implemented as that is one of pre-requisite for the distinct() method to work correctly.

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DistinctDemo {

  public static void main(String[] args) {
    List<Student> studentList = Arrays.asList(new Student(1, "Peter", "Science", 75),
              new Student(2, "Ram", "Science", 99),
              new Student(3, "Priscilla", "Art", 68),
              new Student(2, "Ram", "Science", 99),
              new Student(1, "Peter", "Science", 75));
    List<Student> listWithNoDuplicates = studentList.stream()
                           .distinct()
                           .collect(Collectors.toList());
    System.out.println(listWithNoDuplicates);
}
Output
[Roll Number: 1 Name: Peter, Roll Number: 2 Name: Ram, Roll Number: 3 Name: Priscilla]

That's all for the topic Java Stream distinct() With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 5, 2024

How to Unzip a File in Java

When you zip a file in Java there are different logic based on whether you are zipping a file or you are zipping a folder in Java where the whole directory structure is archived. But unzipping a file in Java doesn’t need such different functionalities. One Java program to unzip a file takes care of all the different functionalities.

Unzip a file – Java program

To unzip a file you need to follow the following steps-

  • Read the compressed file from the zipped archive. For that java.util.zip.ZipInputStream class is used.
  • From the ZipInputStream, zip entries for the files and directories are read using getNextEntry() method.
  • If the entry is for a directory then you just need to create the directory. If the entry is for file then read the content of the file and write it to the destination file.
  • Close the current entry using the closeEntry() method.
  • Once all the zip entries are iterated close the input and output streams.
public class UnzipFile {
  private static final int BUFFER = 2048;
  public static void main(String[] args) {
    final String SOURCE_ZIPDIR = "F:/knpcode/Parent.zip";
    // creating the destination dir using the zip file path
    // by truncating the ".zip" part
    String DESTINATION_DIR = SOURCE_ZIPDIR.substring(0, SOURCE_ZIPDIR.lastIndexOf('.'));
    //System.out.println("" + DESTINATION_DIR);
    extract(SOURCE_ZIPDIR, DESTINATION_DIR);
  }
	
  private static void extract(String source, String dest){
    try {
      File root = new File(dest);
      if(!root.exists()){
        root.mkdir();
      }
      BufferedOutputStream bos = null;
      // zipped input
      FileInputStream fis = new FileInputStream(source);
      ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
      ZipEntry entry;
      while((entry = zis.getNextEntry()) != null) {
        String fileName = entry.getName();
        File file = new File(dest + File.separator + fileName);
        if (!entry.isDirectory()) {
          extractFileContentFromArchive(file, zis);
        }
        else{
          if(!file.exists()){
            file.mkdirs();
          }
        }
        zis.closeEntry();
      }
      zis.close();
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
	
  private static void extractFileContentFromArchive(File file, ZipInputStream zis) throws IOException{
    FileOutputStream fos = new FileOutputStream(file);
    BufferedOutputStream bos = new BufferedOutputStream(fos, BUFFER);
    int len = 0;
    byte data[] = new byte[BUFFER];
    while ((len = zis.read(data, 0, BUFFER)) != -1) {
      bos.write(data, 0, len);
    }
    bos.flush();
    bos.close();
  }
}

That's all for the topic How to Unzip a File in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 4, 2024

How to Zip a Folder in Java

In the post How to Zip Files in Java we have seen how to zip a single file or multiple files in Java but you may also need to zip a folder in Java where you also retain the folder tree structure while zipping it. This post shows how to zip a folder in Java where the zip archive contains the whole tree structure (files and subdirectories).

Options for zipping a folder in Java

For zipping a folder with all its subfolders and files two options are given in this post.

  1. Using Files.walkFileTree() method- Using this method you can recursively visit all the files in a file tree. An implementation of FileVisitor interface is provided to the Files.walkFileTree method to visit each file in a file tree. This option is available Java 7 onward. See example.
  2. By providing the code yourself to read the files with in a folder recursively by using listFiles() method in java.io.File class. See example.

Check this post How to Unzip a File in Java to see how to unzip files and folders in Java.

Directory structure used

Java programs shown here to zip a folder in Java use the following directory structure.

zip a folder in Java

With in the parent folder there is one sub folder Child with two files and one file is stored in the parent folder. The zipped archive should retain the same tree structure.

Using Files.walkFileTree method to zip a folder in Java

One of the argument of this method is a FileVisitor interface. You do need to provide implementation of this interface as per your requirement. FileVisitor interface has four methods, for zipping a folder you do need to implement two of them.

  • preVisitDirectory– Invoked before a directory's entries are visited. By implementing this method you can create the visited folder with in the zip archive.
  • visitFile– Invoked on the file being visited. By implementing this method you can add each visited file to the zip archive.
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipOutputStream;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;

public class ZipFolder {
  public static void main(String[] args) {
    // Source folder
    final String SOURCE_DIR = "F:/knpcode/Parent";
    // creating the name of the zipped archive
    String ZIP_DIR = SOURCE_DIR.concat(".zip");
    zipFolderStructure(SOURCE_DIR, ZIP_DIR);
  }
    
  private static void zipFolderStructure(String sourceFolder, String zipFolder){
    // Creating a ZipOutputStream by wrapping a FileOutputStream
    try (FileOutputStream fos = new FileOutputStream(zipFolder); 
         ZipOutputStream zos = new ZipOutputStream(fos)) {
      Path sourcePath = Paths.get(sourceFolder);
      // Walk the tree structure using WalkFileTree method
      Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>(){
        @Override
        // Before visiting the directory create the directory in zip archive
        public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException {
          // Don't create dir for root folder as it is already created with .zip name 
          if(!sourcePath.equals(dir)){
            System.out.println("Directory- " + dir);
            zos.putNextEntry(new ZipEntry(sourcePath.relativize(dir).toString() + "/"));                  
            zos.closeEntry();    
          }
          return FileVisitResult.CONTINUE;
        }
        @Override
        // For each visited file add it to zip entry
        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
          System.out.println("File Name- " + sourcePath.relativize(file).toString());
          zos.putNextEntry(new ZipEntry(sourcePath.relativize(file).toString()));
          Files.copy(file, zos);
          zos.closeEntry();
          return FileVisitResult.CONTINUE;
        }});
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}
Output
Directory- F:\knpcode\Parent\Child
File Name- Child\hello.txt
File Name- Child\Project.docx
File Name- Test.txt

Zip a folder in Java by listing files recursively

In the code you first create a list of all the files and folders residing with in a parent folder. To go through the list of files with in a directory listFiles() method of java.io.File class is used.

Once you have this folder tree structure in a list you iterate through that list to create a zip archive. For every iterated element of the list you check if it is a directory or a file-

  • If it is a directory then you just add the name of the directory in the zip archive.
  • If it is a file then you add the name as well as the content of the file.
public class ZippingFolder {
  List fileList = new ArrayList();
  public static void main(String[] args) {	
    // Source folder
    final String ROOT_DIR = "F:/knpcode/Parent";
    // creating the name of the zipped archive
    String ZIP_DIR = ROOT_DIR.concat(".zip");
    ZippingFolder zippingFolder = new ZippingFolder();
    // get the list of the whole folder structure
    zippingFolder.getListOfFiles(new File(ROOT_DIR));
    zippingFolder.zipTreeStructure(ROOT_DIR, ZIP_DIR);
  }
	
  private void zipTreeStructure(String ROOT_DIR, String zipDir){
    final int BUFFER = 1024;
    BufferedInputStream bis = null;
    ZipOutputStream zos = null;
    try{
      // Creating ZipOutputStream by wrapping FileOutputStream
      FileOutputStream fos = new FileOutputStream(zipDir);
      zos = new ZipOutputStream(fos);
      // iterating the folder tree structure
      for(File file : fileList){
        // If directory
        if(file.isDirectory()){
          // add the directory name as zipentry
          ZipEntry ze = new ZipEntry(file.getName()+"/");             
          zos.putNextEntry(ze);
          zos.closeEntry();
        }
        // If file
        else{
          FileInputStream fis = new FileInputStream(file);
          bis = new BufferedInputStream(fis, BUFFER);                
          ZipEntry ze = new ZipEntry(getFileName(ROOT_DIR, file.toString()));                   
          zos.putNextEntry(ze);
          byte data[] = new byte[BUFFER];
          int count;
          while((count = bis.read(data, 0, BUFFER)) != -1) {
            zos.write(data, 0, count);
          }
          bis.close();
          zos.closeEntry();
        }               
      }                
           
    }catch(IOException ioExp){
      ioExp.printStackTrace();
    } finally{
      try {
        zos.close(); 
        if(bis != null)
          bis.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }  
    }
  }
  // Method to get the folder tree structure
  private void getListOfFiles(File source){
    File[] fileNames = source.listFiles();
    for(File file : fileNames){
      if(file.isDirectory()){
        fileList.add(file);
        // recursive call to go through the subdirectory structure
        getListOfFiles(file);
      }else{
        fileList.add(file);
      }
    }
  }
    
  // To get the relative file path 
  private String getFileName(String ROOT_DIR, String filePath){
    String name = filePath.substring(ROOT_DIR.length() + 1, filePath.length());
    return name;
  }
}

That's all for the topic How to Zip a Folder in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 3, 2024

How to Zip Files in Java

This post shows how you can zip files in Java. Using the options given here you can zip a single file or more than one file by specifying all those files.

Zip a file in Java

To zip files in Java there are two options-

  1. Using ZipOutputStream and ZipEntry classes residing in java.util.zip package.
  2. Using the Zip File System Provider- The zip file system provider treats a zip or JAR file as a file system and provides the ability to manipulate the contents of the file. The zip file system provider was introduced in the JDK 7 release.

Want to zip a folder, check this post How to Zip a Folder in Java

Zipping single fie in Java using ZipOutputStream

The steps for zipping a file using ZipOutputStream are as follows-

  • Create an InputStream for reading the source file.
  • Create an OutputStream for the zip file and wrap it in a ZipOutputStream object.
  • Create a ZipEntry instance for the source file and add it to the ZipOutputStream.
  • Read data from the source file and write it to the ZIP file.
  • Close the streams.
public class ZipFile {
  public static void main(String[] args) {
    // source file
    String fileName = "F:\\knpcode\\links.txt";
    File file = new File(fileName);
    //Creating zipfile name from fileName by 
    // truncating .txt and appending .zip
    String zipFilename = fileName.substring(0, fileName.indexOf('.')) + ".zip";
    File zipFile = new File(zipFilename);
    zipFile(file, zipFile);
  }
	
  // Method to zip file
  private static void zipFile(File file, File zippedFile){
    final int BUFFER = 1024;
    ZipOutputStream zos = null;
    BufferedInputStream bis = null;
    try{
      FileInputStream fis = new FileInputStream(file);
      bis = new BufferedInputStream(fis, BUFFER);          
      // Creating ZipOutputStream for writing to zip file
      FileOutputStream fos = new FileOutputStream(zippedFile);
      zos = new ZipOutputStream(fos);
      // Each file in the zipped archive is represented by a ZipEntry 
      // Only source file name is needed 
      ZipEntry ze = new ZipEntry(file.getName());        
      zos.putNextEntry(ze);
      byte data[] = new byte[BUFFER];
      int count;
      while((count = bis.read(data, 0, BUFFER)) != -1) {
        zos.write(data, 0, count);
      }                     
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }finally{
      try {
        zos.close();
        bis.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }  
    }
  }
}

Zipping single fie in Java using Zip File System Provider

You can use the factory methods of the java.nio.file.FileSystems class to create a new zip file system or to obtain a reference to an existing zip file system.

You can create a zip file system by specifying the path of the zip or JAR file in following way-

URI uri = URI.create("jar:file:/PATH/TO/ZIPFILE");
FileSystem fs = FileSystems.newFileSystem(uri, env);

public class ZipFile {
  public static void main(String[] args) {
    // source file
    String fileName = "F:/knpcode/links.txt";
    //Creating zipfile name from fileName by 
    // truncating .txt and appending .zip
    String zipFilename = fileName.substring(0, fileName.indexOf('.')) + ".zip";
    
    zipFile(fileName, zipFilename);
  }

  private static void zipFile(String file, String zippedFile){
    Map<String, String> env = new HashMap<>(); 
    env.put("create", "true");
    // locate file system by using the syntax 
    // defined in java.net.JarURLConnection
    URI uri = URI.create("jar:file:/" + zippedFile);
    try (FileSystem zipfs = FileSystems.newFileSystem(uri.normalize(), env)) {
      Path sourceFile = Paths.get(file);
      System.out.println("Name-- " + sourceFile.getFileName().toString());
      Path pathInZipfile = zipfs.getPath(sourceFile.getFileName().toString());          
      // copy a file into the zip file
      Files.copy(sourceFile, pathInZipfile, StandardCopyOption.REPLACE_EXISTING ); 
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

Zipping multiple files in Java

Here is an example of zipping multiple files in Java using ZipOutputStream where each source file is added as a ZipEntry to the ZipOutputStream.

public class ZipFile {
  public static void main(String[] args) {
    try {
      // source files
      String file1 = "F:/knpcode/links.txt";
      String file2 = "F:/knpcode/Test/postend.txt";
      // Zipped file name
      String zipFilename = "F:/knpcode/result.zip";
      File zipFile = new File(zipFilename);
      // Creating ZipOutputStream for writing to zip file
      FileOutputStream fos  = new FileOutputStream(zipFile);			
      ZipOutputStream zos = new ZipOutputStream(fos);
      
      zipFile(file1, zos);
      zipFile(file2, zos);
      zos.close();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
	
  // Method to zip file
  private static void zipFile(String fileName, ZipOutputStream zos) throws IOException{
  final int BUFFER = 1024;
  BufferedInputStream bis = null;
  try{
    File file = new File(fileName);
    FileInputStream fis = new FileInputStream(file);
    bis = new BufferedInputStream(fis, BUFFER);          

    // Each file in the zipped archive is represented by a ZipEntry 
    // Only source file name is needed 
    ZipEntry zipEntry = new ZipEntry(file.getName());        
    zos.putNextEntry(zipEntry);
    byte data[] = new byte[BUFFER];
    int count;
    while((count = bis.read(data, 0, BUFFER)) != -1) {
      zos.write(data, 0, count);
    }    
      zos.closeEntry();
    } finally{
      try {
        bis.close();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }  
    }
  }
}

That's all for the topic How to Zip Files in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 2, 2024

Write to Excel File in Java Using Apache POI

In this article we’ll see how to write to Excel file in Java using Apache POI library. If you have to read an Excel file in Java you can check this post- Read Excel File in Java Using Apache POI

Apache POI

Apache POI is a Java API for Microsoft documents. Using Apache POI you can read and write MS Excel files using Java. In addition, you can read and write MS Word and MS PowerPoint files using Java.

Apache POI provides support for reading both OLE2 files and Office Open XML standards (OOXML) files.

  • OLE2 files include most Microsoft Office files such as XLS, DOC, and PPT as well as MFC serialization API based file formats.
  • Office OpenXML Format is the new standards based XML file format found in Microsoft Office 2007 and 2008. This includes XLSX, DOCX and PPTX.

Which means Apache POI supports writing excel files having .xls format as well as excel files with .xlsx format.

Maven dependencies for Apache POI

To write to excel file using Apache POI you need to add the following dependency.

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>5.2.5</version>
</dependency>
<dependency> 
  <groupId>org.apache.poi</groupId> 
  <artifactId>poi-ooxml</artifactId> 
  <version>5.2.5</version> 
</dependency>

Here note that poi-x.jar has classes for working with old excel format (.xls) and poi-ooxml-x.jar has classes for working with newer excel format (.xlsx).

Apache POI classes for writing excel files

Following section gives an overview of classes that are used for writing to excel file in Java using Apache POI.

Apache POI library provides two implementations for two excel spread sheet formats-

  • HSSF- It is the pure Java implementation for earlier excel format (.xls). Classes in this implementation will usually have HSSF prefix like HSSFWorkBook, HSSFSheet.
  • XSSF- It is the pure Java implementation for xslx file format (OOXML). Classes in this implementation will usually have XSSF prefix like XSSFWorkBook, XSSFSheet.

SS- It is a package built on top of HSSF and XSSF that provides common support for both formats with a common API. You should try to use classes from this package for better compatibility.

While working with excel file the usual progression is-

write to excel file in Java
There are interfaces corresponding to this progression-
  • org.apache.poi.ss.usermodel.Workbook- High level representation of a Excel workbook. This is the first object most users will construct whether they are reading or writing a workbook. It is also the top level object for creating new sheets.
  • org.apache.poi.ss.usermodel.Sheet- High level representation of a Excel worksheet. Sheets are the central structures within a workbook.
  • org.apache.poi.ss.usermodel.Row- High level representation of a row of a spreadsheet.
  • org.apache.poi.ss.usermodel.Cell- High level representation of a cell in a row of a spreadsheet. Cells can be numeric, formula-based or string-based (text).

For creating a Workbook, WorkbookFactory class is used.

  • org.apache.poi.ss.usermodel.WorkbookFactory- Factory for creating the appropriate kind of Workbook (be it HSSFWorkbook or XSSFWorkbook), by auto-detecting from the supplied input.

Write excel file in Java using Apache POI example

For the example there is a class Employee with fields firstName, lastName, department and DOB. Using these fields data is written to excel file in 4 columns per row. One extra column is added to show how to write a formula to excel sheet using Apache POI.

Employee class
import java.time.LocalDate;

public class Employee {
  private String firstName;
  private String lastName;
  private String department;
  private LocalDate dob;
  Employee(){}
  public Employee(String firstName, String lastName, String department, LocalDate dob) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.department = department;
    this.dob = dob;
  }
  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  public String getDepartment() {
    return department;
  }
  public void setDepartment(String department) {
    this.department = department;
  }
  public LocalDate getDob() {
    return dob;
  }
  public void setDob(LocalDate dob) {
    this.dob = dob;
  }
  @Override
  public String toString() {
    return "Employee [firstName=" + firstName + ", lastName=" + lastName + ", department=" + department + ", dob="
        + dob + "]";
  }
}

Following Java class retrieve data from fields of Employee objects and write to excel sheet.

import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class WriteExcel {
  private static final String EXCEL_FILE_PATH="D:\\knpcode\\Employee1.xlsx";
  public static void main(String[] args) {
    WriteExcel writeExcel = new WriteExcel();    
    writeExcel.writeExcelFile(EXCEL_FILE_PATH, WriteExcel.getEmployees());
  }
    
  public void writeExcelFile(String excelFilePath, List<Employee> employees) {
    final String[] header= {"First Name", "Last Name", "Department", "DOB", "Current Date"};
    Workbook workbook = null;
    // Excel with .xslx extension
    workbook = new XSSFWorkbook();
    // For .xls extension HSSF workbook can be created
    //workbook = new HSSFWorkbook();

    // Creating sheet with in the workbook
    Sheet sheet = workbook.createSheet("Employees");
    /*Font and style For Header*/
    Font font = workbook.createFont();
    font.setFontName("VERDANA");
    font.setColor(IndexedColors.CORNFLOWER_BLUE.getIndex());
    font.setBold(true);
         
    CellStyle style = workbook.createCellStyle();
    style.setFont(font);
    style.setWrapText(true);
    style.setAlignment(HorizontalAlignment.CENTER);
    style.setVerticalAlignment(VerticalAlignment.CENTER);
    style.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE.getIndex());
    style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    style.setBorderRight(BorderStyle.THIN);
    style.setRightBorderColor(IndexedColors.BLACK.getIndex());
    style.setBorderLeft(BorderStyle.THIN);
    style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
    style.setBorderTop(BorderStyle.THIN);
    style.setTopBorderColor(IndexedColors.BLACK.getIndex());
    style.setBorderBottom(BorderStyle.THIN);
    style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
         
    Row row = sheet.createRow(0);
    // Writing header to excel
    for(int i = 0; i < header.length; i++) {
       // each column 20 characters wide
       sheet.setColumnWidth(i, 20*256);
       Cell cell = row.createCell(i);
       cell.setCellValue(header[i]);
       cell.setCellStyle(style);
    }   
    // Header styling ends
    //Preparing column data for each row
    CellStyle dateStyle = workbook.createCellStyle();
    // Setting format For the date column
    dateStyle.setDataFormat(workbook.getCreationHelper()
                                    .createDataFormat().getFormat("dd-mm-yyyy"));
    int rowNum = 1;
    for(Employee emp : employees) {
      // create new row
      row = sheet.createRow(rowNum++);
      row.createCell(0).setCellValue(emp.getFirstName());
      row.createCell(1).setCellValue(emp.getLastName());
      row.createCell(2).setCellValue(emp.getDepartment());    
      // Writing date with date formatting
      Cell cell = row.createCell(3);
      cell.setCellStyle(dateStyle);
      cell.setCellValue(emp.getDob());
      // Writing formula with date formatting
      // as formula shows current date
      cell = row.createCell(4);
      cell.setCellStyle(dateStyle);
      cell.setCellFormula("Today()");
    }
          
    FileOutputStream outputStream = null;
    try {
     outputStream = new FileOutputStream(excelFilePath);
     // Writing to excel sheet
     workbook.write(outputStream);
    } catch (IOException exp) {
     // TODO Auto-generated catch block
     exp.printStackTrace();
    }finally {
      if(outputStream != null) {
        try {
          outputStream.close();
          workbook.close();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }   
  }
    
  // Method to get list of employees
  private static List<Employee> getEmployees(){
    List<Employee> employees = new ArrayList<Employee>();
    //Adding 3 employee objects
    employees.add(new Employee("John", "Emerson", "Technology", LocalDate.of(1990,10,12)));
    employees.add(new Employee("Shelly", "Mcarthy", "HR", LocalDate.of(1960, 04, 07)));
    employees.add(new Employee("Tom", "Cevor", "Finance", LocalDate.of(1992, 02, 03)));
    return employees;
  }
}

Running this program creates excel sheet as shown below.

excel file in Java

Points to note here-

  1. For header in excel sheet some styling is done using CellStyle class.
  2. For the date column, date formatting is done. To create a date format you can use CreationHelper class in Apache POI.
      workbook.getCreationHelper().createDataFormat().getFormat("dd-mm-yyyy")
      
  3. To write a formula, setCellFormula() method is used.

That's all for the topic Write to Excel File in Java Using Apache POI. If something is missing or you have something to share about the topic please write a comment.


You may also like

Read Excel File in Java Using Apache POI

In this article we’ll see how to read Excel file in Java using Apache POI library. If you have to write to an Excel file in Java you can check this post- Write to Excel File in Java Using Apache POI

Apache POI

Apache POI is a Java API for Microsoft documents. Using Apache POI you can read and write MS Excel files using Java. In addition, you can read and write MS Word and MS PowerPoint files using Java.

Apache POI provides support for reading both OLE2 files and Office Open XML standards (OOXML) files.

  • OLE2 files include most Microsoft Office files such as XLS, DOC, and PPT as well as MFC serialization API based file formats.
  • Office OpenXML Format is the new standards based XML file format found in Microsoft Office 2007 and 2008. This includes XLSX, DOCX and PPTX.

Which means Apache POI supports reading excel files having .xls format as well as excel files with .xlsx format.

Maven dependencies for Apache POI

To read excel files using Apache POI you need to add the following dependencies.

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.5</version>
</dependency>
<dependency> 
  <groupId>org.apache.poi</groupId> 
  <artifactId>poi-ooxml</artifactId> 
  <version>5.2.5</version> 
</dependency>

Apache POI classes for reading excel files

Here is a primer about the classes that are used for reading excel file in Java using Apache POI.

Apache POI library provides two implementations for two excel spread sheet formats-

  • HSSF- It is the pure Java implementation for earlier excel format (.xls). Classes in this implementation will usually have HSSF prefix like HSSFWorkBook, HSSFSheet.
  • XSSF- It is the pure Java implementation for xslx file format (OOXML). Classes in this implementation will usually have XSSF prefix like XSSFWorkBook, XSSFSheet.

SS- It is a package built on top of HSSF and XSSF that provides common support for both formats with a common API. You should try to use classes from this package for better compatibility.

While working with excel file the usual progression is-

read excel file in Java

There are interfaces corresponding to this progression-

  • org.apache.poi.ss.usermodel.Workbook- High level representation of a Excel workbook. This is the first object most users will construct whether they are reading or writing a workbook. It is also the top level object for creating new sheets.
  • org.apache.poi.ss.usermodel.Sheet- High level representation of a Excel worksheet. Sheets are the central structures within a workbook.
  • org.apache.poi.ss.usermodel.Row- High level representation of a row of a spreadsheet.
  • org.apache.poi.ss.usermodel.Cell- High level representation of a cell in a row of a spreadsheet. Cells can be numeric, formula-based or string-based (text).

For creating a Workbook, WorkbookFactory class is used.

  • org.apache.poi.ss.usermodel.WorkbookFactory- Factory for creating the appropriate kind of Workbook (be it HSSFWorkbook or XSSFWorkbook), by auto-detecting from the supplied input.

Read excel file in Java using Apache POI example

In this Java example to read excel file we’ll read the following sheet (Employee.xslx) having employee information and create Employee objects using that data.

read excel file POI Java

Last column "Current Date" has a formula "Today()" which displays current date. That column is there to show you how to read a formula in excel using Apache POI.

Employee class
import java.time.LocalDate;

public class Employee {
  private String firstName;
  private String lastName;
  private String department;
  private LocalDate dob;
  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  public String getDepartment() {
    return department;
  }
  public void setDepartment(String department) {
    this.department = department;
  }
  public LocalDate getDob() {
    return dob;
  }
  public void setDob(LocalDate dob) {
    this.dob = dob;
  }
  @Override
  public String toString() {
    return "Employee [firstName=" + firstName + ", lastName=" + lastName + ", department=" + department + ", dob="
        + dob + "]";
  }
}

Following class reads data from the excel file and create Employee class objects.

import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

public class ReadExcel {
  // Excel file path (change as per your system)
  private static final String EXCEL_FILE_PATH="D:\\knpcode\\Employee.xlsx";

  public static void main(String[] args) {
    ReadExcel readExcel = new ReadExcel();
    readExcel.readExcelFile(EXCEL_FILE_PATH);
  }
  private void readExcelFile(String excelFilePath) {
    try {
      // get excel workbook
      Workbook workbook = WorkbookFactory.create(new FileInputStream(excelFilePath));
      // get excel sheet
      Sheet sheet = workbook.getSheetAt(0);
      //If you have more than one sheet in a workbook then you 
      // can iterate through sheets 
      /*Iterator<Sheet> sheetIterator = workbook.sheetIterator();
      while(sheetIterator.hasNext()) {
        Sheet sheet = sheetIterator.next();*/
      readSheet(sheet);             
    } catch (IOException | ParseException e) {
      e.printStackTrace();
    }
  }
      
  private void readSheet(Sheet sheet) throws ParseException{
    Iterator<Row> rowItr = sheet.iterator();
    List<Employee> empList = new ArrayList<>();
    // Iterate through rows
    while(rowItr.hasNext()) {
      Employee emp = new Employee();
      Row row = rowItr.next();
      // skip header (First row)
      if(row.getRowNum() == 0) {
          continue;
      }
      Iterator<Cell> cellItr = row.cellIterator();
      // Iterate each cell in a row
      while(cellItr.hasNext()) {                
        Cell cell = cellItr.next();
        int index = cell.getColumnIndex();
        switch(index) {
          case 0:
            emp.setFirstName((String)getValueFromCell(cell));
            break;
          case 1:
            emp.setLastName((String)getValueFromCell(cell));
            break;
          case 2:
            emp.setDepartment((String)getValueFromCell(cell));
            break;
          case 3:
            // cast from Object to LocalDate
            emp.setDob((LocalDate)getValueFromCell(cell));
            break;
          case 4:
            // Formula value is just printed on the console
            System.out.println(getValueFromCell(cell));
            break;
        }
      }
      empList.add(emp);
    }
    for(Employee emp : empList) {
      System.out.println("Employee information- " + emp.toString());
    }    
  }
    
  // Utility method to get cell value based on cell type
  private Object getValueFromCell(Cell cell) {
    CellType cellType = cell.getCellType();
    if(cellType.equals(CellType.FORMULA)) {
      cellType = cell.getCachedFormulaResultType();
    }
    
    switch(cellType) {
      case STRING:
          return cell.getStringCellValue();
      case BOOLEAN:
          return cell.getBooleanCellValue();
      case NUMERIC:
      // Check for date in numeric cell (as date is also considered numeric)
        if(DateUtil.isCellDateFormatted(cell)) {
          return cell.getLocalDateTimeCellValue().toLocalDate();
        }
        return cell.getNumericCellValue();
      case BLANK:
        return "";
      default:
        return "";                                
    }
  }
}
Output
2024-03-21
2024-03-21
2024-03-21
Employee information- Employee [firstName=John, lastName=Emerson, department=Technology, dob=1990-11-12]
Employee information- Employee [firstName=Shelly, lastName=Mcarthy, department=HR, dob=1960-05-07]
Employee information- Employee [firstName=Tom, lastName=Cevor, department=Finance, dob=1992-03-03]

Excel file used in the code has only a single sheet which can be retrieved using- Sheet sheet = workbook.getSheetAt(0);

If there are more than one sheet in the workbook then you can iterate through the sheets too-

Iterator<Sheet> sheetIterator = workbook.sheetIterator();
while(sheetIterator.hasNext()) {
  Sheet sheet = sheetIterator.next();
  // get data from sheet
}

In an excel sheet, cells can have values of different data types. Cell class in Apache POI has different methods to get different types of cell values like getStringCellValue(), getBooleanCellValue() etc.

In order to use the correct method to extract value you need to know the data type of the cell value that's what is done in the getValueFromCell(Cell cell) method in the example code.

Some of the data types are as following-

  • Boolean
  • Blank
  • Formula
  • Numeric
  • String

There is actually no 'DATE' cell type in Excel. Date value is stored as Numeric type. That's why logic for date is in Numeric.

In case value of cell is of type 'Formula', use getCachedFormulaResultType() method to get the type of the value returned by the formula. Then use that type to get the actual value using the appropriate get method.

That's all for the topic Read Excel File in Java Using Apache POI. If something is missing or you have something to share about the topic please write a comment.


You may also like

February 1, 2024

Java ListIterator With Examples

In Java there is an Iterator interface which provides an iterator over a collection (List, Set etc.) but there is another interface ListIterator in Java which provides an iterator exclusively for lists like ArrayList, LinkedList, CopyOnWriteArrayList.

While iterator can only move forward, ListIterator provides functionality to traverse the List in either direction; forward or backward, which is one of the difference between Iterator and ListIterator in Java. Other differences are as follows.

  1. Both of these interfaces have remove() method to safely remove an element from List after the iterator is created but ListIterator has an add() method too.
  2. ListIterator also has a set() method to change the element while iterating a List.

No current element in ListIterator

A ListIterator has no current element; its cursor position always lies between the element that would be returned by a call to previous() and the element that would be returned by a call to next(). Following image shows the possible cursor positions for a list of length n.

ListIterator in Java

Java ListIterator methods

ListIterator interface in Java provides the following methods-

  1. add(E e)- Inserts the specified element into the list.
  2. hasNext()- Returns true if this list iterator has more elements when traversing the list in the forward direction.
  3. hasPrevious()- Returns true if this list iterator has more elements when traversing the list in the reverse direction.
  4. next()- Returns the next element in the list and advances the cursor position.
  5. nextIndex()- Returns the index of the element that would be returned by a subsequent call to next().
  6. previous()- Returns the previous element in the list and moves the cursor position backwards.
  7. previousIndex()- Returns the index of the element that would be returned by a subsequent call to previous().
  8. remove()- Removes from the list the last element that was returned by next() or previous().
  9. set(E e)- Replaces the last element returned by next() or previous() with the specified element.

Java ListIterator example with bi-directional traversal

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

public class ListIterationDemo {
  public static void main(String[] args) {
    List<String> carList = new LinkedList<String>();
    carList.add("Audi");
    carList.add("Jaguar");
    carList.add("BMW");
    carList.add("Mini Cooper");
    //Getting ListIterator
    ListIterator<String> ltr = carList.listIterator();
    //forward iteration
    System.out.println("List iteration - forward direction");
    while(ltr.hasNext()){
        System.out.println(ltr.next());
    }
    // backward iteration 
    System.out.println("List iteration - backward direction");
    while(ltr.hasPrevious()){
        System.out.println(ltr.previous());
    }
  }
}
Output
List iteration - forward direction
Audi
Jaguar
BMW
Mini Cooper
List iteration - backward direction
Mini Cooper
BMW
Jaguar
Audi

Example using add() and set() method of ListIterator

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

public class ListIterationDemo { 
  public static void main(String[] args) {
    List<String> carList = new LinkedList<String>();
    carList.add("Audi");
    carList.add("Jaguar");
    carList.add("BMW");
    carList.add("Mini Cooper");
    //Getting ListIterator
    ListIterator<String> ltr = carList.listIterator(); 
    while(ltr.hasNext()){
      String car = ltr.next();
      
      if(car.equals("BMW")) {
          ltr.add("Mercedes");
      }
      if(car.equals("Mini Cooper")) {
          ltr.set("Camry");
      }
    }
    System.out.println("List elements- " + carList);
  }
}
output
List elements- [Audi, Jaguar, BMW, Mercedes, Camry]

That's all for the topic Java ListIterator With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like