From 5cc71f817ff97a17a9f1dfc72a6f10ebe701baaa Mon Sep 17 00:00:00 2001 From: Pavel Rappo Date: Mon, 17 Jul 2023 22:27:48 +0000 Subject: [PATCH] 8312089: Simplify and modernize equals, hashCode, and compareTo in java.nio and implementation code Reviewed-by: alanb, vtewari --- .../classes/java/nio/charset/Charset.java | 16 ++++---- .../share/classes/java/nio/file/Path.java | 7 ++-- .../java/nio/file/attribute/AclEntry.java | 20 ++++------ .../java/nio/file/attribute/FileTime.java | 4 +- .../unix/classes/sun/nio/ch/FileKey.java | 15 +++---- .../unix/classes/sun/nio/fs/UnixFileKey.java | 9 ++--- .../classes/sun/nio/fs/UnixFileStore.java | 5 +-- .../unix/classes/sun/nio/fs/UnixPath.java | 39 ++++--------------- .../sun/nio/fs/UnixUserPrincipals.java | 5 +-- .../windows/classes/sun/nio/ch/FileKey.java | 19 ++++----- .../classes/sun/nio/fs/WindowsPath.java | 9 ++--- .../sun/nio/fs/WindowsUserPrincipals.java | 8 ++-- .../sun/nio/fs/WindowsWatchService.java | 12 +++--- .../share/classes/jdk/nio/zipfs/ZipPath.java | 17 +------- 14 files changed, 62 insertions(+), 123 deletions(-) diff --git a/src/java.base/share/classes/java/nio/charset/Charset.java b/src/java.base/share/classes/java/nio/charset/Charset.java index 83dc81ba259..2958825e80c 100644 --- a/src/java.base/share/classes/java/nio/charset/Charset.java +++ b/src/java.base/share/classes/java/nio/charset/Charset.java @@ -954,15 +954,15 @@ public abstract class Charset * @return A negative integer, zero, or a positive integer as this charset * is less than, equal to, or greater than the specified charset */ + @Override public final int compareTo(Charset that) { return (name().compareToIgnoreCase(that.name())); } /** - * Computes a hashcode for this charset. - * - * @return An integer hashcode + * {@return the hashcode for this charset} */ + @Override public final int hashCode() { return name().hashCode(); } @@ -976,19 +976,17 @@ public abstract class Charset * @return {@code true} if, and only if, this charset is equal to the * given object */ + @Override public final boolean equals(Object ob) { - if (!(ob instanceof Charset)) - return false; if (this == ob) return true; - return name.equals(((Charset)ob).name()); + return ob instanceof Charset other && name.equals(other.name()); } /** - * Returns a string describing this charset. - * - * @return A string describing this charset + * {@return a string describing this charset} */ + @Override public final String toString() { return name(); } diff --git a/src/java.base/share/classes/java/nio/file/Path.java b/src/java.base/share/classes/java/nio/file/Path.java index d121f438a4f..e5699a96849 100644 --- a/src/java.base/share/classes/java/nio/file/Path.java +++ b/src/java.base/share/classes/java/nio/file/Path.java @@ -984,6 +984,7 @@ public interface Path * @return {@code true} if, and only if, the given object is a {@code Path} * that is identical to this {@code Path} */ + @Override boolean equals(Object other); /** @@ -995,10 +996,11 @@ public interface Path * * @return the hash-code value for this path */ + @Override int hashCode(); /** - * Returns the string representation of this path. + * {@return the string representation of this path} * *

If this path was created by converting a path string using the * {@link FileSystem#getPath getPath} method then the path string returned @@ -1006,8 +1008,7 @@ public interface Path * *

The returned path string uses the default name {@link * FileSystem#getSeparator separator} to separate names in the path. - * - * @return the string representation of this path */ + @Override String toString(); } diff --git a/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java b/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java index 9c00313591b..6f535410e02 100644 --- a/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java +++ b/src/java.base/share/classes/java/nio/file/attribute/AclEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -357,10 +357,6 @@ public final class AclEntry { return true; } - private static int hash(int h, Object o) { - return h * 127 + o.hashCode(); - } - /** * Returns the hash-code value for this ACL entry. * @@ -370,14 +366,12 @@ public final class AclEntry { @Override public int hashCode() { // return cached hash if available - if (hash != 0) - return hash; - int h = type.hashCode(); - h = hash(h, who); - h = hash(h, perms); - h = hash(h, flags); - hash = h; - return hash; + int h = hash; + if (h == 0) { + h = Objects.hash(type, who, perms, flags); + hash = h; + } + return h; } /** diff --git a/src/java.base/share/classes/java/nio/file/attribute/FileTime.java b/src/java.base/share/classes/java/nio/file/attribute/FileTime.java index 7cb3a3ea803..8a5989bf80a 100644 --- a/src/java.base/share/classes/java/nio/file/attribute/FileTime.java +++ b/src/java.base/share/classes/java/nio/file/attribute/FileTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -291,7 +291,7 @@ public final class FileTime */ @Override public boolean equals(Object obj) { - return (obj instanceof FileTime) ? compareTo((FileTime)obj) == 0 : false; + return obj instanceof FileTime other && compareTo(other) == 0; } /** diff --git a/src/java.base/unix/classes/sun/nio/ch/FileKey.java b/src/java.base/unix/classes/sun/nio/ch/FileKey.java index 0c3111464d7..e60e63f073d 100644 --- a/src/java.base/unix/classes/sun/nio/ch/FileKey.java +++ b/src/java.base/unix/classes/sun/nio/ch/FileKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,22 +44,19 @@ public class FileKey { return fk; } + @Override public int hashCode() { return (int)(st_dev ^ (st_dev >>> 32)) + (int)(st_ino ^ (st_ino >>> 32)); } + @Override public boolean equals(Object obj) { if (obj == this) return true; - if (!(obj instanceof FileKey)) - return false; - FileKey other = (FileKey)obj; - if ((this.st_dev != other.st_dev) || - (this.st_ino != other.st_ino)) { - return false; - } - return true; + return obj instanceof FileKey other + && (this.st_dev == other.st_dev) + && (this.st_ino == other.st_ino); } private native void init(FileDescriptor fd) throws IOException; diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileKey.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileKey.java index 92a2f44cc1b..29b1325f3e6 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileKey.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,10 +48,9 @@ class UnixFileKey { public boolean equals(Object obj) { if (obj == this) return true; - if (!(obj instanceof UnixFileKey)) - return false; - UnixFileKey other = (UnixFileKey)obj; - return (this.st_dev == other.st_dev) && (this.st_ino == other.st_ino); + return obj instanceof UnixFileKey other + && (this.st_dev == other.st_dev) + && (this.st_ino == other.st_ino); } @Override diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java index 0d793dc69bb..7f9348a81cb 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -234,9 +234,8 @@ abstract class UnixFileStore public boolean equals(Object ob) { if (ob == this) return true; - if (!(ob instanceof UnixFileStore)) + if (!(ob instanceof UnixFileStore other)) return false; - UnixFileStore other = (UnixFileStore)ob; return (this.dev == other.dev) && Arrays.equals(this.entry.dir(), other.entry.dir()) && this.entry.name().equals(other.entry.name()); diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixPath.java b/src/java.base/unix/classes/sun/nio/fs/UnixPath.java index 044c9321856..1a9b61fd803 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixPath.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixPath.java @@ -37,10 +37,12 @@ import java.nio.file.WatchEvent; import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.nio.file.spi.FileSystemProvider; +import java.util.Arrays; import java.util.Objects; import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; +import jdk.internal.util.ArraysSupport; import static sun.nio.fs.UnixConstants.*; import static sun.nio.fs.UnixNativeDispatcher.*; @@ -706,43 +708,17 @@ class UnixPath implements Path { // compare bytes int thisPos = offsets[thisOffsetCount - thatOffsetCount]; int thatPos = that.offsets[0]; - if ((thatLen - thatPos) != (thisLen - thisPos)) - return false; - while (thatPos < thatLen) { - if (this.path[thisPos++] != that.path[thatPos++]) - return false; - } - - return true; + return Arrays.equals(this.path, thisPos, thisLen, that.path, thatPos, thatLen); } @Override public int compareTo(Path other) { - int len1 = path.length; - int len2 = ((UnixPath) other).path.length; - - int n = Math.min(len1, len2); - byte v1[] = path; - byte v2[] = ((UnixPath) other).path; - - int k = 0; - while (k < n) { - int c1 = v1[k] & 0xff; - int c2 = v2[k] & 0xff; - if (c1 != c2) { - return c1 - c2; - } - k++; - } - return len1 - len2; + return Arrays.compareUnsigned(path, ((UnixPath) other).path); } @Override public boolean equals(Object ob) { - if (ob instanceof UnixPath path) { - return compareTo(path) == 0; - } - return false; + return ob instanceof UnixPath p && compareTo(p) == 0; } @Override @@ -750,9 +726,8 @@ class UnixPath implements Path { // OK if two or more threads compute hash int h = hash; if (h == 0) { - for (int i = 0; i< path.length; i++) { - h = 31*h + (path[i] & 0xff); - } + h = ArraysSupport.vectorizedHashCode(path, 0, path.length, 0, + /* unsigned bytes */ ArraysSupport.T_BOOLEAN); hash = h; } return h; diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java index 5b7612ac710..26da60fe2f8 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,9 +81,8 @@ public class UnixUserPrincipals { public boolean equals(Object obj) { if (obj == this) return true; - if (!(obj instanceof User)) + if (!(obj instanceof User other)) return false; - User other = (User)obj; if ((this.id != other.id) || (this.isGroup != other.isGroup)) { return false; diff --git a/src/java.base/windows/classes/sun/nio/ch/FileKey.java b/src/java.base/windows/classes/sun/nio/ch/FileKey.java index a3fe2550232..1f212ca2ba3 100644 --- a/src/java.base/windows/classes/sun/nio/ch/FileKey.java +++ b/src/java.base/windows/classes/sun/nio/ch/FileKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,24 +45,21 @@ public class FileKey { return fk; } + @Override public int hashCode() { return (int)(dwVolumeSerialNumber ^ (dwVolumeSerialNumber >>> 32)) + (int)(nFileIndexHigh ^ (nFileIndexHigh >>> 32)) + - (int)(nFileIndexLow ^ (nFileIndexHigh >>> 32)); + (int)(nFileIndexLow ^ (nFileIndexLow >>> 32)); } + @Override public boolean equals(Object obj) { if (obj == this) return true; - if (!(obj instanceof FileKey)) - return false; - FileKey other = (FileKey)obj; - if ((this.dwVolumeSerialNumber != other.dwVolumeSerialNumber) || - (this.nFileIndexHigh != other.nFileIndexHigh) || - (this.nFileIndexLow != other.nFileIndexLow)) { - return false; - } - return true; + return obj instanceof FileKey other + && this.dwVolumeSerialNumber == other.dwVolumeSerialNumber + && this.nFileIndexHigh == other.nFileIndexHigh + && this.nFileIndexLow == other.nFileIndexLow; } private native void init(FileDescriptor fd) throws IOException; diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java b/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java index 332454e987a..c3dc204bb9d 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -812,10 +812,7 @@ class WindowsPath implements Path { @Override public boolean equals(Object obj) { - if (obj instanceof WindowsPath path) { - return compareTo(path) == 0; - } - return false; + return obj instanceof WindowsPath other && compareTo(other) == 0; } @Override @@ -823,7 +820,7 @@ class WindowsPath implements Path { // OK if two or more threads compute hash int h = hash; if (h == 0) { - for (int i = 0; i< path.length(); i++) { + for (int i = 0; i < path.length(); i++) { h = 31*h + Character.toUpperCase(path.charAt(i)); } hash = h; diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java index 32d206883cf..cdb66296a63 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,10 +80,8 @@ class WindowsUserPrincipals { public boolean equals(Object obj) { if (obj == this) return true; - if (!(obj instanceof WindowsUserPrincipals.User)) - return false; - WindowsUserPrincipals.User other = (WindowsUserPrincipals.User)obj; - return this.sidString.equals(other.sidString); + return obj instanceof WindowsUserPrincipals.User other + && this.sidString.equals(other.sidString); } @Override diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java b/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java index d5b82285075..d051c833ee7 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -231,12 +231,10 @@ class WindowsWatchService public boolean equals(Object obj) { if (obj == this) return true; - if (!(obj instanceof FileKey)) - return false; - FileKey other = (FileKey)obj; - if (this.volSerialNumber != other.volSerialNumber) return false; - if (this.fileIndexHigh != other.fileIndexHigh) return false; - return this.fileIndexLow == other.fileIndexLow; + return obj instanceof FileKey other + && this.volSerialNumber == other.volSerialNumber + && this.fileIndexHigh == other.fileIndexHigh + && this.fileIndexLow == other.fileIndexLow; } } diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java index 806c8d352bf..66af78e53d2 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -636,20 +636,7 @@ final class ZipPath implements Path { @Override public int compareTo(Path other) { final ZipPath o = checkPath(other); - int len1 = this.path.length; - int len2 = o.path.length; - - int n = Math.min(len1, len2); - - int k = 0; - while (k < n) { - int c1 = this.path[k] & 0xff; - int c2 = o.path[k] & 0xff; - if (c1 != c2) - return c1 - c2; - k++; - } - return len1 - len2; + return Arrays.compareUnsigned(this.path, o.path); } public WatchKey register(