diff --git a/pom.xml b/pom.xml index 2b3b1b7..66f96a1 100644 --- a/pom.xml +++ b/pom.xml @@ -69,12 +69,24 @@ com.zaxxer HikariCP 4.0.3 + + + org.slf4j + slf4j-api + + test org.postgresql postgresql 42.3.8 + + + org.checkerframework + checker-qual + + test diff --git a/src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java b/src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java index 6330673..aa99322 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/collection/MapWrapper.java @@ -49,7 +49,7 @@ public final class MapWrapper extends AbstractMapWrapper(new HashMap<>(initialCapacity, loadFactor)); } - public static Builder wrapTreeMap() { + public static , V> Builder wrapTreeMap() { return new Builder<>(new TreeMap<>()); } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/function/Predicates.java b/src/main/java/xyz/zhouxy/plusone/commons/function/Predicates.java index e1620f4..adb4989 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/function/Predicates.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/function/Predicates.java @@ -42,9 +42,9 @@ public class Predicates { * .and(StringUtils::isNotEmpty); * * - * @param - * @param predicate - * @return + * @param 目标类型 + * @param predicate 原 {@link Predicate} 实例 + * @return 包装的 {@link Predicate} 实例 */ public static Predicate of(Predicate predicate) { return predicate::test; diff --git a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java index e8c1892..472c00d 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/DbRecord.java @@ -59,7 +59,7 @@ public class DbRecord extends AbstractMapWrapper { public Set getValueAsSet(String key) { return this.>getAndConvert(key) .map(l -> (l instanceof Set) ? (Set) l : new HashSet<>(l)) - .orElse(Collections.emptySet()); + .orElse(Collections.emptySet()); } public OptionalInt getValueAsInt(String key) { diff --git a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/ResultMap.java b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/ResultMap.java index de89740..1f078c8 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/ResultMap.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/ResultMap.java @@ -24,5 +24,5 @@ import com.google.common.annotations.Beta; @Beta @FunctionalInterface public interface ResultMap { - T map(ResultSet rs) throws SQLException; + T map(ResultSet rs, int rowNumber) throws SQLException; } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java index e0bab36..0600529 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/jdbc/SimpleJdbcTemplate.java @@ -100,8 +100,9 @@ public class SimpleJdbcTemplate { } try (ResultSet rs = stmt.executeQuery()) { List result = new ArrayList<>(); + int rowNumber = 0; while (rs.next()) { - T e = resultMap.map(rs); + T e = resultMap.map(rs, rowNumber++); result.add(e); } return result; @@ -114,7 +115,7 @@ public class SimpleJdbcTemplate { return (list.isEmpty()) ? Optional.empty() : Optional.ofNullable(list.get(0)); } - public static final ResultMap> mapResultMap = rs -> { + public static final ResultMap> mapResultMap = (rs, rowNumber) -> { Map result = new HashMap<>(); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); @@ -133,7 +134,7 @@ public class SimpleJdbcTemplate { return queryFirst(sql, params, mapResultMap); } - public static final ResultMap recordResultMap = rs -> { + public static final ResultMap recordResultMap = (rs, rowNumber) -> { DbRecord result = new DbRecord(); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); @@ -153,26 +154,26 @@ public class SimpleJdbcTemplate { } public Optional queryToString(String sql, Object... params) throws SQLException { - return queryFirst(sql, params, (ResultSet rs) -> rs.getString(1)); + return queryFirst(sql, params, (ResultSet rs, int rowNumber) -> rs.getString(1)); } public OptionalInt queryToInt(String sql, Object... params) throws SQLException { - Optional result = queryFirst(sql, params, (ResultSet rs) -> rs.getInt(1)); + Optional result = queryFirst(sql, params, (ResultSet rs, int rowNumber) -> rs.getInt(1)); return OptionalUtil.toOptionalInt(result); } public OptionalLong queryToLong(String sql, Object... params) throws SQLException { - Optional result = queryFirst(sql, params, (ResultSet rs) -> rs.getLong(1)); + Optional result = queryFirst(sql, params, (ResultSet rs, int rowNumber) -> rs.getLong(1)); return OptionalUtil.toOptionalLong(result); } public OptionalDouble queryToDouble(String sql, Object... params) throws SQLException { - Optional result = queryFirst(sql, params, (ResultSet rs) -> rs.getDouble(1)); + Optional result = queryFirst(sql, params, (ResultSet rs, int rowNumber) -> rs.getDouble(1)); return OptionalUtil.toOptionalDouble(result); } public Optional queryToBigDecimal(String sql, Object... params) throws SQLException { - return queryFirst(sql, params, (ResultSet rs) -> rs.getBigDecimal(1)); + return queryFirst(sql, params, (ResultSet rs, int rowNumber) -> rs.getBigDecimal(1)); } public int update(String sql, Object... params) throws SQLException { @@ -224,7 +225,7 @@ public class SimpleJdbcTemplate { } @FunctionalInterface - public static interface IAtom { + public interface IAtom { @SuppressWarnings("all") void execute() throws SQLException, T; } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeUtil.java b/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeUtil.java index 51099c0..2fcfcfc 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeUtil.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeUtil.java @@ -9,33 +9,22 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; -import java.util.Objects; import java.util.TimeZone; -import org.apache.commons.lang3.StringUtils; +import xyz.zhouxy.plusone.commons.collection.SafeConcurrentHashMap; import xyz.zhouxy.plusone.commons.collection.MapWrapper; public class DateTimeUtil { - private static final MapWrapper DATE_TIME_FORMATTER_CHCHE = MapWrapper - .wrapHashMap() - .keyChecker(StringUtils::isNotBlank) - .valueChecker(Objects::nonNull) + private static final MapWrapper DATE_TIME_FORMATTER_CACHE = MapWrapper + .wrap(new SafeConcurrentHashMap<>()) + .keyChecker(pattern -> Assert.isNotBlank(pattern, "The pattern could not be blank.")) + .valueChecker(formatter -> Assert.notNull(formatter, "The formatter could not be null.")) .build(); public static DateTimeFormatter getDateTimeFormatter(String pattern) { - if (!DATE_TIME_FORMATTER_CHCHE.containsKey(pattern)) { - synchronized (DateTimeUtil.class) { - if (!DATE_TIME_FORMATTER_CHCHE.containsKey(pattern)) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern); - DATE_TIME_FORMATTER_CHCHE.put(pattern, formatter); - return formatter; - } - } - } - return DATE_TIME_FORMATTER_CHCHE.get(pattern) - .orElseThrow(() -> new IllegalStateException("Formatter does not exist.")); + return DATE_TIME_FORMATTER_CACHE.computeIfAbsent(pattern, DateTimeFormatter::ofPattern); } public static String toString(String pattern, ZonedDateTime dateTime) { @@ -126,7 +115,7 @@ public class DateTimeUtil { * 只是不同时区的表示。 *

* - * @param dateTime {@link Date} 对象 + * @param timeMillis 时间戳 * @param zone 时区 * @return 带时区信息的地区时间 */ @@ -191,7 +180,7 @@ public class DateTimeUtil { /** * 获取时间戳在指定时区的地区时间。 * - * @param dateTime {@link Date} 对象 + * @param timeMillis 时间戳 * @param zone 时区 * @return 地区时间 */ diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/MoreCollections.java b/src/main/java/xyz/zhouxy/plusone/commons/util/MoreCollections.java index 5ad4142..1efca6a 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/MoreCollections.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/MoreCollections.java @@ -60,7 +60,7 @@ public class MoreCollections { return toConcurrentHashMap(c, keyGenerator, c.size()); } - public static TreeMap toTreeMap(Iterable c, Function keyGenerator) { + public static , V> TreeMap toTreeMap(Iterable c, Function keyGenerator) { TreeMap map = new TreeMap<>(); fillIntoEmptyMap(map, c, keyGenerator); return map; @@ -106,7 +106,7 @@ public class MoreCollections { return toConcurrentHashMap(c, keyGenerator, c.length); } - public static TreeMap toTreeMap(V[] c, Function keyGenerator) { + public static , V> TreeMap toTreeMap(V[] c, Function keyGenerator) { TreeMap map = new TreeMap<>(); fillIntoEmptyMap(map, c, keyGenerator); return map; diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java b/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java index 4c852fa..1127ced 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/OptionalUtil.java @@ -55,16 +55,16 @@ public class OptionalUtil { } /** - * 将 {@code Optional} 转为 {@link OptionalInt}。 + * 将 {@code Optional} 对象转为 {@link OptionalInt} 对象。 *

* {@code Optional} 将整数包装了两次,改为使用 {@link OptionalInt} 包装其中的整数数据。 *

* - * @param value 包装对象 + * @param optionalObj {@code Optional} 对象 * @return {@link OptionalInt} 实例 */ - public static OptionalInt toOptionalInt(Optional objectOptional) { - return optionalOf(objectOptional.orElse(null)); + public static OptionalInt toOptionalInt(Optional optionalObj) { + return optionalOf(optionalObj.orElse(null)); } /** @@ -87,11 +87,11 @@ public class OptionalUtil { * {@code Optional} 将整数包装了两次,改为使用 {@link OptionalLong} 包装其中的整数数据。 *

* - * @param value 包装对象 + * @param optionalObj 包装对象 * @return {@link OptionalLong} 实例 */ - public static OptionalLong toOptionalLong(Optional objectOptional) { - return optionalOf(objectOptional.orElse(null)); + public static OptionalLong toOptionalLong(Optional optionalObj) { + return optionalOf(optionalObj.orElse(null)); } /** @@ -114,11 +114,11 @@ public class OptionalUtil { * {@code Optional} 将整数包装了两次,改为使用 {@link OptionalDouble} 包装其中的整数数据。 *

* - * @param value 包装对象 + * @param optionalObj 包装对象 * @return {@link OptionalDouble} 实例 */ - public static OptionalDouble toOptionalDouble(Optional objectOptional) { - return optionalOf(objectOptional.orElse(null)); + public static OptionalDouble toOptionalDouble(Optional optionalObj) { + return optionalOf(optionalObj.orElse(null)); } /** diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java b/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java index b34bea2..3f4a88b 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/PagingAndSortingQueryParams.java @@ -51,10 +51,11 @@ public class PagingAndSortingQueryParams { } public PagingAndSortingQueryParams(String... sortableColNames) { + Set sortableColNameSet = new HashSet<>(sortableColNames.length); for (String colName : sortableColNames) { Assert.isNotBlank(colName, "Column name must has text."); + sortableColNameSet.add(colName); } - Set sortableColNameSet = new HashSet<>(sortableColNames.length); this.sortableColNames = Collections.unmodifiableSet(sortableColNameSet); } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java b/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java index 4e410b2..810eee7 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java @@ -42,10 +42,10 @@ public class SnowflakeIdGenerator { private static final long SEQUENCE_MASK = -1L ^ (-1L << SEQUENCE_BITS); /** 工作机器 ID (0~31) */ - private long workerId; + private final long workerId; /** 数据中心 ID (0~31) */ - private long datacenterId; + private final long datacenterId; /** 毫秒内序列 (0~4095) */ private long sequence = 0L; @@ -78,7 +78,6 @@ public class SnowflakeIdGenerator { * 获得下一个ID (该方法是线程安全的) * * @return SnowflakeId - * @throws InterruptedException */ public synchronized long nextId() { long timestamp = timeGen(); diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java index 247cd4b..e8822e0 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/SimpleJdbcTemplateTests.java @@ -28,7 +28,7 @@ class SimpleJdbcTemplateTests { private static final Logger log = LoggerFactory.getLogger(SimpleJdbcTemplateTests.class); - DataSource dataSource; + final DataSource dataSource; String[] cStruct = { "id", diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java index 446ec35..dd2c063 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/TreeBuilderTests.java @@ -31,7 +31,7 @@ class TreeBuilderTests { MenuItem.of("C", "C2", "二级菜单C2", "/c/c2"), MenuItem.of("C", "C3", "二级菜单C3", "/c/c3") ); - List menuTree = new TreeBuilder( + List menuTree = new TreeBuilder<>( menus, Menu::getMenuCode, Menu::getParentMenuCode,