【问题标题】:Java custom arrayMerge functionJava自定义arrayMerge函数
【发布时间】:2011-10-23 19:44:53
【问题描述】:

我正在尝试使用我在 Google 上找到的这个自定义函数来合并 2 个 int 数组:

public static <T> T[] arrayMerge(T[]... arrays)
{
    int count = 0;
    for (T[] array : arrays) count += array.length;

    T[] mergedArray = (T[]) Array.newInstance(arrays[0][0].getClass(),count);
    int start = 0;
    for (T[] array : arrays) {
        System.arraycopy(array, 0, mergedArray, start, array.length);
        start += array.length;
    }
    return (T[]) mergedArray;
}

但我不明白这个函数需要什么参数。我希望它会像 arrayMerge(int[], int[]) 一样工作,但 Eclipse 告诉我它不接受这些参数。 我无法通过 Google 大写 T 找到答案。

您可以在表格或阅读材料中回答,但是使用此函数合并 2 个 int 数组的示例会很好(它是否消除了重复,如果没有,我该如何实现?)。

【问题讨论】:

  • 您可以通过使用Arrays.copyOf() 来避免相当丑陋(也很危险)的arrays[0][0],如a previous answer from me 所示。 arrays[0][0] 的问题有两个:第一个数组 可能 为空,在这种情况下您会得到一个 ArrayIndexOutOfBoundsException 并且第一个元素可能不是数组的类型 (例如,它可以是Object[] 中的Integer),甚至可以是null

标签: java arrays merge


【解决方案1】:

该方法接受任意数量的数组,它们都具有相同的类型:

String[] array1 = ... ;
String[] array2 = ... ;
String[] array3 = ... ;
String[] mergedArray = ArrayHelper.arrayMerge(array1, array2, array3);

但是,由于泛型在 Java 中的工作方式,您不能传递原始类型的数组(例如 int[])。

【讨论】:

  • 那我怎么会得到:Main类型中的方法arrayMerge(T[]...)不适用于参数(int[],int[])
  • 因为泛型不适用于原始类型。即使用作数组元素。 T 只能代表类型,可以赋值给 Object 无需转换(如装箱)
  • @Dirk:这些通常被称为“引用类型”。
  • @joachim - 我试图避免使用这些术语(但完全失败了 - “泛型”、“拳击”),但还是谢谢 :-)
  • @Dirk:我是这么认为的,实际上我的评论也是针对 user781655 的。只是想把这个词放在那里。
【解决方案2】:

您在此处发布的代码适用于任何类型的数组,不仅适用于 int,还适用于要合并的 2 个以上的数组。 (无限制)
T 代表通用类型。见Generics in Java

您只能使用System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

  • src 源数组。
  • srcPos 源数组中的起始位置。
  • dest 目标数组。
  • destPos 目标数据中的起始位置。
  • length 要复制的数组元素的数量。

首先创建一个数组,它的长度与两个数组的长度相同。

public merge(int[] x, int[] y) {

    int[] merged = new int[x.length + y.length]

比使用System.arraycopy 将第一个数组x 复制到merged 0
并用System.arraycopy将第二个数组y复制到mergedx.length

但是它不会消除重复。

如果没有重复,您可以使用Set。但是我们必须使用Integer 而不是int
所以我们必须转换成Integer 再转换成int。喜欢:

HashSet<Integer> set = new HashSet<Integer>();
for( int i : x ) {
    set.add( Integer.valueOf( i ) );
}
for( int i : y ) {
    set.add( Integer.valueOf( i ) );
}
int[] merged = new int[set.size()];
int i = 0;
for( Integer value : set ) {
    merged[i++] = value.intValue();
}

【讨论】:

    【解决方案3】:

    该语法称为varargs - 这意味着它将接受该类型的任意数量的参数。去掉泛型来简单解释,方法定义如下:

    public static void someMethod(int... numbers) {
        // some code
    }
    

    可以这样调用:

    someMethod(5); // The "numbers" parameter will be an int array size 1: [5]
    someMethod(1,2,3); // The "numbers" parameter will be an int array size 3: [1, 2, 3]
    someMethod(); // The "numbers" parameter will be an int array size 0: []
    

    这就像一个简写:

    someMethod(new int[] {1, 2, 3});
    

    但不那么丑。

    在您的示例中,数组是一个类型化的泛型数组 - 在调用它之前您不知道元素类型是什么。

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 2018-08-16
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多