From 7d1438b6655dd9b216430de95cf949c42655b386 Mon Sep 17 00:00:00 2001 From: Looly Date: Sat, 21 Dec 2024 11:30:02 +0800 Subject: [PATCH] fix code --- .../hutool/core/cache/impl/FIFOCache.java | 4 +- .../hutool/core/cache/impl/StampedCache.java | 3 +- .../hutool/core/collection/CollUtil.java | 182 +++++++++--------- .../hutool/core/collection/iter/IterUtil.java | 19 ++ .../org/dromara/hutool/core/map/MapUtil.java | 21 ++ 5 files changed, 139 insertions(+), 90 deletions(-) diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java index 487e91908..888d5e297 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/FIFOCache.java @@ -28,11 +28,13 @@ import java.util.LinkedHashMap; * 缺点:不灵活,不能保证最常用的对象总是被保留 *

* + *

由于使用LinkedHashMap,并发读也有问题,因此只能使用悲观锁,不能使用读写锁

+ * * @param 键类型 * @param 值类型 * @author Looly */ -public class FIFOCache extends StampedCache { +public class FIFOCache extends ReentrantCache { private static final long serialVersionUID = 1L; /** diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java index 015aa44d7..83a67dc94 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/cache/impl/StampedCache.java @@ -22,7 +22,8 @@ import java.util.Iterator; import java.util.concurrent.locks.StampedLock; /** - * 使用{@link StampedLock}保护的缓存,使用读写乐观锁 + * 使用{@link StampedLock}保护的缓存,使用读写乐观锁
+ * 使用乐观锁有效的提高的缓存性能,但是无法避免脏读问题 * * @param 键类型 * @param 值类型 diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java index 3631d5f53..a2ad0551d 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java @@ -64,7 +64,7 @@ import java.util.stream.Collectors; */ public class CollUtil { - // ---------------------------------------------------------------------- isEmpty + // region ----- isEmpty /** * 集合是否为空 @@ -174,8 +174,9 @@ public class CollUtil { public static List emptyIfNull(final List list) { return ObjUtil.defaultIfNull(list, Collections.emptyList()); } + // endregion - // ---------------------------------------------------------------------- isNotEmpty + // region ----- isNotEmpty /** * 集合是否为非空 @@ -247,6 +248,7 @@ public class CollUtil { public static boolean isNotEmpty(final Map map) { return MapUtil.isNotEmpty(map); } + // endregion /** * 去重集合 @@ -578,6 +580,7 @@ public class CollUtil { return IterUtil.countMap(IterUtil.getIter(collection)); } + // region ----- join /** * 以 conjunction 为分隔符将集合转换为字符串 * @@ -627,6 +630,7 @@ public class CollUtil { } return IterUtil.join(iterable.iterator(), conjunction, prefix, suffix); } + // endregion /** * 切取部分数据
@@ -807,6 +811,7 @@ public class CollUtil { return list; } + // region ----- sub /** * 截取列表的部分 * @@ -869,6 +874,7 @@ public class CollUtil { final List list = collection instanceof List ? (List) collection : ListUtil.of(collection); return sub(list, start, end, step); } + // endregion /** * 对集合按照指定长度分段,每一个段为单独的集合,返回这个集合的列表 @@ -955,6 +961,7 @@ public class CollUtil { return edit(collection, t -> predicate.test(t) ? t : null); } + // region ----- remove /** * 去掉集合中的多个元素,此方法直接修改原集合 * @@ -1074,6 +1081,7 @@ public class CollUtil { removeWithAddIf(targetCollection, removed, predicate); return removed; } + // endregion /** * 通过func自定义一个规则,此规则将原集合中的元素转换成新的元素,生成新的列表返回
@@ -1117,6 +1125,7 @@ public class CollUtil { return StreamUtil.of(collection).map(mapper).collect(Collectors.toList()); } + // region ----- getFieldValues /** * 获取给定Bean列表中指定字段名对应字段值的列表
* 列表元素支持Bean与Map @@ -1165,6 +1174,7 @@ public class CollUtil { final Collection fieldValues = getFieldValues(collection, fieldName); return ConvertUtil.toList(elementType, fieldValues); } + // endregion /** * 字段值与列表值对应的Map,常用于元素对象中有唯一ID时需要按照这个ID查找对象的情况
@@ -1196,73 +1206,6 @@ public class CollUtil { return IterUtil.fieldValueAsMap(IterUtil.getIter(iterable), fieldNameForKey, fieldNameForValue); } - /** - * 获取集合的第一个元素,如果集合为空(null或者空集合),返回{@code null} - * - * @param 集合元素类型 - * @param iterable {@link Iterable} - * @return 第一个元素,为空返回{@code null} - */ - public static T getFirst(final Iterable iterable) { - if (iterable instanceof List) { - final List list = (List) iterable; - return CollUtil.isEmpty(list) ? null : list.get(0); - } - return IterUtil.getFirst(IterUtil.getIter(iterable)); - } - - /** - * 获取集合的第一个非空元素 - * - * @param 集合元素类型 - * @param iterable {@link Iterable} - * @return 第一个元素 - * @since 5.7.2 - */ - public static T getFirstNoneNull(final Iterable iterable) { - return IterUtil.getFirstNoneNull(IterUtil.getIter(iterable)); - } - - /** - * 查找第一个匹配元素对象 - * - * @param 集合元素类型 - * @param collection 集合 - * @param predicate 过滤器,满足过滤条件的第一个元素将被返回 - * @return 满足过滤条件的第一个元素 - * @since 3.1.0 - */ - public static T getFirst(final Iterable collection, final Predicate predicate) { - return IterUtil.getFirst(IterUtil.getIter(collection), predicate); - } - - /** - * 查找第一个匹配元素对象
- * 如果集合元素是Map,则比对键和值是否相同,相同则返回
- * 如果为普通Bean,则通过反射比对元素字段名对应的字段值是否相同,相同则返回
- * 如果给定字段值参数是{@code null} 且元素对象中的字段值也为{@code null}则认为相同 - * - * @param 集合元素类型 - * @param collection 集合,集合元素可以是Bean或者Map - * @param fieldName 集合元素对象的字段名或map的键 - * @param fieldValue 集合元素对象的字段值或map的值 - * @return 满足条件的第一个元素 - * @since 3.1.0 - */ - public static T getFirstByField(final Iterable collection, final String fieldName, final Object fieldValue) { - return getFirst(collection, t -> { - if (t instanceof Map) { - final Map map = (Map) t; - final Object value = map.get(fieldName); - return ObjUtil.equals(value, fieldValue); - } - - // 普通Bean - final Object value = FieldUtil.getFieldValue(t, fieldName); - return ObjUtil.equals(value, fieldValue); - }); - } - /** * 集合中匹配规则的数量 * @@ -1372,7 +1315,7 @@ public class CollUtil { return indexList; } - // ---------------------------------------------------------------------- zip + // region ----- zip /** * 映射键值(参考Python的zip()函数)
@@ -1441,6 +1384,7 @@ public class CollUtil { return map; } + // endregion /** * 将集合转换为排序后的TreeSet @@ -1551,6 +1495,7 @@ public class CollUtil { return MapUtil.toMapList(listMap); } + // region ----- addAll /** * 将指定对象全部加入到集合中
* 提供的对象如果为集合类型,会自动转换为目标元素类型
@@ -1687,6 +1632,75 @@ public class CollUtil { } return collection; } + // endregion + + // region ----- get + /** + * 获取集合的第一个元素,如果集合为空(null或者空集合),返回{@code null} + * + * @param 集合元素类型 + * @param iterable {@link Iterable} + * @return 第一个元素,为空返回{@code null} + */ + public static T getFirst(final Iterable iterable) { + if (iterable instanceof List) { + final List list = (List) iterable; + return CollUtil.isEmpty(list) ? null : list.get(0); + } + return IterUtil.getFirst(IterUtil.getIter(iterable)); + } + + /** + * 获取集合的第一个非空元素 + * + * @param 集合元素类型 + * @param iterable {@link Iterable} + * @return 第一个元素 + * @since 5.7.2 + */ + public static T getFirstNoneNull(final Iterable iterable) { + return IterUtil.getFirstNoneNull(IterUtil.getIter(iterable)); + } + + /** + * 查找第一个匹配元素对象 + * + * @param 集合元素类型 + * @param collection 集合 + * @param predicate 过滤器,满足过滤条件的第一个元素将被返回 + * @return 满足过滤条件的第一个元素 + * @since 3.1.0 + */ + public static T getFirst(final Iterable collection, final Predicate predicate) { + return IterUtil.getFirst(IterUtil.getIter(collection), predicate); + } + + /** + * 查找第一个匹配元素对象
+ * 如果集合元素是Map,则比对键和值是否相同,相同则返回
+ * 如果为普通Bean,则通过反射比对元素字段名对应的字段值是否相同,相同则返回
+ * 如果给定字段值参数是{@code null} 且元素对象中的字段值也为{@code null}则认为相同 + * + * @param 集合元素类型 + * @param collection 集合,集合元素可以是Bean或者Map + * @param fieldName 集合元素对象的字段名或map的键 + * @param fieldValue 集合元素对象的字段值或map的值 + * @return 满足条件的第一个元素 + * @since 3.1.0 + */ + public static T getFirstByField(final Iterable collection, final String fieldName, final Object fieldValue) { + return getFirst(collection, t -> { + if (t instanceof Map) { + final Map map = (Map) t; + final Object value = map.get(fieldName); + return ObjUtil.equals(value, fieldValue); + } + + // 普通Bean + final Object value = FieldUtil.getFieldValue(t, fieldName); + return ObjUtil.equals(value, fieldValue); + }); + } /** * 获取集合的最后一个元素 @@ -1771,8 +1785,9 @@ public class CollUtil { } return result; } + // endregion - // ------------------------------------------------------------------------------------------------- sort + // region ----- sort /** * 将多个集合排序并显示不同的段落(分页)
@@ -1947,8 +1962,9 @@ public class CollUtil { }); return list; } + // endregion - // ------------------------------------------------------------------------------------------------- forEach + // region ----- forEach /** * 循环遍历 {@link Iterable},使用{@link SerBiConsumer} 接受遍历的每条数据,并针对每条数据做处理 @@ -1973,14 +1989,7 @@ public class CollUtil { * @param consumer {@link SerBiConsumer} 遍历的每条数据处理器 */ public static void forEach(final Iterator iterator, final SerBiConsumer consumer) { - if (iterator == null) { - return; - } - int index = 0; - while (iterator.hasNext()) { - consumer.accept(index, iterator.next()); - index++; - } + IterUtil.forEach(iterator, consumer); } /** @@ -2009,18 +2018,14 @@ public class CollUtil { * @param Value类型 * @param map {@link Map} * @param kvConsumer {@link SerConsumer3} 遍历的每条数据处理器 + * @see MapUtil#forEach(Map, SerConsumer3) */ public static void forEach(final Map map, final SerConsumer3 kvConsumer) { - if (map == null) { - return; - } - int index = 0; - for (final Entry entry : map.entrySet()) { - kvConsumer.accept(index, entry.getKey(), entry.getValue()); - index++; - } + MapUtil.forEach(map, kvConsumer); } + // endregion + // region ----- group /** * 分组,按照{@link Hash32}接口定义的hash算法,集合中的元素放入hash值对应的子列表中 * @@ -2104,6 +2109,7 @@ public class CollUtil { } }); } + // endregion /** * 获取指定Map列表中所有的Key diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/collection/iter/IterUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/collection/iter/IterUtil.java index a5d24346c..4d28d30d6 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/collection/iter/IterUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/collection/iter/IterUtil.java @@ -20,6 +20,7 @@ import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.convert.ConvertUtil; +import org.dromara.hutool.core.func.SerBiConsumer; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.math.NumberUtil; @@ -902,6 +903,24 @@ public class IterUtil { } } + /** + * 循环遍历 {@link Iterator},使用{@link SerBiConsumer} 接受遍历的每条数据,并针对每条数据做处理,支持index + * + * @param 集合元素类型 + * @param iterator {@link Iterator} + * @param consumer {@link SerBiConsumer} 遍历的每条数据处理器 + */ + public static void forEach(final Iterator iterator, final SerBiConsumer consumer) { + if (iterator == null) { + return; + } + int index = 0; + while (iterator.hasNext()) { + consumer.accept(index, iterator.next()); + index++; + } + } + /** * 拼接 {@link Iterator}为字符串 * diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/map/MapUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/map/MapUtil.java index 24792954d..49240e7d1 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/map/MapUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/map/MapUtil.java @@ -21,6 +21,7 @@ import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.collection.iter.ArrayIter; import org.dromara.hutool.core.collection.iter.IterUtil; +import org.dromara.hutool.core.func.SerConsumer3; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.map.concurrent.SafeConcurrentHashMap; import org.dromara.hutool.core.reflect.ConstructorUtil; @@ -1447,4 +1448,24 @@ public class MapUtil extends MapGetUtil { } return null; } + + /** + * 循环遍历Map,使用{@link SerConsumer3} 接受遍历的每条数据,并针对每条数据做处理
+ * 和JDK8中的map.forEach不同的是,此方法支持index + * + * @param Key类型 + * @param Value类型 + * @param map {@link Map} + * @param kvConsumer {@link SerConsumer3} 遍历的每条数据处理器 + */ + public static void forEach(final Map map, final SerConsumer3 kvConsumer) { + if (map == null) { + return; + } + int index = 0; + for (final Entry entry : map.entrySet()) { + kvConsumer.accept(index, entry.getKey(), entry.getValue()); + index++; + } + } }