0

我制作了一个非常简单的泛型类,它存储了 2 个相同类型的变量,如下所示:

public MyClass<T>
{
    private T v1;
    private T v2;

    public MyClass(T v1, T v2)
    {
      this.v1 = v1;
      this.v2 = v2;
    {
 }

现在我需要通过另一个非泛型类来实现一个方法,该方法将不同类型的 Object 列表作为输入,并给出MyClass<T>具有相同类型的对的列表作为输出。

我的问题是,在不知道我正在使用什么类型的情况下,我无法找到一种方法来制作这样的东西,我如何MyClass每次都实例化正确的类型?我已经走了这么远,没有从日食中得到错误

public List<MyClass<?>> match()
{
    List<MyClass<?>> list = new ArrayList<MyClass<?>>();

    for(Object obj : this.list)//not the same list it's a parameter of the
    {                     //non-generic class
        for(Object obj2 : this.list)
        {
            if(!(obj == obj2)&&obj.getClass().equals(obj2.getClass()))
            {
                MyClass<Object> couple = new MyClass<Object>(obj, obj2);
                insertCouple(couple, list);
            }
        }
    }

insertCouple是检查这对夫妇是否已经在输出列表中的私有方法,我尝试实现ComparableMyClass使编码更加复杂。

如您所见,我被迫保持通用,但我可以看到它存在问题。如果没有在运行时查找和填充特定类型的方法,我如何编写它以使其成为可能通过泛型?

4

2 回答 2

1

根据我在评论中收集到的信息,解决方案是基于谓词从输入列表中构建元素对列表。

class Match<T>
{
    T a, b;

    Match(T a, T b)
    {
        this.a = a;
        this.b = b;
    }
}

<T> List<Match<T>> match(List<T> list)
{
    List<Match<T>> matchList = new ArrayList<Match<T>>();

    for(T a : list)
    {
        for(T b : list)
        {
            if(a != b && a.getClass().equals(b.getClass()))
            {
                matchList.add(new Match<T>(a, b));
            }
        }
    }

    return matchList;
}

我相信我满足了您的要求:

现在我需要通过另一个非泛型类来实现一个方法,该方法将不同类型的 Object 列表作为输入,并将具有相同类型的一对的 MyClass 列表作为输出。

包含上面代码的类不需要是泛型的,因此match可以使用隐式规范调用该方法T,例如,您不需要知道T或指定它,实际上您可以简单地调用matchor List<Object>( Listlegacy code ) 如果你愿意的话。唯一的限制是,您将返回的列表List<Match<K>>在您调用matcha时输入List<K>,但这是一件好事 - 泛型在这里非常适用。

您甚至可以自定义match,方法是让它对谓词参数进行操作:

class Predicate
{
    <T> boolean eval(T a, T b)
    {
        return a != b && a.getClass().equals(b.getClass());
    }
}

<T> List<Match<T>> match(List<T> list, Predicate predicate)
{
    List<Match<T>> matchList = new ArrayList<Match<T>>();

    for(T a : list)
    {
        for(T b : list)
        {
            if(predicate.eval(a, b))
            {
                matchList.add(new Match<T>(a, b));
            }
        }
    }

    return matchList;
}

作为最后的建议,避免省略泛型类的类型参数 - 这是为遗留代码保留的做法,否则可能表明您的代码存在逻辑问题。这是最容易做的事情 - putObject?无处不在,但在大多数情况下,最好尝试为这些通用规范找到真正匹配的类型。

于 2013-05-24T10:54:59.437 回答
1

您无法决定在运行时创建哪种类型的 MyClass 对象(取决于匹配对象的类),因为所有泛型类型在编译时都会被删除。您可以在以下位置阅读有关类型擦除的更多信息:

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

于 2013-05-23T12:09:18.467 回答