A faster and more comprehensive Java utility library.
For usage, please refer to the documentation and javadoc.
For performance comparison with Hutool, see jmh.comparison.
- Faster: Use JMH for performance testing.
- More complete:
- Safer: Use JUnit for suite testing and JaCoCo for code coverage testing, ensuring every line of code behaves as expected and reducing bugs.
<dependency>
<groupId>top.csaf</groupId>
<artifactId>zutil-all</artifactId>
<version>2.0.0-beta1</version>
</dependency>
// groovy
implementation 'top.csaf:zutil-all:2.0.0-beta1'
// kotlin
implementation("top.csaf:zutil-all:2.0.0-beta1")
This library includes slf4j-api
and slf4j-simple
, which conflict with spring-boot-starter-web
. You need to exclude them manually.
<!-- Option 1: Exclude slf4j from ZUtil -->
<dependency>
<groupId>top.csaf</groupId>
<artifactId>zutil-all</artifactId>
<version>2.0.0-beta1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Option 2: Exclude Logback from spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Reference: Excluding transitive dependencies - Gradle User Manual
// groovy
dependencies {
// Option 1: Exclude slf4j from ZUtil
implementation('top.csaf:zutil-all:2.0.0-beta1') {
exclude group: 'org.slf4j', module: 'slf4j-api'
exclude group: 'org.slf4j', module: 'slf4j-simple'
}
// Option 2: Exclude Logback from spring-boot-starter-web
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
// kotlin
dependencies {
// Option 1: Exclude slf4j from ZUtil
implementation("top.csaf:zutil-all:2.0.0-beta1") {
exclude(group = "org.slf4j", module = "slf4j-api")
exclude(group = "org.slf4j", module = "slf4j-simple")
}
// Option 2: Exclude Logback from spring-boot-starter-web
implementation("org.springframework.boot:spring-boot-starter-web") {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}
}
// Benchmark Mode Cnt Score Error Units
// ToPinyinTest.toPinyinByHutool thrpt 5 2.880 ± 0.160 ops/us
// ToPinyinTest.toPinyinByZUtil thrpt 5 4.577 ± 0.133 ops/us
// ToPinyinTest.toPinyinByHutool avgt 5 0.356 ± 0.012 us/op
// ToPinyinTest.toPinyinByZUtil avgt 5 0.216 ± 0.006 us/op
// ToPinyinTest.toPinyinByHutool sample 175058 0.435 ± 0.008 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p0.00 sample 0.300 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p0.50 sample 0.400 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p0.90 sample 0.500 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p0.95 sample 0.500 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p0.99 sample 0.900 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p0.999 sample 1.600 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p0.9999 sample 40.900 us/op
// ToPinyinTest.toPinyinByHutool:toPinyinByHutool·p1.00 sample 277.504 us/op
// ToPinyinTest.toPinyinByZUtil sample 162384 0.393 ± 0.008 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p0.00 sample 0.200 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p0.50 sample 0.300 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p0.90 sample 0.500 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p0.95 sample 0.600 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p0.99 sample 1.000 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p0.999 sample 2.500 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p0.9999 sample 45.425 us/op
// ToPinyinTest.toPinyinByZUtil:toPinyinByZUtil·p1.00 sample 170.496 us/op
// ToPinyinTest.toPinyinByHutool ss 5 30.880 ± 37.754 us/op
// ToPinyinTest.toPinyinByZUtil ss 5 23.060 ± 16.885 us/op
Mode (org.openjdk.jmh.annotations.Mode
):
- thrpt: Throughput (ops/time). Higher is better.
- avgt: Average time (time/op). Lower is better.
- sample: Sampling time. Lower is better.
- ss: Single shot invocation time. Lower is better.
- Fork and Clone the repo.
- Contribution types:
- Testing:
-
Use
org.junit.jupiter.api.Assertions
for code coverage testing:…… import top.csaf.id.NanoIdUtil; import static org.junit.jupiter.api.Assertions.*; @Slf4j @DisplayName("NanoId Utility Class Test") class NanoIdUtilTest { @DisplayName("Generate NanoID") @Test void randomNanoId() { /** {@link NanoIdUtil#randomNanoId(int, char[], java.util.Random) } */ assertThrows(NullPointerException.class, () -> NanoIdUtils.randomNanoId(0, (char[]) null, NanoIdUtils.DEFAULT_ID_GENERATOR)); assertThrows(NullPointerException.class, () -> NanoIdUtils.randomNanoId(0, new char[0], null)); assertThrows(IllegalArgumentException.class, () -> NanoIdUtils.randomNanoId(0, new char[0], NanoIdUtils.DEFAULT_ID_GENERATOR)); assertThrows(IllegalArgumentException.class, () -> NanoIdUtils.randomNanoId(1, new char[0], NanoIdUtils.DEFAULT_ID_GENERATOR)); assertThrows(IllegalArgumentException.class, () -> NanoIdUtils.randomNanoId(1, new char[256], NanoIdUtils.DEFAULT_ID_GENERATOR)); assertDoesNotThrow(() -> NanoIdUtils.randomNanoId(NanoIdUtils.DEFAULT_SIZE, NanoIdUtils.DEFAULT_ALPHABET, NanoIdUtils.DEFAULT_ID_GENERATOR)); } }
-
Run
mvn test -Dtest=ClassNameToTest
for testing, after whichjacoco.exec
will be generated under thetarget
directory. -
Run
mvn jacoco:report
to generate the code coverage report in thetarget/site
directory. -
Ensure coverage of updated classes or methods is above 90% before submitting.
-
Parameter validation using
lombok.NonNull
can be ignored.
-
- Follow the Angular Commit Message Guidelines when committing, then create a pull request.