This is an automated email from the ASF dual-hosted git repository.

mawiesne pushed a commit to branch 
OPENNLP-1759-Optimize-computation-of-hashCode-in-StringList
in repository https://gitbox.apache.org/repos/asf/opennlp.git

commit 7da1d6bb6bccf17478ad29f1c6022dc1abbd3efd
Author: Martin Wiesner <[email protected]>
AuthorDate: Tue Jul 8 13:45:54 2025 +0200

    OPENNLP-1759: Optimize computation of hashCode in StringList
---
 .../main/java/opennlp/tools/util/StringList.java   | 33 ++++++++--------------
 1 file changed, 12 insertions(+), 21 deletions(-)

diff --git 
a/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/StringList.java 
b/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/StringList.java
index 004292bd..8a1a4e64 100644
--- 
a/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/StringList.java
+++ 
b/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/StringList.java
@@ -30,9 +30,11 @@ import opennlp.tools.util.jvm.StringInterners;
 public class StringList implements Iterable<String> {
 
   private final String[] tokens;
-
   private final boolean caseSensitive;
 
+  // It is safe to use caching of the hashCode for this class
+  private transient Integer hashCode = null; // initial value is uncomputed
+  
   /**
    * Initializes a {@link StringList} instance. By default, this instance is 
case-sensitive.
    * <p>
@@ -53,7 +55,7 @@ public class StringList implements Iterable<String> {
    *
    * @param tokens The string parts of the new {@link StringList}.
    *               Must not be an empty tokens array or {@code null}.
-   *               
+   *
    * @throws IllegalArgumentException Thrown if parameters were invalid.
    */
   public StringList(String... tokens) {
@@ -73,7 +75,6 @@ public class StringList implements Iterable<String> {
    * @throws IllegalArgumentException Thrown if parameters were invalid.
    */
   public StringList(boolean isCaseSensitive, String... tokens) {
-
     Objects.requireNonNull(tokens, "tokens must not be null");
 
     if (tokens.length == 0) {
@@ -81,7 +82,6 @@ public class StringList implements Iterable<String> {
     }
 
     this.tokens = new String[tokens.length];
-
     for (int i = 0; i < tokens.length; i++) {
       this.tokens[i] = StringInterners.intern(tokens[i]);
     }
@@ -161,8 +161,11 @@ public class StringList implements Iterable<String> {
 
   @Override
   public int hashCode() {
-    // if lookup is too slow optimize this
-    return StringUtil.toLowerCase(toString()).hashCode();
+    if (hashCode == null) {
+      // compute once and cache to safe CPU cycles during use
+      this.hashCode = StringUtil.toLowerCase(String.join(",", 
tokens)).hashCode();
+    }
+    return hashCode;
   }
 
   @Override
@@ -184,21 +187,9 @@ public class StringList implements Iterable<String> {
    */
   @Override
   public String toString() {
-    StringBuilder string = new StringBuilder();
-
-    string.append('[');
-
-    for (int i = 0; i < size(); i++) {
-      string.append(getToken(i));
-
-      if (i < size() - 1) {
-        string.append(',');
-      }
-    }
-
-    string.append(']');
-
-    return string.toString();
+    StringBuilder sb = new StringBuilder();
+    sb.append('[').append(String.join(",", tokens)).append(']');
+    return sb.toString();
   }
 
   /**

Reply via email to