Préface
Récemment, lorsque je développais, j'avais besoin de calculer la longueur d'un tableau de chaînes après l'épissage. J'avais initialement prévu d'écrire moi-même une classe d'outils simple pour calculer la longueur. Après qu'un collègue me l'ait rappelé, j'ai découvert qu'il existait un outil très utile. classe
.
première méthode
public static int calculateStrJoinLengthOfListMethod1(List<String> strList){
if(CollectionUtils.isEmpty(strList)){
return 0;
}
// 数组的join方法 “[Hello,world,abc]”
String tmpStr1 = StringUtils.join(strList);
// 注意此处我们不希望使用默认的分隔符 "," "HelloWorldAbc"
String tmpStr2 = StringUtils.join(strList, "");
return tmpStr2.length();
}
Deuxième méthode
public static int calculateStrJoinLengthOfListMethod2(List<String> strList){
if(CollectionUtils.isEmpty(strList)){
return 0;
}
StringBuilder builder = new StringBuilder();
strList.forEach(str -> builder.append(str));
return builder.toString().length();
}
Méthodes d'essai
package com.yanxml.util.string;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class StringArrayUtils {
public static int calculateStrJoinLengthOfListMethod1(List<String> strList){
if(CollectionUtils.isEmpty(strList)){
return 0;
}
// 数组的join方法 “[Hello,world,abc]”
String tmpStr1 = StringUtils.join(strList);
// 注意此处我们不希望使用默认的分隔符 "," "HelloWorldAbc"
String tmpStr2 = StringUtils.join(strList, "");
return tmpStr2.length();
}
public static int calculateStrJoinLengthOfListMethod2(List<String> strList){
if(CollectionUtils.isEmpty(strList)){
return 0;
}
StringBuilder builder = new StringBuilder();
strList.forEach(str -> builder.append(str));
return builder.toString().length();
}
public static void main(String[] args) {
List<String> strList = new ArrayList<>();
strList.add("Hello");
strList.add("World");
strList.add("abc");
// 测试方法1
int lengthByTest1 = calculateStrJoinLengthOfListMethod1(strList);
System.out.println("Test By Method1 - StringUtils.join, length " + lengthByTest1);
// 测试方法2
int lengthByTest2 = calculateStrJoinLengthOfListMethod2(strList);
System.out.println("Test By Method2 - StringBuilder.append, length "+ lengthByTest2);
}
}
# 测试结果
Test By Method1 - StringUtils.join, length 13
Test By Method2 - StringBuilder.append, length 13
Analyse du code source
Du point de vue de l'utilisateur, cela devrait normalement s'arrêter là, mais à partir du développement réel, nous avons tous appris que lorsque nous rencontrons des problèmes, si nous approfondissons, nous aurons une meilleure compréhension et des récompenses
.
Examinons d'abord la méthode de plus près StringUtils.join
.
Méthode de jointure du tableau
String tmpStr1 = StringUtils.join(strList);
# org.apache.commons.lang3.StringUtils 类
# 单参数重载方法 Array
public static <T> String join(T... elements) {
return join((Object[])elements, (String)null);
}
# 2个参数重载方法 Array & 间隔符
public static String join(Object[] array, String separator) {
return array == null ? null : join(array, separator, 0, array.length);
}
# 4个参数重载方法 Array & 间隔符 & 开始下标 & 结束下标
public static String join(Object[] array, String separator, int startIndex, int endIndex) {
if (array == null) {
return null;
} else {
if (separator == null) {
separator = "";
}
int noOfItems = endIndex - startIndex;
if (noOfItems <= 0) {
return "";
} else {
StringBuilder buf = new StringBuilder(noOfItems * 16);
for(int i = startIndex; i < endIndex; ++i) {
if (i > startIndex) {
buf.append(separator);
}
if (array[i] != null) {
buf.append(array[i]);
}
}
return buf.toString();
}
}
}
- Comme vous pouvez le voir, cette méthode de jointure est la même que les deux méthodes. La méthode utilisée
StringBuilder.append
n'est qu'une couche d'empaquetage et n'a aucune autre utilité. Et les deux sont thread-unsafe.
Méthode de jointure de chaîne
String tmpStr2 = StringUtils.join(strList, "");
# org.apache.commons.lang3.StringUtils 类
public static String join(Iterable<?> iterable, String separator) {
return iterable == null ? null : join(iterable.iterator(), separator);
}
public static String join(Iterator<?> iterator, String separator) {
if (iterator == null) {
return null;
} else if (!iterator.hasNext()) {
return "";
} else {
Object first = iterator.next();
if (!iterator.hasNext()) {
String result = ObjectUtils.toString(first);
return result;
} else {
StringBuilder buf = new StringBuilder(256);
if (first != null) {
buf.append(first);
}
while(iterator.hasNext()) {
if (separator != null) {
buf.append(separator);
}
Object obj = iterator.next();
if (obj != null) {
buf.append(obj);
}
}
return buf.toString();
}
}
}
- Ce qui est plus intéressant, c'est que les résultats obtenus par ces deux méthodes sont complètement différents.Le problème principal peut être ici, l'itération du tableau se fait par conversion forcée et la chaîne est traitée en
return join((Object[])elements, (String)null);
utilisantIterator
.
un phénomène étrange
Le résultat est "[Bonjour, Monde, Abc]"
// 数组的join方法 “[Hello,world,abc]”
String tmpStr1 = StringUtils.join(strList);
// 注意此处我们不希望使用默认的分隔符 "," "HelloWorldAbc"
String tmpStr2 = StringUtils.join(strList, "");
- Il se peut que la première méthode appelante déclenche la méthode array , ce qui conduit à un tel affichage
toString
ici .[XX,XX,XX]
Référence
[1]. [Méthode et utilisation de la méthode StringUtils.join()] ( https://www.cnblogs.com/fenghh/p/12175368.html )
[2]. [À quel paquet appartient CollectionUtils] https:// blog .csdn.net/weixin_42114097/article/details/90579980