所以我一直在回顾我大约一年半前编写的代码,试图修复它,我发现这个函数让我感到困惑。我搜索了一种做同样事情的方法,并找到了一个相当不错的功能,我很好奇什么会更好。
函数 A:
public static String listToString(List<String> list){
StringBuilder sb = new StringBuilder();
if (list != null && list.size() > 1){
sb.append(list.get(0));
for (int i = 1; i < list.size(); i++){
sb.append(", " + list.get(i));
}
}else if(list != null && (list.size() == 1)){
sb.append(list.get(0));
}
return sb.toString();
}
函数 B:
public static String listToString(List<String> list) {
String str = "";
for (String s : list) {
str += s + ", ";
}
return str;
}
现在我在学习Java的头几个月内编写了函数A,所以我可能不是最好的,尽管有什么理由我应该坚持这种方法吗?
检查番石榴上的木匠
String s= Joiner.on(",").join(lists);
检查下面的输出测试
List<String> lists=new ArrayList<String>();
lists.add("a1");
lists.add("a2");
lists.add("a3");
lists.add("a4");
String s = Joiner.on(",").join(lists);
System.out.println(s);
输出:
a1,a2,a3,a4
Apache 的 commons lang,只是附加
StringUtils.join(list);
或 按字符分隔。
StringUtils.join(java.lang.Iterable,char)
Java 8.0 及以上,第一个参数是分离元素
String joined = String.join("", list);
函数 A 更可取,因为它只使用 StringBuilder 的一个实例,而函数 B 中的代码在循环中执行
str += s + ", ";
相当于
str = new StringBuilder(str).append(s).append(", ").toString();
因此,在每次迭代中,您必须:
- 创建新的字符串生成器
- 将当前字符串的内容复制到此字符串生成器
- 现在,您可以添加
", "
和s
- 根据 StringBuilder 的当前内容创建并返回新字符串
(所以在每次迭代中,你需要一次又一次地读取整个字符串......)而在场景B中,你只专注于向单个StringBuilder添加新字符
。无论如何,从Java 8开始,你不需要把太多精力放在可以连接字符串集合的编写方法上。您可以简单地使用StringJoiner
类或更简单的调用
join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
字符串类中的方法,它将为您使用 StringJoiner
。此方法的代码如下所示:
public static String join(CharSequence delimiter,
Iterable<? extends CharSequence> elements) {
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
joiner.add(cs);
}
return joiner.toString();
}
请注意,Objects.requireNonNull(delimiter);
会在 null
的情况下抛出 NPE,所以如果你想避免它,你可以编写你自己的此方法版本,并用更类似的东西替换这个测试。
if (delimiter==null || elements==null) return "";
或者,如果您希望允许分隔符为空
if (elements==null) return "";
if (delimiter == null) delimiter = "";//use empty string as delimiter
除了使用库之外,您还可以使用
(我最常看到的模式)
public static String listToString(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String string : list) {
if (first)
first = false;
else
sb.append(", ");
sb.append(string);
}
return sb.toString();
}
(也很常见)
public static String listToString(List<String> list) {
StringBuilder sb = new StringBuilder();
String separator = "";
for (String string : list) {
sb.append(separator).append(string);
separator = ", ";
}
return sb.toString();
}
(最短,有点难读)
public static String listToString(List<String> list) {
StringBuilder sb = new StringBuilder();
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();)
sb.append(iterator.next()).append(iterator.hasNext() ? ", " : "");
return sb.toString();
}
(可能是最快的,因为循环中没有额外的条件跳转)
public static String listToString(List<String> list) {
StringBuilder sb = new StringBuilder();
Iterator<String> iterator = list.iterator();
if (iterator.hasNext()) {
sb.append(iterator.next());
while (iterator.hasNext())
sb.append(", ").append(iterator.next());
}
return sb.toString();
}
或者其他可读和简短的东西,如B,但使用StringBuilder
。您不希望在循环中+
字符串串联。这将创建临时对象。