Merge pull request #1841 from Hccake/v5-dev

在做字符串切割时,允许传入 mapping 方法,来对切割后的元素做一个处理
This commit is contained in:
Golden Looly 2021-09-25 09:49:25 +08:00 committed by GitHub
commit 35b9212103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 24 deletions

View File

@ -23,6 +23,7 @@ import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
@ -1698,6 +1699,19 @@ public class CharSequenceUtil {
return split(str, separator, 0); return split(str, separator, 0);
} }
/**
* 切分字符串并根据指定的映射函数进行切分后的元素类型转换
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param mapping 切分后的字符串元素的转换方法
* @return 切分后的集合元素类型是经过 mapping 转换后的
* @since 5.7.14
*/
public static <R> List<R> split(CharSequence str, char separator, Function<String, R> mapping) {
return split(str, separator, 0, mapping);
}
/** /**
* 切分字符串如果分隔符不存在则返回原字符串 * 切分字符串如果分隔符不存在则返回原字符串
* *
@ -1752,6 +1766,20 @@ public class CharSequenceUtil {
return split(str, separator, limit, false, false); return split(str, separator, limit, false, false);
} }
/**
* 切分字符串不去除切分后每个元素两边的空白符不去除空白项会根据指定的映射函数进行切分后的元素类型转换
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数-1不限制
* @param mapping 切分后的字符串元素的转换方法
* @return 切分后的集合元素类型是经过 mapping 转换后的
* @since 5.7.14
*/
public static <R> List<R> split(CharSequence str, char separator, int limit, Function<String, R> mapping) {
return split(str, separator, limit, false, false, mapping);
}
/** /**
* 切分字符串去除切分后每个元素两边的空白符去除空白项 * 切分字符串去除切分后每个元素两边的空白符去除空白项
* *
@ -1828,10 +1856,26 @@ public class CharSequenceUtil {
* @since 3.0.8 * @since 3.0.8
*/ */
public static List<String> split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) { public static List<String> split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty) {
return split(str, separator, limit, isTrim, ignoreEmpty, Function.identity());
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数-1不限制
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @param mapping 切分后的字符串元素的转换方法
* @return 切分后的集合元素类型是经过 mapping 转换后的
* @since 5.7.14
*/
public static <R> List<R> split(CharSequence str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, Function<String, R> mapping) {
if (null == str) { if (null == str) {
return new ArrayList<>(0); return new ArrayList<>(0);
} }
return StrSplitter.split(str.toString(), separator, limit, isTrim, ignoreEmpty); return StrSplitter.split(str.toString(), separator, limit, isTrim, ignoreEmpty, mapping);
} }
/** /**
@ -4028,8 +4072,8 @@ public class CharSequenceUtil {
* @param str 转换前的驼峰式命名的字符串也可以为符号连接形式 * @param str 转换前的驼峰式命名的字符串也可以为符号连接形式
* @param symbol 连接符 * @param symbol 连接符
* @return 转换后符号连接方式命名的字符串 * @return 转换后符号连接方式命名的字符串
* @since 4.0.10
* @see NamingCase#toSymbolCase(CharSequence, char) * @see NamingCase#toSymbolCase(CharSequence, char)
* @since 4.0.10
*/ */
public static String toSymbolCase(CharSequence str, char symbol) { public static String toSymbolCase(CharSequence str, char symbol) {
return NamingCase.toSymbolCase(str, symbol); return NamingCase.toSymbolCase(str, symbol);
@ -4203,7 +4247,7 @@ public class CharSequenceUtil {
} }
// since 5.7.5特殊长度 // since 5.7.5特殊长度
switch (maxLength){ switch (maxLength) {
case 1: case 1:
return String.valueOf(str.charAt(0)); return String.valueOf(str.charAt(0));
case 2: case 2:
@ -4234,7 +4278,7 @@ public class CharSequenceUtil {
/** /**
* conjunction 为分隔符将多个对象转换为字符串 * conjunction 为分隔符将多个对象转换为字符串
* *
* @param <T> 元素类型 * @param <T> 元素类型
* @param conjunction 分隔符 {@link StrPool#COMMA} * @param conjunction 分隔符 {@link StrPool#COMMA}
* @param iterable 集合 * @param iterable 集合
* @return 连接后的字符串 * @return 连接后的字符串
@ -4257,7 +4301,7 @@ public class CharSequenceUtil {
if (StrUtil.isBlank(value)) { if (StrUtil.isBlank(value)) {
return false; return false;
} }
for (int i = value.length(); --i >= 0;) { for (int i = value.length(); --i >= 0; ) {
if (false == matcher.match(value.charAt(i))) { if (false == matcher.match(value.charAt(i))) {
return false; return false;
} }

View File

@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -122,6 +123,22 @@ public class StrSplitter {
return split(str, separator, limit, isTrim, ignoreEmpty, false); return split(str, separator, limit, isTrim, ignoreEmpty, false);
} }
/**
* 切分字符串大小写敏感
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数-1不限制
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @param mapping 切分后的字符串元素的转换方法
* @return 切分后的集合元素类型是经过 mapping 转换后的
* @since 5.7.14
*/
public static <R> List<R> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, Function<String, R> mapping) {
return split(str, separator, limit, isTrim, ignoreEmpty, false, mapping);
}
/** /**
* 切分字符串忽略大小写 * 切分字符串忽略大小写
* *
@ -150,19 +167,36 @@ public class StrSplitter {
* @since 3.2.1 * @since 3.2.1
*/ */
public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) { public static List<String> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase) {
return split(str, separator, limit, isTrim, ignoreEmpty, ignoreCase, Function.identity());
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数-1不限制
* @param isTrim 是否去除切分字符串后每个元素两边的空格
* @param ignoreEmpty 是否忽略空串
* @param ignoreCase 是否忽略大小写
* @param mapping 切分后的字符串元素的转换方法
* @return 切分后的集合元素类型是经过 mapping 转换后的
* @since 5.7.14
*/
public static <R> List<R> split(String str, char separator, int limit, boolean isTrim, boolean ignoreEmpty, boolean ignoreCase, Function<String, R> mapping) {
if (StrUtil.isEmpty(str)) { if (StrUtil.isEmpty(str)) {
return new ArrayList<>(0); return new ArrayList<>(0);
} }
if (limit == 1) { if (limit == 1) {
return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty); return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty, mapping);
} }
final ArrayList<String> list = new ArrayList<>(limit > 0 ? limit : 16); final ArrayList<R> list = new ArrayList<>(limit > 0 ? limit : 16);
int len = str.length(); int len = str.length();
int start = 0;//切分后每个部分的起始 int start = 0;//切分后每个部分的起始
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (NumberUtil.equals(separator, str.charAt(i), ignoreCase)) { if (NumberUtil.equals(separator, str.charAt(i), ignoreCase)) {
addToList(list, str.substring(start, i), isTrim, ignoreEmpty); addToList(list, str.substring(start, i), isTrim, ignoreEmpty, mapping);
start = i + 1;//i+1同时将start与i保持一致 start = i + 1;//i+1同时将start与i保持一致
//检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串 //检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串
@ -171,7 +205,7 @@ public class StrSplitter {
} }
} }
} }
return addToList(list, str.substring(start, len), isTrim, ignoreEmpty);//收尾 return addToList(list, str.substring(start, len), isTrim, ignoreEmpty, mapping);//收尾
} }
/** /**
@ -293,7 +327,7 @@ public class StrSplitter {
return new ArrayList<>(0); return new ArrayList<>(0);
} }
if (limit == 1) { if (limit == 1) {
return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty); return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty, Function.identity());
} }
if (StrUtil.isEmpty(separator)) {//分隔符为空时按照空白符切分 if (StrUtil.isEmpty(separator)) {//分隔符为空时按照空白符切分
@ -310,7 +344,7 @@ public class StrSplitter {
while (i < len) { while (i < len) {
i = StrUtil.indexOf(str, separator, start, ignoreCase); i = StrUtil.indexOf(str, separator, start, ignoreCase);
if (i > -1) { if (i > -1) {
addToList(list, str.substring(start, i), isTrim, ignoreEmpty); addToList(list, str.substring(start, i), isTrim, ignoreEmpty, Function.identity());
start = i + separatorLen; start = i + separatorLen;
//检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串 //检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串
@ -321,7 +355,7 @@ public class StrSplitter {
break; break;
} }
} }
return addToList(list, str.substring(start, len), isTrim, ignoreEmpty); return addToList(list, str.substring(start, len), isTrim, ignoreEmpty, Function.identity());
} }
/** /**
@ -355,7 +389,7 @@ public class StrSplitter {
return new ArrayList<>(0); return new ArrayList<>(0);
} }
if (limit == 1) { if (limit == 1) {
return addToList(new ArrayList<>(1), str, true, true); return addToList(new ArrayList<>(1), str, true, true, Function.identity());
} }
final ArrayList<String> list = new ArrayList<>(); final ArrayList<String> list = new ArrayList<>();
@ -363,7 +397,7 @@ public class StrSplitter {
int start = 0;//切分后每个部分的起始 int start = 0;//切分后每个部分的起始
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (CharUtil.isBlankChar(str.charAt(i))) { if (CharUtil.isBlankChar(str.charAt(i))) {
addToList(list, str.substring(start, i), true, true); addToList(list, str.substring(start, i), true, true, Function.identity());
start = i + 1;//i+1同时将start与i保持一致 start = i + 1;//i+1同时将start与i保持一致
//检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串 //检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串
@ -372,7 +406,7 @@ public class StrSplitter {
} }
} }
} }
return addToList(list, str.substring(start, len), true, true);//收尾 return addToList(list, str.substring(start, len), true, true, Function.identity());//收尾
} }
/** /**
@ -421,7 +455,7 @@ public class StrSplitter {
return new ArrayList<>(0); return new ArrayList<>(0);
} }
if (limit == 1) { if (limit == 1) {
return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty); return addToList(new ArrayList<>(1), str, isTrim, ignoreEmpty, Function.identity());
} }
if (null == separatorPattern) {//分隔符为空时按照空白符切分 if (null == separatorPattern) {//分隔符为空时按照空白符切分
@ -433,7 +467,7 @@ public class StrSplitter {
int len = str.length(); int len = str.length();
int start = 0; int start = 0;
while (matcher.find()) { while (matcher.find()) {
addToList(list, str.substring(start, matcher.start()), isTrim, ignoreEmpty); addToList(list, str.substring(start, matcher.start()), isTrim, ignoreEmpty, Function.identity());
start = matcher.end(); start = matcher.end();
//检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串 //检查是否超出范围最大允许limit-1个剩下一个留给末尾字符串
@ -441,7 +475,7 @@ public class StrSplitter {
break; break;
} }
} }
return addToList(list, str.substring(start, len), isTrim, ignoreEmpty); return addToList(list, str.substring(start, len), isTrim, ignoreEmpty, Function.identity());
} }
/** /**
@ -496,14 +530,15 @@ public class StrSplitter {
* @param part 被加入的部分 * @param part 被加入的部分
* @param isTrim 是否去除两端空白符 * @param isTrim 是否去除两端空白符
* @param ignoreEmpty 是否略过空字符串空字符串不做为一个元素 * @param ignoreEmpty 是否略过空字符串空字符串不做为一个元素
* @return 列表 * @param mapping part的类型转换方法
* @return 列表集合
*/ */
private static List<String> addToList(List<String> list, String part, boolean isTrim, boolean ignoreEmpty) { private static <R> List<R> addToList(List<R> list, String part, boolean isTrim, boolean ignoreEmpty, Function<String, R> mapping) {
if (isTrim) { if (isTrim) {
part = StrUtil.trim(part); part = StrUtil.trim(part);
} }
if (false == ignoreEmpty || false == part.isEmpty()) { if (false == ignoreEmpty || false == part.isEmpty()) {
list.add(part); list.add(mapping.apply(part));
} }
return list; return list;
} }

