使方法泛型于 CharSequence[] 和 Set<String>



我正在尝试将方法转换为CharSequence[]和Set的通用方法。我在这方面没有经验。

这个方法的第二个参数/返回值应该是泛型的(T)。这可能吗?

private CharSequence[] remove(String string, CharSequence[] charSequences)
    {
        ArrayList<CharSequence> newArray = new ArrayList<CharSequence>();
        int foundPlace = -1;
        CharSequence[] v = charSequences;
        for (int i = 0; i < v.length; i++) {
            if (foundPlace != -1 && v[i].equals(string))
                foundPlace = i;
            else
                newArray.add(v[i]);
        }
        return newArray.toArray(new CharSequence[newArray.size()]);
    }

我试过了。替换所有CharSequence[]出现在T的地方,但当我将T放在T.length行时它不起作用。


更多说明(抱歉)。我想转换第二个参数并返回值为T -所以到处都是CharSequence[]到T

也许这就是你想要的:

private <T> T[] remove(T string, T[] charSequences)
    {
        ArrayList<T> newArray = new ArrayList<T>();
        int foundPlace = -1;
        T[] v = charSequences;
        for (int i = 0; i < v.length; i++) {
            if (foundPlace != -1 && v[i].equals(string))
                foundPlace = i;
            else
                newArray.add(v[i]);
        }
        @SuppressWarnings("unchecked")
        T[] ret = (T[]) Array.newInstance(v.getClass().getComponentType(), newArray.size());
        return newArray.toArray(ret);
    }

或者,如果包含类也是T类型的泛型,则从上面删除<T>。这一行

private <T> T[] remove(T string, T[] charSequences)

将变成

private T[] remove(T string, T[] charSequences)

如果string的类型无关紧要,您可以将其类型更改为普通的Object

private T[] remove(Object string, T[] charSequences)
    {
        ArrayList<T> newArray = new ArrayList<T>();
        int foundPlace = -1;
        T[] v = charSequences;
        for (int i = 0; i < v.length; i++) {
            if (foundPlace != -1 && v[i].equals(string))
                foundPlace = i;
            else
                newArray.add(v[i]);
        }
        ...
    }

您可能还希望将string重命名为其他名称。


我还应该注意,在您的逻辑中,foundPlace将始终是-1

  • 你使用一个整数的foundPlace,但布尔值是足够的,因为你只是测试它是否已经初始化,从不使用它的值。
  • 你甚至不需要这个布尔值,你的equals测试永远不会被评估,因为foundPlace总是等于-1(所以你返回的数组总是charSequences的副本)
  • 你不需要一个中间变量v,你可以简单地迭代charSequences

这是一个带有Object的版本,如果它是你正在寻找的:

private Object[] remove(Object val, Object[] array)
    {
        ArrayList<Object> newArray = new ArrayList<Object>();
        for (Object o : array)
            if(!o.equals(val))
                newArray.add(o);
        return newArray.toArray(new Object[newArray.size()]);
}

泛型和数组的组合可能是相当痛苦的。我会坚持列表界面,如果这是一个选项,你(即。将返回类型更改为List,并简单地返回newArray(也是List类型)。

否则,我推荐这篇文章来更好地理解泛型和数组:如何在Java中创建一个通用数组?

编辑:哦,你绝对不想用"T"替换"CharSequence[]",但如果你真的需要在这里使用数组,可能会用"T[]"。

要实现泛型集合,请使用:

int length; // ...
T[] array = (T[])new Object[length];

那么,返回语句将是这样的:

return (T[])newArray.toArray(new Object[newArray.size()]);

下面是实现remove例程的方法。注意,您甚至不需要单独的remove方法。我希望,我没有错过需要您创建单独的remove方法的用例。

package com.anupam;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class SO31535852 {
  public static void main(String args[]) {
    String[] arr = {"1", "2", "3"};
    // Create a copy of the orginal array if you do not want to modify it.
    Set<String> test = new HashSet<>(Arrays.asList(Arrays.copyOf(arr, arr.length)));
    // In fact you do not even need a remove method. I could not understand why you are using
    // foundPlace variable it's not doing much.
    System.out.println(remove("1", test));
    System.out.println(remove("1", test));
  }
  /**
   * Removes a specific value from the underling collection
   *
   * @param toRemove the object to be removed
   * @param myCollection the colelction from which to be removed
   * @return the removed value or null.
   */
  private static <T> T remove(T toRemove, Set<T> myCollection) {
    return myCollection.remove(toRemove) ? toRemove : null;
  }
}

最新更新