Fix SpotBugs issues.

- [ERROR] Medium: org.apache.commons.io.file.CleaningPathVisitor doesn't
override CountingPathVisitor.equals(Object)
[org.apache.commons.io.file.CleaningPathVisitor] At
CleaningPathVisitor.java:[line 1] EQ_DOESNT_OVERRIDE_EQUALS
- [ERROR] Medium: org.apache.commons.io.file.CopyDirectoryVisitor
doesn't override CountingPathVisitor.equals(Object)
[org.apache.commons.io.file.CopyDirectoryVisitor] At
CopyDirectoryVisitor.java:[line 1] EQ_DOESNT_OVERRIDE_EQUALS
- [ERROR] Medium: org.apache.commons.io.file.DeletingPathVisitor doesn't
override CountingPathVisitor.equals(Object)
[org.apache.commons.io.file.DeletingPathVisitor] At
DeletingPathVisitor.java:[line 1] EQ_DOESNT_OVERRIDE_EQUALS
diff --git a/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java b/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java
index 80546c0..9df929b 100644
--- a/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/CleaningPathVisitor.java
@@ -60,16 +60,6 @@ public static CountingPathVisitor withLongCounters() {
      * Constructs a new visitor that deletes files except for the files and directories explicitly given.
      *
      * @param pathCounter How to count visits.
-     * @param skip The files to skip deleting.
-     */
-    public CleaningPathVisitor(final PathCounters pathCounter, final String... skip) {
-        this(pathCounter, PathUtils.EMPTY_DELETE_OPTION_ARRAY, skip);
-    }
-
-    /**
-     * Constructs a new visitor that deletes files except for the files and directories explicitly given.
-     *
-     * @param pathCounter How to count visits.
      * @param deleteOption options indicating how deletion is handled.
      * @param skip The files to skip deleting.
      * @since 2.8.0
@@ -84,6 +74,16 @@ public CleaningPathVisitor(final PathCounters pathCounter, final DeleteOption[]
     }
 
     /**
+     * Constructs a new visitor that deletes files except for the files and directories explicitly given.
+     *
+     * @param pathCounter How to count visits.
+     * @param skip The files to skip deleting.
+     */
+    public CleaningPathVisitor(final PathCounters pathCounter, final String... skip) {
+        this(pathCounter, PathUtils.EMPTY_DELETE_OPTION_ARRAY, skip);
+    }
+
+    /**
      * Returns true to process the given path, false if not.
      *
      * @param path the path to test.
@@ -94,6 +94,30 @@ private boolean accept(final Path path) {
     }
 
     @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final CleaningPathVisitor other = (CleaningPathVisitor) obj;
+        return overrideReadOnly == other.overrideReadOnly && Arrays.equals(skip, other.skip);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + Arrays.hashCode(skip);
+        result = prime * result + Objects.hash(overrideReadOnly);
+        return result;
+    }
+
+    @Override
     public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attributes) throws IOException {
         super.preVisitDirectory(dir, attributes);
         return accept(dir) ? FileVisitResult.CONTINUE : FileVisitResult.SKIP_SUBTREE;
diff --git a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java
index 7e46bbb..bb93ba5 100644
--- a/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/CopyDirectoryVisitor.java
@@ -23,6 +23,8 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Objects;
 
 import org.apache.commons.io.file.Counters.PathCounters;
 
@@ -67,6 +69,22 @@ protected void copy(final Path sourceFile, final Path targetFile) throws IOExcep
         Files.copy(sourceFile, targetFile, copyOptions);
     }
 
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final CopyDirectoryVisitor other = (CopyDirectoryVisitor) obj;
+        return Arrays.equals(copyOptions, other.copyOptions) && Objects.equals(sourceDirectory, other.sourceDirectory)
+                && Objects.equals(targetDirectory, other.targetDirectory);
+    }
+
     /**
      * Gets the copy options.
      *
@@ -98,6 +116,15 @@ public Path getTargetDirectory() {
     }
 
     @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + Arrays.hashCode(copyOptions);
+        result = prime * result + Objects.hash(sourceDirectory, targetDirectory);
+        return result;
+    }
+
+    @Override
     public FileVisitResult preVisitDirectory(final Path directory, final BasicFileAttributes attributes)
         throws IOException {
         final Path newTargetDir = targetDirectory.resolve(sourceDirectory.relativize(directory));
diff --git a/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java b/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java
index 7437650..d6913a4 100644
--- a/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java
+++ b/src/main/java/org/apache/commons/io/file/DeletingPathVisitor.java
@@ -61,17 +61,6 @@ public static DeletingPathVisitor withLongCounters() {
      * Constructs a new visitor that deletes files except for the files and directories explicitly given.
      *
      * @param pathCounter How to count visits.
-     *
-     * @param skip The files to skip deleting.
-     */
-    public DeletingPathVisitor(final PathCounters pathCounter, final String... skip) {
-        this(pathCounter, PathUtils.EMPTY_DELETE_OPTION_ARRAY, skip);
-    }
-
-    /**
-     * Constructs a new visitor that deletes files except for the files and directories explicitly given.
-     *
-     * @param pathCounter How to count visits.
      * @param deleteOption options indicating how deletion is handled.
      * @param skip The files to skip deleting.
      * @since 2.8.0
@@ -85,6 +74,17 @@ public DeletingPathVisitor(final PathCounters pathCounter, final DeleteOption[]
     }
 
     /**
+     * Constructs a new visitor that deletes files except for the files and directories explicitly given.
+     *
+     * @param pathCounter How to count visits.
+     *
+     * @param skip The files to skip deleting.
+     */
+    public DeletingPathVisitor(final PathCounters pathCounter, final String... skip) {
+        this(pathCounter, PathUtils.EMPTY_DELETE_OPTION_ARRAY, skip);
+    }
+
+    /**
      * Returns true to process the given path, false if not.
      *
      * @param path the path to test.
@@ -95,6 +95,30 @@ private boolean accept(final Path path) {
     }
 
     @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final DeletingPathVisitor other = (DeletingPathVisitor) obj;
+        return overrideReadOnly == other.overrideReadOnly && Arrays.equals(skip, other.skip);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + Arrays.hashCode(skip);
+        result = prime * result + Objects.hash(overrideReadOnly);
+        return result;
+    }
+
+    @Override
     public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
         if (PathUtils.isEmptyDirectory(dir)) {
             Files.deleteIfExists(dir);