【发布时间】:2010-09-16 07:19:15
【问题描述】:
我知道这是一个新手问题,但有没有 C# 在 Java 中的字符串操作等价物?
具体来说,我说的是String.Format 和String.Join。
【问题讨论】:
-
所以有一个 String.format 但我必须自己加入。
-
对于 join(),我喜欢这个答案:stackoverflow.com/a/6116469/562139
我知道这是一个新手问题,但有没有 C# 在 Java 中的字符串操作等价物?
具体来说,我说的是String.Format 和String.Join。
【问题讨论】:
String.format。至于join,需要自己写:
static String join(Collection<?> s, String delimiter) {
StringBuilder builder = new StringBuilder();
Iterator<?> iter = s.iterator();
while (iter.hasNext()) {
builder.append(iter.next());
if (!iter.hasNext()) {
break;
}
builder.append(delimiter);
}
return builder.toString();
}
【讨论】:
Java String 对象有一个format 方法(从1.5 开始),但没有join 方法。
要获得一些尚未包含的有用的字符串实用方法,您可以使用org.apache.commons.lang.StringUtils。
【讨论】:
String.join() 方法。
至于加入,我相信这看起来不那么复杂:
public String join (Collection<String> c) {
StringBuilder sb=new StringBuilder();
for(String s: c)
sb.append(s);
return sb.toString();
}
我没有尽可能多地使用 Java 5 语法(信不信由你,我最近一直在使用 1.0.x)所以我可能有点生疏,但我确信概念是正确的。
编辑添加:字符串追加可能会很慢,但是如果您正在处理 GUI 代码或一些短期运行的例程,那么您需要 0.005 秒还是 0.006 秒并不重要,所以如果您有一个名为"joinMe" 你想附加到一个现有的字符串 "target" 内联它不会是可怕的:
for(String s : joinMe)
target += s;
这是非常低效的(也是一个坏习惯),但除非有数千个字符串,或者这是在一个巨大的循环中,或者您的代码对性能非常关键,否则您将无法感知到任何东西。
更重要的是,它易于记忆、简短、快速且易读。性能并不总是设计选择的自动赢家。
【讨论】:
如果您希望将多个字符串连接(连接)为一个,则应使用 StringBuilder。这比使用
好得多for(String s : joinMe)
target += s;
由于 StringBuilder 不使用同步,因此性能也比 StringBuffer 略有优势。
对于像这样的通用实用程序方法,它会(最终)在很多情况下被多次调用,所以你应该让它高效而不是分配很多瞬态对象。我们分析了许许多多不同的 Java 应用程序,并且几乎总是发现字符串连接和字符串/char[] 分配占用了大量的时间/内存。
我们的可重用集合 -> 字符串方法首先计算所需结果的大小,然后创建一个具有该初始大小的 StringBuilder;这避免了附加字符串时使用的内部 char[] 不必要的加倍/复制。
【讨论】:
StringUtils 是 Apache Commons Lang 库中一个非常有用的类。
【讨论】:
我只想使用字符串连接运算符“+”来连接两个字符串。 s1 += s2;
【讨论】:
您还可以对字符串使用可变参数,如下所示:
String join (String delim, String ... data) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length; i++) {
sb.append(data[i]);
if (i >= data.length-1) {break;}
sb.append(delim);
}
return sb.toString();
}
【讨论】:
import com.google.common.base.Joiner;
Joiner.on(separator).join(data);
【讨论】:
我自己写的:
public static String join(Collection<String> col, String delim) {
StringBuilder sb = new StringBuilder();
Iterator<String> iter = col.iterator();
if (iter.hasNext())
sb.append(iter.next().toString());
while (iter.hasNext()) {
sb.append(delim);
sb.append(iter.next().toString());
}
return sb.toString();
}
但是JSP不支持Collection,所以对于标签功能我写了:
public static String join(List<?> list, String delim) {
int len = list.size();
if (len == 0)
return "";
StringBuilder sb = new StringBuilder(list.get(0).toString());
for (int i = 1; i < len; i++) {
sb.append(delim);
sb.append(list.get(i).toString());
}
return sb.toString();
}
并放入.tld文件:
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
<function>
<name>join</name>
<function-class>com.core.util.ReportUtil</function-class>
<function-signature>java.lang.String join(java.util.List, java.lang.String)</function-signature>
</function>
</taglib>
并在 JSP 文件中将其用作:
<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}
【讨论】:
TextUtils.join 在 Android 上可用
【讨论】:
ArrayList<Double> j=new ArrayList<>;
j.add(1);
j.add(.92);
j.add(3);
String ntop=j.toString(); //ntop= "[1, 0.92, 3]"
所以基本上,String ntop 用逗号分隔符和方括号存储整个集合的值。
【讨论】:
从 Java 8 开始,join() 现在可用作 String 类的两个类方法。在这两种情况下,第一个参数都是分隔符。
你可以pass individual CharSequences as additional arguments:
String joined = String.join(", ", "Antimony", "Arsenic", "Aluminum", "Selenium");
// "Antimony, Arsenic, Alumninum, Selenium"
或者你可以pass an Iterable<? extends CharSequence>:
List<String> strings = new LinkedList<String>();
strings.add("EX");
strings.add("TER");
strings.add("MIN");
strings.add("ATE");
String joined = String.join("-", strings);
// "EX-TER-MIN-ATE"
Java 8 还添加了一个新类 StringJoiner,您可以像这样使用它:
StringJoiner joiner = new StringJoiner("&");
joiner.add("x=9");
joiner.add("y=5667.7");
joiner.add("z=-33.0");
String joined = joiner.toString();
// "x=9&y=5667.7&z=-33.0"
【讨论】:
我不想导入整个 Apache 库来添加简单的连接函数,所以这是我的 hack。
public String join(String delim, List<String> destinations) {
StringBuilder sb = new StringBuilder();
int delimLength = delim.length();
for (String s: destinations) {
sb.append(s);
sb.append(delim);
}
// we have appended the delimiter to the end
// in the previous for-loop. Let's now remove it.
if (sb.length() >= delimLength) {
return sb.substring(0, sb.length() - delimLength);
} else {
return sb.toString();
}
}
【讨论】:
removeCharAt 不存在,整个函数不再返回字符串...将解决此问题。
这是一个非常简单的答案。使用+=,因为它的代码更少,让优化器为您将其转换为StringBuilder。使用这种方法,您不必在循环中执行任何“最后一次”检查(性能改进),并且您不必担心在末尾剥离任何分隔符。
Iterator<String> iter = args.iterator();
output += iter.hasNext() ? iter.next() : "";
while (iter.hasNext()) {
output += "," + iter.next();
}
【讨论】:
MessageFormat.format() 与 C# 的 String.Format() 类似。
【讨论】:
我在这里看到了很多过于复杂的 String.Join 实现。如果您没有 Java 1.8,并且不想导入新库,则以下实现就足够了。
public String join(Collection<String> col, String delim) {
StringBuilder sb = new StringBuilder();
for ( String s : col ) {
if ( sb.length() != 0 ) sb.append(delim);
sb.append(s);
}
return sb.toString();
}
【讨论】: