This commit is contained in:
Looly 2023-04-15 23:07:59 +08:00
parent 9781d5eb9f
commit 656c551068
13 changed files with 400 additions and 392 deletions

View File

@ -100,6 +100,89 @@ public class ArrayUtil extends PrimitiveArrayUtil {
public static <T> T[] ofArray(final Iterable<T> iterable, final Class<T> componentType) {
return ofArray(IterUtil.getIter(iterable), componentType);
}
// ---------------------------------------------------------------------- isBlank
/**
* <p>指定字符串数组中是否包含空字符串</p>
* <p>如果指定的字符串数组的长度为 0或者其中的任意一个元素是空字符串则返回 true</p>
* <br>
*
* <p></p>
* <ul>
* <li>{@code hasBlank() // true}</li>
* <li>{@code hasBlank("", null, " ") // true}</li>
* <li>{@code hasBlank("123", " ") // true}</li>
* <li>{@code hasBlank("123", "abc") // false}</li>
* </ul>
*
* <p>注意该方法与 {@link #isAllBlank(CharSequence...)} 的区别在于</p>
* <ul>
* <li>hasBlank(CharSequence...) 等价于 {@code isBlank(...) || isBlank(...) || ...}</li>
* <li>{@link #isAllBlank(CharSequence...)} 等价于 {@code isBlank(...) && isBlank(...) && ...}</li>
* </ul>
*
* @param strs 字符串列表
* @return 是否包含空字符串
*/
public static boolean hasBlank(final CharSequence... strs) {
if (ArrayUtil.isEmpty(strs)) {
return true;
}
for (final CharSequence str : strs) {
if (StrUtil.isBlank(str)) {
return true;
}
}
return false;
}
/**
* 是否存都不为{@code null}或空对象或空白符的对象通过{@link #hasBlank(CharSequence...)} 判断元素
*
* @param args 被检查的对象,一个或者多个
* @return 是否都不为空
*/
public static boolean isAllNotBlank(final CharSequence... args) {
return !hasBlank(args);
}
/**
* <p>指定字符串数组中的元素是否全部为空字符串</p>
* <p>如果指定的字符串数组的长度为 0或者所有元素都是空字符串则返回 true</p>
* <br>
*
* <p></p>
* <ul>
* <li>{@code isAllBlank() // true}</li>
* <li>{@code isAllBlank("", null, " ") // true}</li>
* <li>{@code isAllBlank("123", " ") // false}</li>
* <li>{@code isAllBlank("123", "abc") // false}</li>
* </ul>
*
* <p>注意该方法与 {@link #hasBlank(CharSequence...)} 的区别在于</p>
* <ul>
* <li>{@link #hasBlank(CharSequence...)} 等价于 {@code isBlank(...) || isBlank(...) || ...}</li>
* <li>isAllBlank(CharSequence...) 等价于 {@code isBlank(...) && isBlank(...) && ...}</li>
* </ul>
*
* @param strs 字符串列表
* @return 所有字符串是否为空白
*/
public static boolean isAllBlank(final CharSequence... strs) {
if (ArrayUtil.isEmpty(strs)) {
return true;
}
for (final CharSequence str : strs) {
if (StrUtil.isNotBlank(str)) {
return false;
}
}
return true;
}
// ---------------------------------------------------------------------- isEmpty
/**

View File

@ -12,13 +12,15 @@
package org.dromara.hutool.core.collection.iter;
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.lang.Assert;
import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.core.reflect.FieldUtil;
import org.dromara.hutool.core.reflect.MethodUtil;
import org.dromara.hutool.core.text.StrJoiner;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ObjUtil;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@ -135,6 +137,41 @@ public class IterUtil {
return null == getFirstNoneNull(iter);
}
/**
* 指定字符串集合中是否包含空字符串
*
* @param strs 字符串列表
* @return 批量判断字符串是否全部为空白
* @since 6.0.0
*/
public static boolean hasBlank(final Iterable<? extends CharSequence> strs) {
if (CollUtil.isEmpty(strs)) {
return true;
}
for (final CharSequence str : strs) {
if (StrUtil.isBlank(str)) {
return true;
}
}
return false;
}
/**
* @param strs 字符串列表
* @return 批量判断字符串是否全部为空白
* @since 6.0.1
*/
public static boolean isAllBlank(final Iterable<? extends CharSequence> strs) {
if (CollUtil.isNotEmpty(strs)) {
for (final CharSequence str : strs) {
if (StrUtil.isNotBlank(str)) {
return false;
}
}
}
return true;
}
/**
* 根据集合返回一个元素计数的 {@link Map}<br>
* 所谓元素计数就是假如这个集合中某个元素出现了n次那将这个元素做为keyn做为value<br>
@ -187,8 +224,8 @@ public class IterUtil {
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> fieldValueAsMap(final Iterator<?> iter, final String fieldNameForKey, final String fieldNameForValue) {
return MapUtil.putAll(new HashMap<>(), iter,
(value) -> (K) FieldUtil.getFieldValue(value, fieldNameForKey),
(value) -> (V) FieldUtil.getFieldValue(value, fieldNameForValue)
(value) -> (K) FieldUtil.getFieldValue(value, fieldNameForKey),
(value) -> (V) FieldUtil.getFieldValue(value, fieldNameForValue)
);
}
@ -256,10 +293,10 @@ public class IterUtil {
*/
public static <T> String join(final Iterator<T> iterator, final CharSequence conjunction, final String prefix, final String suffix) {
return StrJoiner.of(conjunction, prefix, suffix)
// 每个元素都添加前后缀
.setWrapElement(true)
.append(iterator)
.toString();
// 每个元素都添加前后缀
.setWrapElement(true)
.append(iterator)
.toString();
}
/**

View File

@ -12,6 +12,7 @@
package org.dromara.hutool.core.convert;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.classloader.ClassLoaderUtil;
import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.core.convert.impl.CollectionConverter;
@ -946,7 +947,7 @@ public class Convert {
* @see CharsetUtil#convert(String, String, String)
*/
public static String convertCharset(final String str, final String sourceCharset, final String destCharset) {
if (StrUtil.hasBlank(str, sourceCharset, destCharset)) {
if (ArrayUtil.hasBlank(str, sourceCharset, destCharset)) {
return str;
}

View File

@ -12,6 +12,7 @@
package org.dromara.hutool.core.regex;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.collection.set.SetUtil;
import org.dromara.hutool.core.comparator.CompareUtil;
import org.dromara.hutool.core.comparator.StrLengthComparator;
@ -376,7 +377,7 @@ public class ReUtil {
* @return 删除后剩余的内容
*/
public static String delFirst(final String regex, final CharSequence content) {
if (StrUtil.hasBlank(regex, content)) {
if (ArrayUtil.hasBlank(regex, content)) {
return StrUtil.str(content);
}
@ -421,7 +422,7 @@ public class ReUtil {
* @since 5.6.5
*/
public static String delLast(final String regex, final CharSequence str) {
if (StrUtil.hasBlank(regex, str)) {
if (ArrayUtil.hasBlank(regex, str)) {
return StrUtil.str(str);
}

View File

@ -17,7 +17,7 @@ import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.resource.MultiResource;
import org.dromara.hutool.core.io.resource.Resource;
import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.util.CharUtil;
import org.dromara.hutool.core.text.StrUtil;
import java.io.BufferedReader;
import java.io.IOException;
@ -99,6 +99,7 @@ public class ListServiceLoader<S> extends AbsServiceLoader<S> {
@Override
public void load() {
// 解析同名的所有service资源
final MultiResource resources = ResourceUtil.getResources(
pathPrefix + serviceClass.getName(),
this.classLoader);
@ -112,43 +113,72 @@ public class ListServiceLoader<S> extends AbsServiceLoader<S> {
return this.serviceNames.size();
}
private void parse(final Resource resource){
try(final BufferedReader reader = resource.getReader(this.charset)){
/**
* 解析一个资源一个资源对应一个service文件
*
* @param resource 资源
*/
private void parse(final Resource resource) {
try (final BufferedReader reader = resource.getReader(this.charset)) {
int lc = 1;
while(lc >= 0){
lc = parseLine(resource, reader, lc, this.serviceNames);
while (lc >= 0) {
lc = parseLine(resource, reader, lc);
}
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
private int parseLine(final Resource resource, final BufferedReader r, final int lc,
final List<String> names)
/**
* 解析一行
*
* @param resource 资源
* @param reader {@link BufferedReader}
* @param lineNo 行号
* @return 下一个行号-1表示读取完毕
* @throws IOException IO异常
*/
private int parseLine(final Resource resource, final BufferedReader reader, final int lineNo)
throws IOException {
String ln = r.readLine();
if (ln == null) {
String line = reader.readLine();
if (line == null) {
// 结束
return -1;
}
final int ci = ln.indexOf('#');
if (ci >= 0) ln = ln.substring(0, ci);
ln = ln.trim();
final int n = ln.length();
if (n != 0) {
if ((ln.indexOf(CharUtil.SPACE) >= 0) || (ln.indexOf(CharUtil.TAB) >= 0))
fail(resource, lc, "Illegal configuration-file syntax");
int cp = ln.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp))
fail(resource, lc, "Illegal provider-class name: " + ln);
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
cp = ln.codePointAt(i);
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
fail(resource, lc, "Illegal provider-class name: " + ln);
}
if (!serviceCache.containsKey(ln) && !names.contains(ln))
names.add(ln);
final int ci = line.indexOf('#');
if (ci >= 0) {
// 截取去除注释部分
// 当注释单独成行则此行长度为0跳过读取下一行
line = line.substring(0, ci);
}
line = StrUtil.trim(line);
if (line.length() > 0) {
// 检查行
checkLine(resource, lineNo, line);
// 不覆盖模式
final List<String> names = this.serviceNames;
if (!serviceCache.containsKey(line) && !names.contains(line)) {
names.add(line);
}
}
return lineNo + 1;
}
private void checkLine(final Resource resource, final int lineNo, final String line) {
if (StrUtil.containsBlank(line)) {
fail(resource, lineNo, "Illegal configuration-file syntax");
}
int cp = line.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp)) {
fail(resource, lineNo, "Illegal provider-class name: " + line);
}
final int n = line.length();
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
cp = line.codePointAt(i);
if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
fail(resource, lineNo, "Illegal provider-class name: " + line);
}
}
return lc + 1;
}
private void fail(final Resource resource, final int line, final String msg) {

View File

@ -44,7 +44,31 @@ import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* {@link CharSequence} 相关工具类封装
* {@link CharSequence} 相关工具类封装包括但不限于
* <ul>
* <li>字符串补充前缀或后缀addXXX</li>
* <li>字符串补充长度padXXX</li>
* <li>字符串包含关系containsXXX</li>
* <li>字符串默认值defaultIfXXX</li>
* <li>字符串查找indexOf</li>
* <li>字符串判断以什么结尾endWith</li>
* <li>字符串判断以什么开始startWith</li>
* <li>字符串匹配equals</li>
* <li>字符串格式化format</li>
* <li>字符串去除removeXXX</li>
* <li>字符串重复repeat</li>
* <li>获取子串sub</li>
* <li>去除两边的指定字符串只去除一次strip</li>
* <li>去除两边的指定所有字符trim</li>
* <li>去除两边的指定所有字符包装和去除包装wrap</li>
* </ul>
*
* 需要注意的是striptrimwrapunWrap的策略不同
* <ul>
* <li>strip 强调去除两边或某一边的指定字符串这个字符串不会重复去除如果一边不存在另一边不影响去除</li>
* <li>trim 强调去除两边指定字符如果这个字符有多个全部去除例如去除两边所有的空白符</li>
* <li>unWrap强调去包装要求包装的前后字符都要存在只有一个则不做处理如去掉双引号包装</li>
* </ul>
*
* @author looly
* @since 5.5.3
@ -73,6 +97,8 @@ public class CharSequenceUtil extends StrChecker {
return null == cs ? null : cs.toString();
}
// region ----- defaultIf
/**
* 当给定字符串为null时转换为Empty
*
@ -171,6 +197,7 @@ public class CharSequenceUtil extends StrChecker {
}
return handler.apply(str);
}
// endregion
// region ----- trim
@ -427,7 +454,7 @@ public class CharSequenceUtil extends StrChecker {
*/
public static boolean startWith(final CharSequence str, final CharSequence prefix, final boolean ignoreCase, final boolean ignoreEquals) {
return new StrRegionMatcher(ignoreCase, ignoreEquals, true)
.test(str, prefix);
.test(str, prefix);
}
// endregion
@ -539,7 +566,7 @@ public class CharSequenceUtil extends StrChecker {
*/
public static boolean endWith(final CharSequence str, final CharSequence suffix, final boolean ignoreCase, final boolean ignoreEquals) {
return new StrRegionMatcher(ignoreCase, ignoreEquals, false)
.test(str, suffix);
.test(str, suffix);
}
// endregion
@ -926,7 +953,7 @@ public class CharSequenceUtil extends StrChecker {
}
}
return StrFinder.of(searchStr, ignoreCase)
.setText(text).setNegative(true).start(from);
.setText(text).setNegative(true).start(from);
}
/**
@ -1198,7 +1225,8 @@ public class CharSequenceUtil extends StrChecker {
}
/**
* 去除两边的指定字符串
* 去除两边的指定字符串<br>
* 两边字符如果存在则去除不存在不做处理
*
* @param str 被处理的字符串
* @param prefix 前缀
@ -1776,8 +1804,8 @@ public class CharSequenceUtil extends StrChecker {
*/
public static String[] subBetweenAll(final CharSequence str, final CharSequence prefix, final CharSequence suffix) {
if (hasEmpty(str, prefix, suffix) ||
// 不包含起始字符串则肯定没有子串
!contains(str, prefix)) {
// 不包含起始字符串则肯定没有子串
!contains(str, prefix)) {
return new String[0];
}
@ -3492,8 +3520,8 @@ public class CharSequenceUtil extends StrChecker {
final int preLength = suffixLength + (maxLength - 3) % 2; // suffixLength suffixLength + 1
final String str2 = str.toString();
return format("{}...{}",
str2.substring(0, preLength),
str2.substring(strLength - suffixLength));
str2.substring(0, preLength),
str2.substring(strLength - suffixLength));
}
/**
@ -3558,15 +3586,15 @@ public class CharSequenceUtil extends StrChecker {
if (moveLength > 0) {
final int endAfterMove = Math.min(endExclude + moveLength, str.length());
strBuilder.append(str.subSequence(0, startInclude))//
.append(str.subSequence(endExclude, endAfterMove))//
.append(str.subSequence(startInclude, endExclude))//
.append(str.subSequence(endAfterMove, str.length()));
.append(str.subSequence(endExclude, endAfterMove))//
.append(str.subSequence(startInclude, endExclude))//
.append(str.subSequence(endAfterMove, str.length()));
} else if (moveLength < 0) {
final int startAfterMove = Math.max(startInclude + moveLength, 0);
strBuilder.append(str.subSequence(0, startAfterMove))//
.append(str.subSequence(startInclude, endExclude))//
.append(str.subSequence(startAfterMove, startInclude))//
.append(str.subSequence(endExclude, str.length()));
.append(str.subSequence(startInclude, endExclude))//
.append(str.subSequence(startAfterMove, startInclude))//
.append(str.subSequence(endExclude, str.length()));
} else {
return str(str);
}

View File

@ -61,7 +61,7 @@ public class StrChecker {
* <p>建议</p>
* <ul>
* <li>该方法建议仅对于客户端或第三方接口传入的参数使用该方法</li>
* <li>需要同时校验多个字符串时建议采用 {@link #hasBlank(CharSequence...)} {@link #isAllBlank(CharSequence...)}</li>
* <li>需要同时校验多个字符串时建议采用 {@link ArrayUtil#hasBlank(CharSequence...)} {@link ArrayUtil#isAllBlank(CharSequence...)}</li>
* </ul>
*
* @param str 被检测的字符串
@ -127,113 +127,6 @@ public class StrChecker {
return false;
}
/**
* <p>指定字符串数组中是否包含空字符串</p>
* <p>如果指定的字符串数组的长度为 0或者其中的任意一个元素是空字符串则返回 true</p>
* <br>
*
* <p></p>
* <ul>
* <li>{@code StrUtil.hasBlank() // true}</li>
* <li>{@code StrUtil.hasBlank("", null, " ") // true}</li>
* <li>{@code StrUtil.hasBlank("123", " ") // true}</li>
* <li>{@code StrUtil.hasBlank("123", "abc") // false}</li>
* </ul>
*
* <p>注意该方法与 {@link #isAllBlank(CharSequence...)} 的区别在于</p>
* <ul>
* <li>hasBlank(CharSequence...) 等价于 {@code isBlank(...) || isBlank(...) || ...}</li>
* <li>{@link #isAllBlank(CharSequence...)} 等价于 {@code isBlank(...) && isBlank(...) && ...}</li>
* </ul>
*
* @param strs 字符串列表
* @return 是否包含空字符串
*/
public static boolean hasBlank(final CharSequence... strs) {
if (ArrayUtil.isEmpty(strs)) {
return true;
}
for (final CharSequence str : strs) {
if (isBlank(str)) {
return true;
}
}
return false;
}
/**
* 指定字符串集合中是否包含空字符串
*
* @param strs 字符串列表
* @return 批量判断字符串是否全部为空白
* @see CharSequenceUtil#hasBlank(CharSequence...)
* @since 6.0.0
*/
public static boolean hasBlank(final Iterable<? extends CharSequence> strs) {
if (CollUtil.isEmpty(strs)) {
return true;
}
for (final CharSequence str : strs) {
if (isBlank(str)) {
return true;
}
}
return false;
}
/**
* <p>指定字符串数组中的元素是否全部为空字符串</p>
* <p>如果指定的字符串数组的长度为 0或者所有元素都是空字符串则返回 true</p>
* <br>
*
* <p></p>
* <ul>
* <li>{@code StrUtil.isAllBlank() // true}</li>
* <li>{@code StrUtil.isAllBlank("", null, " ") // true}</li>
* <li>{@code StrUtil.isAllBlank("123", " ") // false}</li>
* <li>{@code StrUtil.isAllBlank("123", "abc") // false}</li>
* </ul>
*
* <p>注意该方法与 {@link #hasBlank(CharSequence...)} 的区别在于</p>
* <ul>
* <li>{@link #hasBlank(CharSequence...)} 等价于 {@code isBlank(...) || isBlank(...) || ...}</li>
* <li>isAllBlank(CharSequence...) 等价于 {@code isBlank(...) && isBlank(...) && ...}</li>
* </ul>
*
* @param strs 字符串列表
* @return 所有字符串是否为空白
*/
public static boolean isAllBlank(final CharSequence... strs) {
if (ArrayUtil.isEmpty(strs)) {
return true;
}
for (final CharSequence str : strs) {
if (isNotBlank(str)) {
return false;
}
}
return true;
}
/**
* @param strs 字符串列表
* @return 批量判断字符串是否全部为空白
* @see CharSequenceUtil#isAllBlank(CharSequence...)
* @since 6.0.1
*/
public static boolean isAllBlank(final Iterable<? extends CharSequence> strs) {
if (CollUtil.isNotEmpty(strs)) {
for (final CharSequence str : strs) {
if (isNotBlank(str)) {
return false;
}
}
}
return true;
}
/**
* <p>字符串是否为空空的定义如下</p>
* <ol>
@ -429,17 +322,6 @@ public class StrChecker {
return !hasEmpty(args);
}
/**
* 是否存都不为{@code null}或空对象或空白符的对象通过{@link #hasBlank(CharSequence...)} 判断元素
*
* @param args 被检查的对象,一个或者多个
* @return 是否都不为空
* @since 5.3.6
*/
public static boolean isAllNotBlank(final CharSequence... args) {
return !hasBlank(args);
}
/**
* 检查字符串是否为nullnullundefined
*

View File

@ -22,7 +22,8 @@ import java.nio.charset.Charset;
import java.util.Map;
/**
* 字符串工具类
* 字符串工具类<br>
* 此工具主要针对单个字符串的操作
*
* @author xiaoleilu
*/

View File

@ -1,144 +0,0 @@
package org.dromara.hutool.core.collection;
import org.dromara.hutool.core.collection.iter.FilterIter;
import org.dromara.hutool.core.collection.iter.IterUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.dromara.hutool.core.collection.set.SetUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.*;
/**
* {@link IterUtil} 单元测试
*
* @author looly
*/
public class IterUtilTest {
@Test
public void getFirstNonNullTest() {
final List<String> strings = ListUtil.of(null, null, "123", "456", null);
Assertions.assertEquals("123", CollUtil.getFirstNoneNull(strings));
}
@Test
public void fieldValueMapTest() {
final List<Car> carList = ListUtil.of(new Car("123", "大众"), new Car("345", "奔驰"), new Car("567", "路虎"));
final Map<String, Car> carNameMap = IterUtil.fieldValueMap(carList.iterator(), "carNumber");
Assertions.assertEquals("大众", carNameMap.get("123").getCarName());
Assertions.assertEquals("奔驰", carNameMap.get("345").getCarName());
Assertions.assertEquals("路虎", carNameMap.get("567").getCarName());
}
@Test
public void joinTest() {
final List<String> list = ListUtil.of("1", "2", "3", "4");
final String join = IterUtil.join(list.iterator(), ":");
Assertions.assertEquals("1:2:3:4", join);
final List<Integer> list1 = ListUtil.of(1, 2, 3, 4);
final String join1 = IterUtil.join(list1.iterator(), ":");
Assertions.assertEquals("1:2:3:4", join1);
// 包装每个节点
final List<String> list2 = ListUtil.of("1", "2", "3", "4");
final String join2 = IterUtil.join(list2.iterator(), ":", "\"", "\"");
Assertions.assertEquals("\"1\":\"2\":\"3\":\"4\"", join2);
}
@Test
public void joinWithFuncTest() {
final List<String> list = ListUtil.of("1", "2", "3", "4");
final String join = IterUtil.join(list.iterator(), ":", String::valueOf);
Assertions.assertEquals("1:2:3:4", join);
}
@Test
public void joinWithNullTest() {
final List<String> list = ListUtil.of("1", null, "3", "4");
final String join = IterUtil.join(list.iterator(), ":", String::valueOf);
Assertions.assertEquals("1:null:3:4", join);
}
@Test
public void testToListMap() {
final Map<String, List<String>> expectedMap = new HashMap<>();
expectedMap.put("a", Collections.singletonList("and"));
expectedMap.put("b", Arrays.asList("brave", "back"));
final Map<String, List<String>> testMap = IterUtil.toListMap(Arrays.asList("and", "brave", "back"),
v -> v.substring(0, 1));
Assertions.assertEquals(testMap, expectedMap);
}
@Test
public void testToMap() {
final Map<String, Car> expectedMap = new HashMap<>();
final Car bmw = new Car("123", "bmw");
expectedMap.put("123", bmw);
final Car benz = new Car("456", "benz");
expectedMap.put("456", benz);
final Map<String, Car> testMap = IterUtil.toMap(Arrays.asList(bmw, benz), Car::getCarNumber);
Assertions.assertEquals(expectedMap, testMap);
}
@Test
public void getElementTypeTest() {
final List<Integer> integers = Arrays.asList(null, 1);
final Class<?> elementType = IterUtil.getElementType(integers);
Assertions.assertEquals(Integer.class, elementType);
}
@Data
@AllArgsConstructor
public static class Car {
private String carNumber;
private String carName;
}
@Test
public void removeTest() {
final List<String> obj2 = ListUtil.of("3");
final List<String> obj = ListUtil.of("1", "3");
IterUtil.remove(obj.iterator(), (e)-> !obj2.contains(e));
Assertions.assertEquals(1, obj.size());
Assertions.assertEquals("3", obj.get(0));
}
@Test
public void filteredTest() {
final List<String> obj2 = ListUtil.of("3");
final List<String> obj = ListUtil.of("1", "3");
final FilterIter<String> filtered = IterUtil.filtered(obj.iterator(), obj2::contains);
Assertions.assertEquals("3", filtered.next());
Assertions.assertFalse(filtered.hasNext());
}
@Test
public void filterToListTest() {
final List<String> obj2 = ListUtil.of("3");
final List<String> obj = ListUtil.of("1", "3");
final List<String> filtered = IterUtil.filterToList(obj.iterator(), obj2::contains);
Assertions.assertEquals(1, filtered.size());
Assertions.assertEquals("3", filtered.get(0));
}
@Test
public void getTest() {
final HashSet<String> set = SetUtil.ofLinked("A", "B", "C", "D");
final String str = IterUtil.get(set.iterator(), 2);
Assertions.assertEquals("C", str);
}
}

View File

@ -1,6 +1,11 @@
package org.dromara.hutool.core.collection.iter;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.collection.set.SetUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.w3c.dom.NodeList;
@ -64,27 +69,27 @@ public class IterUtilTest {
@Test
public void testCountMap() {
Object o1 = new Object();
Object o2 = new Object();
Map<Object, Integer> countMap = IterUtil.countMap(Arrays.asList(o1, o2, o1, o1).iterator());
final Object o1 = new Object();
final Object o2 = new Object();
final Map<Object, Integer> countMap = IterUtil.countMap(Arrays.asList(o1, o2, o1, o1).iterator());
Assertions.assertEquals((Integer)3, countMap.get(o1));
Assertions.assertEquals((Integer)1, countMap.get(o2));
}
@Test
public void testFieldValueMap() {
Bean bean1 = new Bean(1, "A");
Bean bean2 = new Bean(2, "B");
Map<Integer, Bean> map = IterUtil.fieldValueMap(Arrays.asList(bean1, bean2).iterator(), "id");
final Bean bean1 = new Bean(1, "A");
final Bean bean2 = new Bean(2, "B");
final Map<Integer, Bean> map = IterUtil.fieldValueMap(Arrays.asList(bean1, bean2).iterator(), "id");
Assertions.assertEquals(bean1, map.get(1));
Assertions.assertEquals(bean2, map.get(2));
}
@Test
public void testFieldValueAsMap() {
Bean bean1 = new Bean(1, "A");
Bean bean2 = new Bean(2, "B");
Map<Integer, String> map = IterUtil.fieldValueAsMap(
final Bean bean1 = new Bean(1, "A");
final Bean bean2 = new Bean(2, "B");
final Map<Integer, String> map = IterUtil.fieldValueAsMap(
Arrays.asList(bean1, bean2).iterator(), "id", "name"
);
Assertions.assertEquals("A", map.get(1));
@ -93,8 +98,8 @@ public class IterUtilTest {
@Test
public void testFieldValueList() {
Bean bean1 = new Bean(1, "A");
Bean bean2 = new Bean(2, "B");
final Bean bean1 = new Bean(1, "A");
final Bean bean2 = new Bean(2, "B");
Assertions.assertEquals(Arrays.asList(1, 2), IterUtil.fieldValueList(Arrays.asList(bean1, bean2), "id"));
Assertions.assertEquals(
Arrays.asList(1, 2),
@ -104,7 +109,7 @@ public class IterUtilTest {
@Test
public void testJoin() {
List<String> stringList = Arrays.asList("1", "2", "3");
final List<String> stringList = Arrays.asList("1", "2", "3");
Assertions.assertEquals("123", IterUtil.join(stringList.iterator(), ""));
Assertions.assertEquals("-1--2--3-", IterUtil.join(stringList.iterator(), "", "-", "-"));
Assertions.assertEquals("123", IterUtil.join(stringList.iterator(), "", Function.identity()));
@ -112,7 +117,7 @@ public class IterUtilTest {
@Test
public void testToMap() {
List<Integer> keys = Arrays.asList(1, 2, 3);
final List<Integer> keys = Arrays.asList(1, 2, 3);
Map<Integer, Integer> map = IterUtil.toMap(keys, keys);
Assertions.assertEquals(keys, new ArrayList<>(map.keySet()));
@ -141,7 +146,7 @@ public class IterUtilTest {
@Test
public void testToListMap() {
List<Integer> keys = Arrays.asList(1, 2, 3, 4);
final List<Integer> keys = Arrays.asList(1, 2, 3, 4);
Map<Boolean, List<Integer>> map = IterUtil.toListMap(keys, i -> (i & 1) == 0, Function.identity());
Assertions.assertEquals(Arrays.asList(2, 4), map.get(true));
@ -152,20 +157,32 @@ public class IterUtilTest {
Assertions.assertEquals(Arrays.asList(1, 3), map.get(false));
map = new LinkedHashMap<>();
Map<Boolean, List<Integer>> rawMap = IterUtil.toListMap(map, keys, i -> (i & 1) == 0, Function.identity());
final Map<Boolean, List<Integer>> rawMap = IterUtil.toListMap(map, keys, i -> (i & 1) == 0, Function.identity());
Assertions.assertSame(rawMap, map);
Assertions.assertEquals(Arrays.asList(2, 4), rawMap.get(true));
Assertions.assertEquals(Arrays.asList(1, 3), rawMap.get(false));
}
@Test
public void testToListMap2() {
final Map<String, List<String>> expectedMap = new HashMap<>();
expectedMap.put("a", Collections.singletonList("and"));
expectedMap.put("b", Arrays.asList("brave", "back"));
final Map<String, List<String>> testMap = IterUtil.toListMap(Arrays.asList("and", "brave", "back"),
v -> v.substring(0, 1));
Assertions.assertEquals(testMap, expectedMap);
}
@SuppressWarnings("DataFlowIssue")
@Test
public void testAsIterable() {
Iterator<Integer> iter = Arrays.asList(1, 2, 3).iterator();
final Iterator<Integer> iter = Arrays.asList(1, 2, 3).iterator();
Assertions.assertEquals(iter, IterUtil.asIterable(iter).iterator());
Assertions.assertNull(IterUtil.asIterable(null).iterator());
Enumeration<Integer> enumeration = new IteratorEnumeration<>(iter);
Iterator<Integer> iter2 = IterUtil.asIterator(enumeration);
final Enumeration<Integer> enumeration = new IteratorEnumeration<>(iter);
final Iterator<Integer> iter2 = IterUtil.asIterator(enumeration);
Assertions.assertEquals((Integer)1, iter2.next());
Assertions.assertEquals((Integer)2, iter2.next());
Assertions.assertEquals((Integer)3, iter2.next());
@ -173,14 +190,14 @@ public class IterUtilTest {
@Test
public void testGet() {
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
final Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
Assertions.assertEquals((Integer)3, IterUtil.get(iter, 2));
Assertions.assertThrows(IllegalArgumentException.class, () -> IterUtil.get(iter, -1));
}
@Test
public void testGetFirst() {
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
final Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4).iterator();
Assertions.assertEquals((Integer)1, IterUtil.getFirst(iter));
Assertions.assertNull(IterUtil.getFirst(null));
Assertions.assertNull(IterUtil.getFirst(Collections.emptyIterator()));
@ -192,7 +209,7 @@ public class IterUtilTest {
@Test
public void testGetFirstNoneNull() {
Iterator<Integer> iter = Arrays.asList(null, 2, null, 4).iterator();
final Iterator<Integer> iter = Arrays.asList(null, 2, null, 4).iterator();
Assertions.assertEquals((Integer)2, IterUtil.getFirstNoneNull(iter));
Assertions.assertNull(IterUtil.getFirstNoneNull(null));
Assertions.assertNull(IterUtil.getFirstNoneNull(Collections.emptyIterator()));
@ -200,7 +217,7 @@ public class IterUtilTest {
@Test
public void testGetElementType() {
List<Object> list = Arrays.asList(null, "str", null);
final List<Object> list = Arrays.asList(null, "str", null);
Assertions.assertEquals(String.class, IterUtil.getElementType(list));
Assertions.assertNull(IterUtil.getElementType((Iterable<?>)null));
Assertions.assertNull(IterUtil.getElementType(Collections.emptyList()));
@ -225,16 +242,15 @@ public class IterUtilTest {
@Test
public void testRemove() {
List<Integer> list = new ArrayList<>(Arrays.asList(1, null, null, 3));
final List<Integer> list = new ArrayList<>(Arrays.asList(1, null, null, 3));
IterUtil.remove(list.iterator(), Objects::isNull);
Assertions.assertEquals(Arrays.asList(1, 3), list);
}
@Test
public void testFilterToList() {
List<Integer> list1 = new ArrayList<>(Arrays.asList(1, null, null, 3));
List<Integer> list2 = IterUtil.filterToList(list1.iterator(), Objects::nonNull);
Assertions.assertSame(list1, list1);
final List<Integer> list1 = new ArrayList<>(Arrays.asList(1, null, null, 3));
final List<Integer> list2 = IterUtil.filterToList(list1.iterator(), Objects::nonNull);
Assertions.assertEquals(Arrays.asList(1, 3), list2);
}
@ -276,7 +292,7 @@ public class IterUtilTest {
@Test
public void testClear() {
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
final List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
IterUtil.clear(list.iterator());
Assertions.assertTrue(list.isEmpty());
Assertions.assertThrows(UnsupportedOperationException.class, () -> IterUtil.clear(Arrays.asList(1, 2).iterator()));
@ -284,7 +300,7 @@ public class IterUtilTest {
@Test
public void testToStr() {
List<Integer> list = Arrays.asList(1, 2, 3);
final List<Integer> list = Arrays.asList(1, 2, 3);
Assertions.assertEquals("[1, 2, 3]", IterUtil.toStr(list.iterator()));
Assertions.assertEquals("[1, 2, 3]", IterUtil.toStr(list.iterator(), Objects::toString));
Assertions.assertEquals("{1:2:3}", IterUtil.toStr(list.iterator(), Objects::toString, ":", "{", "}"));
@ -292,15 +308,133 @@ public class IterUtilTest {
@Test
public void testForEach() {
List<Integer> list = new ArrayList<>();
final List<Integer> list = new ArrayList<>();
IterUtil.forEach(Arrays.asList(1, 2, 3, 4).iterator(), list::add);
Assertions.assertEquals(Arrays.asList(1, 2, 3, 4), list);
}
@SuppressWarnings("unused")
@RequiredArgsConstructor
private static class Bean {
private final Integer id;
private final String name;
}
@Test
public void getFirstNonNullTest() {
final List<String> strings = ListUtil.of(null, null, "123", "456", null);
Assertions.assertEquals("123", CollUtil.getFirstNoneNull(strings));
}
@Test
public void fieldValueMapTest() {
final List<Car> carList = ListUtil.of(
new Car("123", "大众"),
new Car("345", "奔驰"),
new Car("567", "路虎"));
final Map<String, Car> carNameMap = IterUtil.fieldValueMap(carList.iterator(), "carNumber");
Assertions.assertEquals("大众", carNameMap.get("123").getCarName());
Assertions.assertEquals("奔驰", carNameMap.get("345").getCarName());
Assertions.assertEquals("路虎", carNameMap.get("567").getCarName());
}
@Test
public void joinTest() {
final List<String> list = ListUtil.of("1", "2", "3", "4");
final String join = IterUtil.join(list.iterator(), ":");
Assertions.assertEquals("1:2:3:4", join);
final List<Integer> list1 = ListUtil.of(1, 2, 3, 4);
final String join1 = IterUtil.join(list1.iterator(), ":");
Assertions.assertEquals("1:2:3:4", join1);
// 包装每个节点
final List<String> list2 = ListUtil.of("1", "2", "3", "4");
final String join2 = IterUtil.join(list2.iterator(), ":", "\"", "\"");
Assertions.assertEquals("\"1\":\"2\":\"3\":\"4\"", join2);
}
@Test
public void joinWithFuncTest() {
final List<String> list = ListUtil.of("1", "2", "3", "4");
final String join = IterUtil.join(list.iterator(), ":", String::valueOf);
Assertions.assertEquals("1:2:3:4", join);
}
@Test
public void joinWithNullTest() {
final List<String> list = ListUtil.of("1", null, "3", "4");
final String join = IterUtil.join(list.iterator(), ":", String::valueOf);
Assertions.assertEquals("1:null:3:4", join);
}
@Test
public void testToMap2() {
final Map<String, Car> expectedMap = new HashMap<>();
final Car bmw = new Car("123", "bmw");
expectedMap.put("123", bmw);
final Car benz = new Car("456", "benz");
expectedMap.put("456", benz);
final Map<String, Car> testMap = IterUtil.toMap(Arrays.asList(bmw, benz), Car::getCarNumber);
Assertions.assertEquals(expectedMap, testMap);
}
@Test
public void getElementTypeTest() {
final List<Integer> integers = Arrays.asList(null, 1);
final Class<?> elementType = IterUtil.getElementType(integers);
Assertions.assertEquals(Integer.class, elementType);
}
@Data
@AllArgsConstructor
public static class Car {
private String carNumber;
private String carName;
}
@Test
public void removeTest() {
final List<String> obj2 = ListUtil.of("3");
final List<String> obj = ListUtil.of("1", "3");
IterUtil.remove(obj.iterator(), (e)-> !obj2.contains(e));
Assertions.assertEquals(1, obj.size());
Assertions.assertEquals("3", obj.get(0));
}
@Test
public void filteredTest() {
final List<String> obj2 = ListUtil.of("3");
final List<String> obj = ListUtil.of("1", "3");
final FilterIter<String> filtered = IterUtil.filtered(obj.iterator(), obj2::contains);
Assertions.assertEquals("3", filtered.next());
Assertions.assertFalse(filtered.hasNext());
}
@Test
public void filterToListTest() {
final List<String> obj2 = ListUtil.of("3");
final List<String> obj = ListUtil.of("1", "3");
final List<String> filtered = IterUtil.filterToList(obj.iterator(), obj2::contains);
Assertions.assertEquals(1, filtered.size());
Assertions.assertEquals("3", filtered.get(0));
}
@Test
public void getTest() {
final HashSet<String> set = SetUtil.ofLinked("A", "B", "C", "D");
final String str = IterUtil.get(set.iterator(), 2);
Assertions.assertEquals("C", str);
}
}

View File

@ -7,7 +7,6 @@ import org.dromara.hutool.core.util.RandomUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.LinkedList;
import java.util.List;
/**
@ -618,50 +617,6 @@ public class StrUtilTest {
Assertions.assertEquals("/", result);
}
@Test
public void testIsAllBlank() {
final List<String> queue = new LinkedList<>();
queue.add("apple");
queue.add("banana");
queue.add("cherry");
queue.add("orange");
queue.add("strawberry");
queue.add("watermelon");
Assertions.assertFalse(StrUtil.isAllBlank(queue));
Assertions.assertTrue(CharSequenceUtil.isAllBlank(""));
Assertions.assertTrue(CharSequenceUtil.isAllBlank(" "));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\t"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\n"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\r"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\f"));
Assertions.assertFalse(CharSequenceUtil.isAllBlank("\b"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u00A0"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\uFEFF"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2000"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2001"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2002"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2003"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2004"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2005"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2006"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2007"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2008"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2009"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u200A"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u3000"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\uFEFF"));
// 其他空白字符
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u000B"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u000C"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u00A0"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u1680"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u180E"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2000"));
Assertions.assertTrue(CharSequenceUtil.isAllBlank("\u2001"));
}
@Test
public void issue2628Test(){
final String s = StrUtil.indexedFormat("a{0,number,#}", 1234567);

View File

@ -108,7 +108,7 @@ public class AnsiSqlDialect implements Dialect {
@Override
public PreparedStatement psForPage(final Connection conn, final Query query) throws SQLException {
Assert.notNull(query, "query must be not null !");
if (StrUtil.hasBlank(query.getTableNames())) {
if (ArrayUtil.hasBlank(query.getTableNames())) {
throw new DbRuntimeException("Table name must be not empty !");
}

View File

@ -338,7 +338,7 @@ public class SqlBuilder implements Builder<String> {
* @return 自己
*/
public SqlBuilder from(String... tableNames) {
if (ArrayUtil.isEmpty(tableNames) || StrUtil.hasBlank(tableNames)) {
if (ArrayUtil.isEmpty(tableNames) || ArrayUtil.hasBlank(tableNames)) {
throw new DbRuntimeException("Table name is blank in table names !");
}