@@ -8,9 +8,9 @@
|
|||||||
name: Publish Packages to GitHub Packages with Gradle
|
name: Publish Packages to GitHub Packages with Gradle
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
release:
|
||||||
branches:
|
types:
|
||||||
- main
|
- published
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -51,19 +51,17 @@ jobs:
|
|||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: "17"
|
||||||
distribution: 'corretto'
|
distribution: "corretto"
|
||||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
|
||||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
|
||||||
|
|
||||||
- name: Setup Gradle
|
- name: Setup Gradle
|
||||||
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0
|
uses: gradle/actions/setup-gradle@v4
|
||||||
|
|
||||||
- name: Grant Execution Authority to Gradlew
|
- name: Grant Execution Authority to Gradlew
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew build
|
run: ./gradlew build -PartefactVersion=${{ github.event.release.tag_name }} # Overwrite artefactVersion
|
||||||
|
|
||||||
- name: Publish to Maven Central
|
- name: Publish to Maven Central
|
||||||
run: ./gradlew publish
|
run: ./gradlew publish
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package com.onixbyte.devkit.utils;
|
package com.onixbyte.devkit.utils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
@@ -89,62 +88,50 @@ public final class BranchUtil<T> {
|
|||||||
* Creates a {@code BranchUtil} instance to evaluate a logical OR operation on the provided
|
* Creates a {@code BranchUtil} instance to evaluate a logical OR operation on the provided
|
||||||
* boolean expressions.
|
* boolean expressions.
|
||||||
*
|
*
|
||||||
* @param booleans the boolean expressions to be evaluated
|
* @param values the boolean expressions to be evaluated
|
||||||
* @param <T> the type of the result to be handled by the methods
|
* @param <T> the type of the result to be handled by the methods
|
||||||
* @return a {@code BranchUtil} instance representing the result of the logical OR operation
|
* @return a {@code BranchUtil} instance representing the result of the logical OR operation
|
||||||
*/
|
*/
|
||||||
public static <T> BranchUtil<T> or(Boolean... booleans) {
|
public static <T> BranchUtil<T> or(Boolean... values) {
|
||||||
var result = Arrays.stream(booleans)
|
return new BranchUtil<>(BoolUtil.or(values));
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.anyMatch(Boolean::booleanValue);
|
|
||||||
return new BranchUtil<>(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code BranchUtil} instance to evaluate a logical AND operation on the provided
|
* Creates a {@code BranchUtil} instance to evaluate a logical AND operation on the provided
|
||||||
* boolean expressions.
|
* boolean expressions.
|
||||||
*
|
*
|
||||||
* @param booleans the boolean expressions to be evaluated
|
* @param values the boolean expressions to be evaluated
|
||||||
* @param <T> the type of the result to be handled by the methods
|
* @param <T> the type of the result to be handled by the methods
|
||||||
* @return a {@code BranchUtil} instance representing the result of the logical AND operation
|
* @return a {@code BranchUtil} instance representing the result of the logical AND operation
|
||||||
*/
|
*/
|
||||||
public static <T> BranchUtil<T> and(Boolean... booleans) {
|
public static <T> BranchUtil<T> and(Boolean... values) {
|
||||||
var result = Arrays.stream(booleans)
|
return new BranchUtil<>(BoolUtil.and(values));
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.allMatch(Boolean::booleanValue);
|
|
||||||
return new BranchUtil<>(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code BranchUtil} instance to evaluate a logical OR operation on the provided
|
* Creates a {@code BranchUtil} instance to evaluate a logical OR operation on the provided
|
||||||
* boolean suppliers.
|
* boolean suppliers.
|
||||||
*
|
*
|
||||||
* @param booleanSuppliers the boolean suppliers to be evaluated
|
* @param valueSuppliers the boolean suppliers to be evaluated
|
||||||
* @param <T> the type of the result to be handled by the methods
|
* @param <T> the type of the result to be handled by the methods
|
||||||
* @return a {@code BranchUtil} instance representing the result of the
|
* @return a {@code BranchUtil} instance representing the result of the
|
||||||
* logical OR operation
|
* logical OR operation
|
||||||
*/
|
*/
|
||||||
public static <T> BranchUtil<T> or(BooleanSupplier... booleanSuppliers) {
|
public static <T> BranchUtil<T> or(BooleanSupplier... valueSuppliers) {
|
||||||
var result = Arrays.stream(booleanSuppliers)
|
return new BranchUtil<>(BoolUtil.or(valueSuppliers));
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.anyMatch(BooleanSupplier::getAsBoolean);
|
|
||||||
return new BranchUtil<>(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code BranchUtil} instance to evaluate a logical AND operation on the provided
|
* Creates a {@code BranchUtil} instance to evaluate a logical AND operation on the provided
|
||||||
* boolean suppliers.
|
* boolean suppliers.
|
||||||
*
|
*
|
||||||
* @param booleanSuppliers the boolean suppliers to be evaluated
|
* @param valueSuppliers the boolean suppliers to be evaluated
|
||||||
* @param <T> the type of the result to be handled by the methods
|
* @param <T> the type of the result to be handled by the methods
|
||||||
* @return a {@code BranchUtil} instance representing the result of the
|
* @return a {@code BranchUtil} instance representing the result of the
|
||||||
* logical AND operation
|
* logical AND operation
|
||||||
*/
|
*/
|
||||||
public static <T> BranchUtil<T> and(BooleanSupplier... booleanSuppliers) {
|
public static <T> BranchUtil<T> and(BooleanSupplier... valueSuppliers) {
|
||||||
var result = Arrays.stream(booleanSuppliers)
|
return new BranchUtil<>(BoolUtil.and(valueSuppliers));
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.allMatch(BooleanSupplier::getAsBoolean);
|
|
||||||
return new BranchUtil<>(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+8
-9
@@ -15,18 +15,17 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
jacksonVersion=2.17.2
|
jacksonVersion=2.18.0
|
||||||
javaJwtVersion=4.4.0
|
javaJwtVersion=4.4.0
|
||||||
jjwtVersion=0.12.6
|
junitVersion=5.11.2
|
||||||
junitVersion=5.10.2
|
logbackVersion=1.5.10
|
||||||
logbackVersion=1.5.4
|
lombokVersion=1.18.34
|
||||||
lombokVersion=1.18.30
|
slf4jVersion=2.0.16
|
||||||
slf4jVersion=2.0.9
|
springVersion=6.1.13
|
||||||
springVersion=6.1.3
|
springBootVersion=3.3.4
|
||||||
springBootVersion=3.2.3
|
|
||||||
|
|
||||||
buildGroupId=com.onixbyte
|
buildGroupId=com.onixbyte
|
||||||
buildVersion=1.6.4
|
buildVersion=1.6.5
|
||||||
projectUrl=https://onixbyte.com/JDevKit
|
projectUrl=https://onixbyte.com/JDevKit
|
||||||
projectGithubUrl=https://github.com/OnixByte/JDevKit
|
projectGithubUrl=https://github.com/OnixByte/JDevKit
|
||||||
licenseName=The Apache License, Version 2.0
|
licenseName=The Apache License, Version 2.0
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
plugins {
|
||||||
|
id("java")
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "com.onixbyte"
|
||||||
|
version = "unspecified"
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testImplementation(platform("org.junit:junit-bom:5.10.0"))
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
+2
-2
@@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.onixbyte.devkit.utils;
|
package com.onixbyte.nums;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ import java.util.function.Function;
|
|||||||
*
|
*
|
||||||
* @author sunzsh
|
* @author sunzsh
|
||||||
* @version 1.1.0
|
* @version 1.1.0
|
||||||
* @see java.math.BigDecimal
|
* @see BigDecimal
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024 OnixByte.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.onixbyte.nums;
|
||||||
|
|
||||||
|
import com.onixbyte.nums.model.QuartileBounds;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class that provides methods for calculating percentiles and interquartile range (IQR) bounds
|
||||||
|
* for a dataset.
|
||||||
|
* <p>
|
||||||
|
* This class contains static methods to:
|
||||||
|
* <ul>
|
||||||
|
* <li>Calculate a specified percentile from a list of double values using linear interpolation.</li>
|
||||||
|
* <li>Calculate interquartile bounds (Q1, Q3) and the corresponding lower and upper bounds,
|
||||||
|
* which can be used to identify outliers in the dataset.</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* This class is final, meaning it cannot be subclassed, and it only contains static methods,
|
||||||
|
* so instances of the class cannot be created.
|
||||||
|
* </p>
|
||||||
|
* <h2>Example usage:</h2>
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* List<Double> data = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0);
|
||||||
|
* Double percentileValue = PercentileCalculator.calculatePercentile(data, 50.0); // Calculates median
|
||||||
|
* QuartileBounds bounds = PercentileCalculator.calculatePercentileBounds(data); // Calculates IQR bounds
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author zihluwang
|
||||||
|
* @version 1.6.5
|
||||||
|
* @since 1.6.5
|
||||||
|
*/
|
||||||
|
public final class PercentileCalculator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the specified percentile from a list of values.
|
||||||
|
* <p>
|
||||||
|
* This method takes a list of double values and calculates the given percentile using linear interpolation between
|
||||||
|
* the two closest ranks. The list is first sorted in ascending order, and the specified percentile is
|
||||||
|
* then calculated.
|
||||||
|
*
|
||||||
|
* @param values a list of {@code Double} values from which the percentile is calculated.
|
||||||
|
* @param percentile a {@code Double} representing the percentile to be calculated (e.g., 50.0 for the median)
|
||||||
|
* @return a {@code Double} value representing the calculated percentile
|
||||||
|
*/
|
||||||
|
public static Double calculatePercentile(List<Double> values, Double percentile) {
|
||||||
|
var sorted = values.stream().sorted().toList();
|
||||||
|
if (sorted.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("Unable to sort an empty list.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var rank = percentile / 100. * (sorted.size() - 1);
|
||||||
|
var lowerIndex = (int) Math.floor(rank);
|
||||||
|
var upperIndex = (int) Math.ceil(rank);
|
||||||
|
var weight = rank - lowerIndex;
|
||||||
|
|
||||||
|
return sorted.get(lowerIndex) * (1 - weight) + sorted.get(upperIndex) * weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the interquartile range (IQR) and the corresponding lower and upper bounds
|
||||||
|
* based on the first (Q1) and third (Q3) quartiles of a dataset.
|
||||||
|
* <p>
|
||||||
|
* This method takes a list of double values, calculates the first quartile (Q1),
|
||||||
|
* the third quartile (Q3), and the interquartile range (IQR). Using the IQR, it computes
|
||||||
|
* the lower and upper bounds, which can be used to detect outliers in the dataset.
|
||||||
|
* The lower bound is defined as {@code Q1 - 1.5 * IQR}, and the upper bound is defined as
|
||||||
|
* {@code Q3 + 1.5 * IQR}.
|
||||||
|
*
|
||||||
|
* @param data a list of {@code Double} values for which the quartile bounds will be calculated
|
||||||
|
* @return a {@code QuartileBounds} object containing the calculated lower and upper bounds
|
||||||
|
*/
|
||||||
|
public static QuartileBounds calculatePercentileBounds(List<Double> data) {
|
||||||
|
var sorted = data.stream().sorted().toList();
|
||||||
|
var Q1 = calculatePercentile(sorted, 25.);
|
||||||
|
var Q3 = calculatePercentile(sorted, 75.);
|
||||||
|
|
||||||
|
var IQR = Q3 - Q1;
|
||||||
|
|
||||||
|
var lowerBound = Q1 - 1.5 * IQR;
|
||||||
|
var upperBound = Q3 + 1.5 * IQR;
|
||||||
|
|
||||||
|
return QuartileBounds.builder()
|
||||||
|
.upperBound(upperBound)
|
||||||
|
.lowerBound(lowerBound)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2024-2024 OnixByte.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.onixbyte.nums.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A record representing the quartile bounds of a dataset.
|
||||||
|
* <p>
|
||||||
|
* This class encapsulates the lower and upper bounds of a dataset, which are typically used for detecting outliers in
|
||||||
|
* the data. The bounds are calculated based on the interquartile range (IQR) of the dataset. Values below the lower
|
||||||
|
* bound or above the upper bound may be considered outliers.
|
||||||
|
* <p>
|
||||||
|
* Quartile bounds consist of:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@code lowerBound} - The lower bound of the dataset, typically {@code Q1 - 1.5 * IQR}.</li>
|
||||||
|
* <li>{@code upperBound} - The upper bound of the dataset, typically {@code Q3 + 1.5 * IQR}.</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Example usage:
|
||||||
|
* <pre>
|
||||||
|
* QuartileBounds bounds = QuartileBounds.builder()
|
||||||
|
* .lowerBound(1.5)
|
||||||
|
* .upperBound(7.5)
|
||||||
|
* .build();
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param upperBound the upper bound of the dataset
|
||||||
|
* @param lowerBound the lower bound of the dataset
|
||||||
|
* @author zihluwang
|
||||||
|
* @version 1.6.5
|
||||||
|
* @since 1.6.5
|
||||||
|
*/
|
||||||
|
public record QuartileBounds(
|
||||||
|
Double upperBound,
|
||||||
|
Double lowerBound
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link Builder} instance for building a {@code QuartileBounds} object.
|
||||||
|
* <p>
|
||||||
|
* The {@link Builder} pattern is used to construct the {@code QuartileBounds} object with optional values for the
|
||||||
|
* upper and lower bounds.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a new instance of the {@link Builder} class
|
||||||
|
*/
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder class for constructing instances of the {@code QuartileBounds} record.
|
||||||
|
* <p>
|
||||||
|
* The {@link Builder} pattern allows for the step-by-step construction of a {@code QuartileBounds} object,
|
||||||
|
* providing a flexible way to set values for the lower and upper bounds. Once the builder has the required values,
|
||||||
|
* the {@link #build()} method creates and returns a new {@code QuartileBounds} object.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Example usage:
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* QuartileBounds bounds = QuartileBounds.builder()
|
||||||
|
* .lowerBound(1.5)
|
||||||
|
* .upperBound(7.5)
|
||||||
|
* .build();
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
private Double upperBound;
|
||||||
|
private Double lowerBound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor for {@code Builder}, ensuring it can only be instantiated through the
|
||||||
|
* {@link QuartileBounds#builder()} method.
|
||||||
|
*/
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the upper bound for the {@code QuartileBounds}.
|
||||||
|
*
|
||||||
|
* @param upperBound the upper bound of the dataset
|
||||||
|
* @return the current {@code Builder} instance, for method chaining
|
||||||
|
*/
|
||||||
|
public Builder upperBound(Double upperBound) {
|
||||||
|
this.upperBound = upperBound;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the lower bound for the {@code QuartileBounds}.
|
||||||
|
*
|
||||||
|
* @param lowerBound the lower bound of the dataset
|
||||||
|
* @return the current {@code Builder} instance, for method chaining
|
||||||
|
*/
|
||||||
|
public Builder lowerBound(Double lowerBound) {
|
||||||
|
this.lowerBound = lowerBound;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and returns a new {@code QuartileBounds} instance with the specified upper and lower bounds.
|
||||||
|
*
|
||||||
|
* @return a new {@code QuartileBounds} object containing the specified bounds
|
||||||
|
*/
|
||||||
|
public QuartileBounds build() {
|
||||||
|
return new QuartileBounds(upperBound, lowerBound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -28,3 +28,4 @@ include(
|
|||||||
"simple-jwt-spring-boot-starter",
|
"simple-jwt-spring-boot-starter",
|
||||||
"property-guard-spring-boot-starter"
|
"property-guard-spring-boot-starter"
|
||||||
)
|
)
|
||||||
|
include("num4j")
|
||||||
|
|||||||
Reference in New Issue
Block a user