How do I implement equals() method using EqualsBuilder class?

This code snippet show you how to use HashCodeBuilder and EqualsBuilder class from the Apache Commons Lang library to implement the hashCode() and equals() method of an object. To use both of these classes, we just need to create instance of these classes and append the properties that we will use to calculate the hashcode and to test for equality.

Implementing the hashCode() method first by creating the hashCode() method. Add the @Override annotation to make sure that we’ve overridden the correct method. Then we create an instance of HashCodeBuilder. Append the fields we’re going to use to calculate the hashcode. The final result of the actual hashcode can be obtained by calling the toHashCode() from the instance of HashCodeBuilder.

/**
 * Implement the hashCode() method using HashCodeBuilder.
 */
@Override
public int hashCode() {
    return new HashCodeBuilder().append(id).append(name).toHashCode();
}

We do the same to create the equals() method. First create the method, it takes a single argument type of java.lang.Object. Add the @Override annotation to make sure we override the correct method. On the first line you can check to see if the passed object is an instance of the same object, we use the instanceof operator. We then compare the values stored in both objects using the EqualsBuilder class. To get the equality result, we must remember to call the isEquals() method.

/**
 * Implement the equals() method using the EqualsBuilder.
 */
@Override
public boolean equals(Object obj) {
    if (!(obj instanceof DummyUser that)) {
        return false;
    }
    return new EqualsBuilder().append(this.id, that.id)
            .append(this.name, that.name).isEquals();
}

Here is the complete look of the snippet.

package org.kodejava.commons.lang;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class DummyUser {
    private Long id;
    private String name;

    /**
     * Constructor to create an instance of this class.
     */
    public DummyUser() {
    }

    public static void main(String[] args) {
        DummyUser user1 = new DummyUser();
        user1.setId(10L);
        user1.setName("Carol");

        DummyUser user2 = new DummyUser();
        user2.setId(10L);
        user2.setName("Carol");

        System.out.println("user1.hashCode() = " + user1.hashCode());
        System.out.println("user2.hashCode() = " + user2.hashCode());

        System.out.println("user1.equals(user2) = " + user1.equals(user2));
    }

    // Getters & Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * Implement the hashCode() method using HashCodeBuilder.
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(id).append(name).toHashCode();
    }

    /**
     * Implement the equals() method using the EqualsBuilder.
     */
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof DummyUser that)) {
            return false;
        }
        return new EqualsBuilder().append(this.id, that.id)
                .append(this.name, that.name).isEquals();
    }
}

The results of our code are:

user1.hashCode() = 64902380
user2.hashCode() = 64902380
user1.equals(user2) = true

Maven Dependencies

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

Maven Central

How do I implement hashCode() method using HashCodeBuilder class?

package org.kodejava.commons.lang;

public class ObjectHashCodeDemo {

    public static void main(String[] args) {
        Book book1 = new Book(1L, "Spring Boot in Action", "Craig Walls");
        Book book2 = new Book(2L, "Docker in Action", "Jeff Nickoloff");
        Book book3 = book1;

        System.out.println("book1.hashCode() = " + book1.hashCode());
        System.out.println("book2.hashCode() = " + book2.hashCode());
        System.out.println("book3.hashCode() = " + book3.hashCode());
    }
}
package org.kodejava.commons.lang;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.io.Serializable;

public class Book implements Serializable {
    private Long id;
    private String title;
    private String author;

    public Book(Long id, String title, String author) {
        this.id = id;
        this.title = title;
        this.author = author;
    }

    //~ Implements getters and setters here.

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if (!(o instanceof Book)) {
            return false;
        }

        Book that = (Book) o;
        return new EqualsBuilder()
            .append(this.id, that.id)
            .append(this.title, that.title)
            .append(this.author, that.author)
            .isEquals();

        // You can also use reflection of the EqualsBuilder class.
        // return EqualsBuilder.reflectionEquals(this, that);
    }

    public int hashCode() {
        return new HashCodeBuilder()
            .append(id)
            .append(title)
            .append(author)
            .toHashCode();

        // Or even use the simplest method using reflection below.
        // return HashCodeBuilder.reflectionHashCode(this);
    }
}

Maven Dependencies

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

Maven Central

How do I create an empty collection object?

Sometimes you need to return an empty collection from your Java methods. The java.util.Collections utility class have three different static constants for creating empty List, Set and Map.

  • Collections.EMPTY_LIST
  • Collections.EMPTY_SET
  • Collections.EMPTY_MAP