View File

@ -81,6 +81,15 @@ public class StrUtilTest {
Assert.assertEquals("", split.get(2)); Assert.assertEquals("", split.get(2));
} }
@Test
public void splitTest3() {
String str = "1.2.";
List<Long> split = StrUtil.split(str, '.', 0, true, true, Long::parseLong);
Assert.assertEquals(2, split.size());
Assert.assertEquals(Long.valueOf(1L), split.get(0));
Assert.assertEquals(Long.valueOf(2L), split.get(1));
}
@Test @Test
public void splitToLongTest() { public void splitToLongTest() {
String str = "1,2,3,4, 5"; String str = "1,2,3,4, 5";
@ -550,7 +559,7 @@ public class StrUtilTest {
} }
@Test @Test
public void startWithTest(){ public void startWithTest() {
String a = "123"; String a = "123";
String b = "123"; String b = "123";
@ -577,13 +586,13 @@ public class StrUtilTest {
@Test @Test
public void isCharEqualsTest(){ public void isCharEqualsTest() {
String a = "aaaaaaaaa"; String a = "aaaaaaaaa";
Assert.assertTrue(StrUtil.isCharEquals(a)); Assert.assertTrue(StrUtil.isCharEquals(a));
} }
@Test @Test
public void isNumericTest(){ public void isNumericTest() {
String a = "2142342422423423"; String a = "2142342422423423";
Assert.assertTrue(StrUtil.isNumeric(a)); Assert.assertTrue(StrUtil.isNumeric(a));
} }