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(); } /**
