GitHub 上 1
if (caseSensitive) {return value.contains(needle);}return value.toLowerCase().contains(needle.toLowerCase());}内部通过 String 类的方法实现,如果不区分大小写,则先调用方法转成小写。验证指定的字符串是否包含字符串数组中任意一个字符串,或更多。System.out.println(St
if (caseSensitive) {
return value.contains(needle);
}
return value.toLowerCase().contains(needle.toLowerCase());
}
内部通过 String 类的 contains()
方法实现,如果不区分大小写,则先调用 toLowerCase()
方法转成小写。
09、containsAny
验证指定的字符串是否包含字符串数组中任意一个字符串,或更多。
System.out.println(Strman.containsAny(“沉默王二”, new String [] {“沉”,“三”}));
System.out.println(Strman.containsAny(“沉默王二”, new String [] {“沉默”,“三”}));
System.out.println(Strman.containsAny(“沉默王二”, new String [] {“不”,“三”}));
结果如下所示:
true
true
false
来看一下源码:
public static boolean containsAny(final String value, final String[] needles, final boolean caseSensitive) {
return Arrays.stream(needles).anyMatch(needle -> contains(value, needle, caseSensitive));
}
Stream 类提供了三个方法可供进行元素匹配,它们分别是:
-
anyMatch()
,只要有一个元素匹配传入的条件,就返回 true。 -
allMatch()
,只有有一个元素不匹配传入的条件,就返回 false;如果全部匹配,则返回 true。 -
noneMatch()
,只要有一个元素匹配传入的条件,就返回 false;如果全部匹配,则返回 true。
10、endsWith
验证字符串是否以某个字符串结尾。
System.out.println(Strman.endsWith(“沉默王二”,“二”));
System.out.println(Strman.endsWith(“Abbc”, “A”, false));
结果如下所示:
true
false
来看一下源码:
public static boolean endsWith(final String value, final String search, final int position,
final boolean caseSensitive) {
int remainingLength = position - search.length();
if (caseSensitive) {
return value.indexOf(search, remainingLength) > -1;
}
return value.toLowerCase().indexOf(search.toLowerCase(), remainingLength) > -1;
}
内部通过 String 类的 indexOf()
方法实现。
11、ensureLeft
确保字符串以某个字符串开头,如果该字符串没有以指定的字符串开头,则追加上去。
System.out.println(Strman.ensureLeft(“沉默王二”, “沉”));
System.out.println(Strman.ensureLeft(“默王二”, “沉”));
结果如下所示:
沉默王二
沉默王二
来看一下源码:
public static String ensureLeft(final String value, final String prefix, final boolean caseSensitive) {
if (caseSensitive) {
return value.startsWith(prefix) ? value : prefix + value;
}
String _value = value.toLowerCase();
String _prefix = prefix.toLowerCase();
return _value.startsWith(_prefix) ? value : prefix + value;
}
内部通过 String 类的 startsWith()
方法先进行判断,如果结果为 false,则通过“+”操作符进行连接。
ensureLeft 对应的还有 ensureRight,同理,这里不再赘述。
12、base64Encode
把字符串进行 base64 编码。
Strman.base64Encode(“沉默王二”);
结果如下所示:
5rKJ6buY546L5LqM
Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。来看一下源码:
public static String base64Encode(final String value) {
return Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8));
}
内部是通过 Base64 类实现的,Java 8 新增的一个类。
base64Encode 对应的解码方法是 base64Decode,使用方法如下所示:
Strman.base64Decode(“5rKJ6buY546L5LqM”)
如果不可解码的会,会抛出 IllegalArgumentException 异常。
Exception in thread “main” java.lang.IllegalArgumentException: Last unit does not have enough valid bits
at java.base/java.util.Base64$Decoder.decode0(Base64.java:763)
at java.base/java.util.Base64$Decoder.decode(Base64.java:535)
at java.base/java.util.Base64$Decoder.decode(Base64.java:558)
at strman.Strman.base64Decode(Strman.java:328)
at com.itwanger.strman.Demo.main(Demo.java:58)
13、binEncode
把字符串转成二进制的 Unicode(16 位)。
Strman.binEncode(“沉默王二”);
结果如下所示:
0110110010001001100111101101100001110011100010110100111010001100
binEncode 对应的方法是 binDecode,把二进制的 Unicode 转成字符串,使用方法如下所示:
Strman.binDecode(“0110110010001001100111101101100001110011100010110100111010001100”);
14、first
返回字符串的前 N 个字符。
System.out.println(Strman.first(“沉默王二”, 0));
System.out.println(Strman.first(“沉默王二”, 1));
System.out.println(Strman.first(“沉默王二”, 2));
结果如下所示:
Optional[]
Optional[沉]
Optional[沉默]
如果 N 为负数的话,将会抛出 StringIndexOutOfBoundsException 异常:
Exception in thread “main” java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 4
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:3319)
at java.base/java.lang.String.substring(String.java:1874)
at strman.Strman.lambda$first$9(Strman.java:414)
at java.base/java.util.Optional.map(Optional.java:265)
at strman.Strman.first(Strman.java:414)
at com.itwanger.strman.Demo.main(Demo.java:68)
针对 N 为负数的情况,我觉得没有之前的 at 方法处理的巧妙。
来看一下源码:
public static Optional first(final String value, final int n) {
return Optional.ofNullable(value).filter(v -> !v.isEmpty()).map(v -> v.substring(0, n));
}
内部是通过 String 类的 substring()
方法实现的,不过没有针对 n 小于 0 的情况做处理。
ofNullable()
方法可以创建一个即可空又可非空的 Optional 对象。
filter()
方法的参数类型为 Predicate(Java 8 新增的一个函数式接口),也就是说可以将一个 Lambda 表达式传递给该方法作为条件,如果表达式的结果为 false,则返回一个 EMPTY 的 Optional 对象,否则返回过滤后的 Optional 对象。
map()
方法可以按照一定的规则将原有 Optional 对象转换为一个新的 Optional 对象,原有的 Optional 对象不会更改。
first 对应的的是 last 方法,返回字符串的后 N 个字符。
15、head
返回字符串的第一个字符。
Strman.head(“沉默王二”);
结果如下所示:
Optional[沉]
来看一下源码:
public static Optional head(final String value) {
return first(value, 1);
}
内部是通过调用 first()
方法实现的,只不过 N 为 1。
16、unequal
检查两个字符串是否不等。
Strman.unequal(“沉默王二”,“沉默王三”);
结果如下所示:
true
来看一下源码:
public static boolean unequal(final String first, final String second) {
return !Objects.equals(first, second);
}
内部是通过 Objects.equals()
方法进行判断的,由于 String 类重写了 equals()
方法,也就是说,实际上还是通过 String 类的 equals()
方法进行判断的。
17、insert
把字符串插入到指定索引处。
Strman.insert(“沉默二”,“王”,2);
结果如下所示:
沉默王二
来看一下源码:
public static String insert(final String value, final String substr, final int index) {
if (index > value.length()) {
return value;
}
return append(value.substring(0, index), substr, value.substring(index));
}
如果索引超出字符串长度,直接返回原字符串;否则调用 append()
方法将指定字符串插入到对应索引处。
18、repeat
对字符串重复指定次数。
Strman.repeat(“沉默王二”, 3);
结果如下所示:
沉默王二沉默王二沉默王二
来看一下源码:
public static String repeat(final String value, final int multiplier) {
return Stream.generate(() -> value).limit(multiplier).collect(joining());
}
Stream.generate()
生成的 Stream,默认是串行(相对 parallel 而言)但无序的(相对 ordered 而言)。由于它是无限的,在管道中,必须利用 limit 之类的操作限制 Stream 大小。
collect(joining())
可以将流转成字符串。
19、leftPad
返回给定长度的新字符串,以便填充字符串的开头。
Strman.leftPad(“王二”,“沉默”,6);
结果如下所示:
沉默沉默沉默沉默王二
来看一下源码:
public static String leftPad(final String value, final String pad, final int length) {
if (value.length() > length) {
return value;
}
return append(repeat(pad, length - value.length()), value);
}
内部会先调用 repeat()
方法进行补位,然后再调用 append()
方法拼接。
leftPad 方法对应的是 rightPad,填充字符串的末尾。
19)removeEmptyStrings,从字符串数组中移除空字符串。
String [] results = Strman.removeEmptyStrings(new String[]{“沉”, " ", " ", “默王二”});
System.out.println(Arrays.toString(results));
结果如下所示:
[沉, 默王二]
来看一下源码:
public static String[] removeEmptyStrings(String[] strings) {
if (Objects.isNull(strings)) {
throw new IllegalArgumentException(“Input array should not be null”);
}
return Arrays.stream(strings).filter(str -> str != null && !str.trim().isEmpty()).toArray(String[]::new);
}
通过 Stream 的 filter()
方法过滤掉了空格。
20、reverse
反转字符串。
Strman.reverse(“沉默王二”);
结果如下所示:
二王默沉
来看一下源码:
public static String reverse(final String value) {
return new StringBuilder(value).reverse().toString();
}
内部是通过 StringBuilder
类的 reverse()
方法进行反转的。
21、safeTruncate
对字符串进行截断,但不会破坏单词的完整性。
Strman.safeTruncate(“Java is the best”,13,“…”);
结果如下所示:
Java is…
来看一下源码:
public static String safeTruncate(final String value, final int length, final String filler) {
if (length == 0) {
return “”;
}
if (length >= value.length()) {
return value;
}
String[] words = words(value);
StringJoiner result = new StringJoiner(" ");
int spaceCount = 0;
for (String word : words) {
if (result.length() + word.length() + filler.length() + spaceCount > length) {
break;
} else {
result.add(word);
spaceCount++;
}
}
return append(result.toString(), filler);
}
先调用 words()
方法对字符串进行单词分割,然后按照长度进行截断,最后调用 append()
方法填充上补位符。
safeTruncate 对应的是 truncate,可能会破坏单词的完整性,使用方法如下所示:
Strman.truncate(“Java is the best”,13,“…”)
结果如下所示:
Java is th…
来看一下源码:
public static String truncate(final String value, final int length, final String filler) {
if (length == 0) {
return “”;
}
if (length >= value.length()) {
return value;
}
return append(value.substring(0, length - filler.length()), filler);
}
就是单纯的切割和补位,没有对单词进行保护。
22、shuffle
对字符串重新洗牌。
Strman.shuffle(“沉默王二”);
结果如下所示:
王默二沉
来看一下源码:
public static String shuffle(final String value) {
String[] chars = chars(value);
Random random = new Random();
for (int i = 0; i < chars.length; i++) {
int r = random.nextInt(chars.length);
String tmp = chars[i];
chars[i] = chars[r];
chars[r] = tmp;
}
return Arrays.stream(chars).collect(joining());
}
调用 chars()
方法把字符串拆分为字符串数组,然后遍历对其重排,最后通过 Stream 转成新的字符串。
23、其他方法
Strman 中还有很多其他巧妙的字符串处理方法,比如说把字符串按照指定的前后缀进行包裹 surround 等等,同学们可以参考 Strman 的官方文档进行学习:
https://github.com/shekhargulati/strman-java/wiki
PS:最近有小伙伴私信我要一份优质的 Java 教程,我在 GitHub 花了很长时间才找到了一份,115k star,真的非常不错,来看一下目录:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)
更多:Java进阶核心知识集
包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等
高效学习视频
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
csdnimg.cn/img_convert/e72ac6414ce6b141482a596f177f9afa.png)
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-6k4DFyhl-1711600207948)]
[外链图片转存中…(img-0cMMKG4B-1711600207948)]
[外链图片转存中…(img-jbgePyV9-1711600207949)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)
更多:Java进阶核心知识集
包含:JVM,JAVA集合,网络,JAVA多线程并发,JAVA基础,Spring原理,微服务,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存等等
[外链图片转存中…(img-OSFoUPnf-1711600207949)]
高效学习视频
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)