我需要在Java中连接两个字符串数组。
void f(String[] first, String[] second) {
String[] both = ???
}
哪种方法最简单?
我需要在Java中连接两个字符串数组。
void f(String[] first, String[] second) {
String[] both = ???
}
哪种方法最简单?
当前回答
在Haskell中,您可以执行类似[a,b,c]++[d,e]的操作来获得[a,b,c,d,e]。这些是连接起来的Haskell列表,但很高兴看到Java中的类似运算符用于数组。你不这么认为吗?这是优雅、简单、通用的,而且实现起来并不那么困难。
如果你愿意,我建议你看看Alexander Hristov在破解OpenJDK编译器方面的工作。他解释了如何修改javac源代码以创建新的运算符。他的示例包括定义一个'**'运算符,其中i**j=Math.pow(i,j)。我们可以用这个例子来实现一个连接两个相同类型数组的运算符。
这样做之后,您就绑定到定制的javac来编译代码,但是任何JVM都可以理解生成的字节码。当然,您可以在源代码级别实现自己的数组连接方法,其他答案中有很多关于如何实现的示例!有这么多有用的运算符可以添加,这一个将是其中之一。
其他回答
我最近一直在与过度的记忆循环作斗争。如果已知a和/或b通常是空的,这里是silvertab代码的另一种修改(也被通用化):
private static <T> T[] concatOrReturnSame(T[] a, T[] b) {
final int alen = a.length;
final int blen = b.length;
if (alen == 0) {
return b;
}
if (blen == 0) {
return a;
}
final T[] result = (T[]) java.lang.reflect.Array.
newInstance(a.getClass().getComponentType(), alen + blen);
System.arraycopy(a, 0, result, 0, alen);
System.arraycopy(b, 0, result, alen, blen);
return result;
}
编辑:这篇文章的前一个版本指出,像这样的数组重用应该清楚地记录下来。正如Maarten在评论中指出的那样,一般来说,最好删除if语句,这样就不需要文档了。但话说回来,那些if语句首先就是这个特定优化的要点。我会在这里留下这个答案,但要小心!
您可以尝试将其转换为ArrayList,然后使用addAll方法将其转换回数组。
List list = new ArrayList(Arrays.asList(first));
list.addAll(Arrays.asList(second));
String[] both = list.toArray();
这里是silvertab编写的伪代码解决方案的工作代码中的一个可能实现。
谢谢silvertab!
public class Array {
public static <T> T[] concat(T[] a, T[] b, ArrayBuilderI<T> builder) {
T[] c = builder.build(a.length + b.length);
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
return c;
}
}
接下来是构建器界面。
注意:构建器是必要的,因为在java中不可能这样做
新T[尺寸]
由于通用类型擦除:
public interface ArrayBuilderI<T> {
public T[] build(int size);
}
这里是一个实现接口的具体构建器,构建一个整数数组:
public class IntegerArrayBuilder implements ArrayBuilderI<Integer> {
@Override
public Integer[] build(int size) {
return new Integer[size];
}
}
最后是应用程序/测试:
@Test
public class ArrayTest {
public void array_concatenation() {
Integer a[] = new Integer[]{0,1};
Integer b[] = new Integer[]{2,3};
Integer c[] = Array.concat(a, b, new IntegerArrayBuilder());
assertEquals(4, c.length);
assertEquals(0, (int)c[0]);
assertEquals(1, (int)c[1]);
assertEquals(2, (int)c[2]);
assertEquals(3, (int)c[3]);
}
}
允许连接多个阵列的简单变体:
public static String[] join(String[]...arrays) {
final List<String> output = new ArrayList<String>();
for(String[] array : arrays) {
output.addAll(Arrays.asList(array));
}
return output.toArray(new String[output.size()]);
}
一个与类型无关的变体(已更新-感谢Volley实例化T):
@SuppressWarnings("unchecked")
public static <T> T[] join(T[]...arrays) {
final List<T> output = new ArrayList<T>();
for(T[] array : arrays) {
output.addAll(Arrays.asList(array));
}
return output.toArray((T[])Array.newInstance(
arrays[0].getClass().getComponentType(), output.size()));
}