There are also methods when you want to create type-safe empty collections.

  • Collections.emptyList()
  • Collections.emptySet()
  • Collections.emptyMap()

Bellow it the code example.

package org.kodejava.util;

import java.util.*;

public class EmptyCollectionDemo {
    public static void main(String[] args) {
        List list = Collections.EMPTY_LIST;
        System.out.println("list.size()  = " + list.size());
        Set set = Collections.EMPTY_SET;
        System.out.println("set.size()   = " + set.size());
        Map map = Collections.EMPTY_MAP;
        System.out.println("map.size()   = " + map.size());

        // For the type-safe example use the following methods.
        List<String> strings = Collections.emptyList();
        System.out.println("strings.size = " + strings.size());

        Set<Long> longs = Collections.emptySet();
        System.out.println("longs.size() = " + longs.size());

        Map<String, Date> dates = Collections.emptyMap();
        System.out.println("dates.size() = " + dates.size());
    }
}

The output are:

list.size()  = 0
set.size()   = 0
map.size()   = 0
strings.size = 0
longs.size() = 0
dates.size() = 0

How do I write string data to file?

The following code snippet shows you how to write strings of data into a file using the Apache Commons IO library. We can use the FileUtils.writeStringToFile() method to do it. This method accepts the file object where the data will be stored, the data itself, and the encoding.

package org.kodejava.commons.io;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class WriteToFileExample {
    public static void main(String[] args) {
        try {
            // Here we'll write our data into a file called
            // output.txt; this is the output.
            File file = new File("output.txt");
            // We'll write the string below into the file
            String data = "Learn Java by Examples";

            // To write a file called the writeStringToFile
            // method which requires you to pass the file and
            // the data to be written.
            FileUtils.writeStringToFile(file, data, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Maven Dependencies

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.14.0</version>
</dependency>

Maven Central

How do I calculate directory size?

In this example, we are going to use the Apache Commons IO library to get or calculate the total size of a directory. The FileUtils class provided by the Commons IO can help us to achieve this goal.

The first method that we can use is the FileUtils.sizeOfDirectory(), it calculates the size of a directory recursively. It takes a File object that represent a directory as parameter and returns long value. If the directory has security restriction this method return 0. A negative value returned when the directory size if bigger than Long.MAX_VALUE.

You can also use the FileUtils.sizeOfDirectoryAsBigInteger() method. This method returns the result as BigInteger as the method name describe. As the first method, this method also return 0 when the directory has a security restriction.

Both of the methods described above return the directory size in byte. If you want a more human-readable size you can utilize the FileUtils.byteCountToDisplaySize() method, it will convert the byte value into something like 1 MB, 1 GB.

package org.kodejava.commons.io;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.math.BigInteger;

public class DirectorySizeSample {
    public static void main(String[] args) {
        // sizeOfDirectory
        File tempDir = new File("/Users/wayan/Temp");
        long size = FileUtils.sizeOfDirectory(tempDir);
        System.out.println("TempDir size = " + size + " bytes");
        System.out.println("TempDir size = " +
                FileUtils.byteCountToDisplaySize(size));

        // sizeOfDirectoryAsBigInteger()
        File dropboxDir = new File("/Users/wayan/Dropbox");
        BigInteger sizeBig = FileUtils.sizeOfDirectoryAsBigInteger(dropboxDir);
        System.out.println("DropboxDir size = " + sizeBig);
        System.out.println("DropboxDir size = " +
                FileUtils.byteCountToDisplaySize(sizeBig));
    }
}

The result of the code snippet above:

TempDir size = 514239345 bytes
TempDir size = 490 MB
DropboxDir size = 6184
DropboxDir size = 6 KB

Maven Dependencies

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.14.0</version>
</dependency>

Maven Central

How do I read text file content line by line to a List of Strings using Commons IO?

The following example show how to use the Apache Commons IO library to read a text file line by line to a List of String. In the code snippet below we will read the contents of a file called sample.txt using FileUtils class. We use FileUtils.readLines() method to read the contents line by line and return the result as a List of Strings.

package org.kodejava.commons.io;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.List;

public class ReadFileToListSample {
    public static void main(String[] args) {
        // Create a file object of sample.txt
        File file = new File("README.md");

        try {
            List<String> contents = FileUtils.readLines(file, "UTF-8");

            // Iterate the result to print each line of the file.
            for (String line : contents) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Maven Dependencies

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.14.0</version>
</dependency>

Maven Central

How do I read file contents to string using Commons IO?

In this example we use FileUtils class from Apache Commons IO to read the content of a file. FileUtils have two static methods called readFileToString(File) and readFileToString(File, String) that we can use.

An example to read file contents and return the result as a string can be seen below.

package org.kodejava.commons.io;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public class ReadFileToStringSample {
    public static void main(String[] args) {
        // Here we create an instance of File for sample.txt file.
        File file = new File("sample.txt");

        try {
            // Read the entire contents of sample.txt
            String content = FileUtils.readFileToString(file, "UTF-8");
            System.out.println("File content: " + content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}                                                                  

Maven Dependencies

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.14.0</version>
</dependency>

Maven Central

How do I read entries in a zip / compressed file?

package org.kodejava.util.zip;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class ZipFileExample {
    public static void main(String[] args) {
        try {
            // Create an instance of ZipFile to read a zip file
            // called sample.zip
            ZipFile zip = new ZipFile(new File("data.zip"));

            // Here we start to iterate each entry inside
            // sample.zip
            for (Enumeration<?> e = zip.entries(); e.hasMoreElements(); ) {
                // Get ZipEntry which is a file or a directory
                ZipEntry entry = (ZipEntry) e.nextElement();

                // Get some information about the entry such as
                // file name, its size.
                System.out.println("File name: " + entry.getName()
                    + "; size: " + entry.getSize()
                    + "; compressed size: "
                    + entry.getCompressedSize());
                System.out.println();

                // Now we want to get the content of this entry.
                // Get the InputStream, we read through the input
                // stream until all the content is read.
                InputStream is = zip.getInputStream(entry);
                InputStreamReader isr = new InputStreamReader(is);

                char[] buffer = new char[1024];
                while (isr.read(buffer, 0, buffer.length) != -1) {
                    String s = new String(buffer);
                    // Here we just print out what is inside the
                    // buffer.
                    System.out.println(s.trim());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

What is Autoboxing?

Autoboxing is a new feature offered in the Tiger (1.5) release of Java SDK. In short auto boxing is a capability to convert or cast between object wrappers (Integer, Long, etc) and their primitive types.

Previously when placing primitive data into one of the Java Collection Framework object we have to wrap it to an object because the collection cannot work with primitive data. Also, when calling a method that requires an instance of object rather than an int or long, we have to convert it too.

Now, starting from version Java 1.5 we have a new feature in the Java Language which automate this process, its call the Autoboxing. When we place an int value into a collection, such as List, it will be converted into an Integer object behind the scene. When we read it back, it will automatically convert to the primitive type. In most way this simplifies the way we code, no need to do an explicit object casting.

Here an example how it will look like using the Autoboxing feature:

package org.kodejava.basic;

import java.util.HashMap;
import java.util.Map;

public class Autoboxing {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();

        // Here we put an int into the Map, and it accepted
        // as it will be autoboxed or converted into the wrapper
        // of this type, in this case the Integer object.
        map.put("Age", 25);

        // Here we can just get the value from the map, no need
        // to cast it from Integer to int.
        int age = map.get("Age");

        // Here we simply do the math on the primitive type
        // and got the result as an Integer.
        Integer newAge = age + 10;
    }
}

How do I use Java NIO to copy file?

The following code snippet show you how to copy a file using the NIO API. The NIO (New IO) API is in the java.nio.* package. It requires at least Java 1.4 because the API was first included in this version. The JAVA NIO is a block based IO processing, instead of a stream based IO which is the old version IO processing in Java.

package org.kodejava.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;

public class CopyFileExample {
    public static void main(String[] args) throws Exception {
        String source = "medical-report.txt";
        String destination = "medical-report-final.txt";

        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(destination);

        FileChannel inputChannel = fis.getChannel();
        FileChannel outputChannel = fos.getChannel();

        // Create a buffer with 1024 size for buffering data
        // while copying from source file to destination file.
        // To create the buffer here we used a static method
        // ByteBuffer.allocate()
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        // Here we start to read the source file and write it
        // to the destination file. We repeat this process
        // until the read method of input stream channel return
        // nothing (-1).
        while (true) {
            // Read a block of data and put it in the buffer
            int read = inputChannel.read(buffer);

            // Did we reach the end of the channel? if yes
            // jump out the while-loop
            if (read == -1) {
                break;
            }

            // flip the buffer
            buffer.flip();

            // write to the destination channel and clear the buffer.
            outputChannel.write(buffer);
            buffer.clear();
        }
    }
}