Releases: jdereg/java-util
Releases · jdereg/java-util
4.98.0
Changes
- PERFORMANCE:
CaseInsensitiveMap.get(),containsKey(), andremove()now use aThreadLocal<LookupKey>for String key lookups on hash-based backings (HashMap, LinkedHashMap, ConcurrentHashMap), eliminating per-callCaseInsensitiveStringallocation. This removes the single largest remaining allocation cost center (403 JFR samples).LookupKeyis a lightweight mutable object reused via ThreadLocal, with bidirectional equals support for both HashMap and ConcurrentHashMap lookup directions. SortedMap backings continue to useCaseInsensitiveStringsince they requireComparablekeys. - PERFORMANCE:
CaseInsensitiveMapnow overridessize()andisEmpty()to delegate directly to the backing map, bypassing theAbstractMap.size()→entrySet().size()indirection chain (168 JFR samples eliminated). - PERFORMANCE:
CaseInsensitiveMapinternal fields changed fromprivateto package-private to eliminate JVM synthetic accessor methods generated for anonymous inner class access (40 JFR samples eliminated). - PERFORMANCE:
StringUtilities.hashCodeIgnoreCase()now inlines the case-fold logic directly into the hash loop, ensuring C2 JIT compiles the entire loop as a single compilation unit. - PERFORMANCE:
StringUtilities.foldCaseForHash()branch ordering optimized to checkc <= 'Z'first, partitioning ASCII so uppercase and lowercase each take only two comparisons. - BUG FIX:
ConverterDurationToOffsetDateTimeTestused the current system timezone offset to compute expected values, but the conversion target is the epoch (1970). Fixed to compute the offset at the actual target instant. - TESTING: Added
ToonRoundTripTest— 46 parameterized tests verifying allConverter-supported types round-trip through TOON format. - TESTING: Added
ConverterDurationToOffsetDateTimeTest— verifies Duration → OffsetDateTime conversion across multiple scenarios.
Maven:
<dependency>
<groupId>com.cedarsoftware</groupId>
<artifactId>java-util</artifactId>
<version>4.98.0</version>
</dependency>4.97.0
Changes
- PERFORMANCE:
FastReader.readUntil()now splits the inner loop into a read-only delimiter scan followed by a bulkSystem.arraycopy, allowing the JIT to optimize the tight scan loop independently from memory writes. - PERFORMANCE:
FastReader.readUntil()scan loop now uses ado-whilewith a single array access per iteration and hoists position assignment above the delimiter check to eliminate a duplicate write.
Maven:
<dependency>
<groupId>com.cedarsoftware</groupId>
<artifactId>java-util</artifactId>
<version>4.97.0</version>
</dependency>4.96.0
Bug Fix
ClassUtilities.trySetAccessible()no longer caches successfulsetAccessible(true)results. TheWeakHashMap-based cache usesequals()for lookup, butField.equals()matches by declaring class, name, and type — not identity. WhengetDeclaredFields()was called with different predicates, the JVM returned differentFieldinstances for the same logical field; the cache returnedTRUEfor the second instance without ever callingsetAccessible(true)on it, leaving it inaccessible. This causedTraverserto silently skip inaccessible fields, breakingGraphComparator.applyDelta(). Only failures (FALSE) are now cached to avoid expensive repeated exceptions on JPMS-sealed modules.
Install
Maven
<dependency>
<groupId>com.cedarsoftware</groupId>
<artifactId>java-util</artifactId>
<version>4.96.0</version>
</dependency>Gradle
implementation 'com.cedarsoftware:java-util:4.96.0'