按类型参数排序泛型类的对象

时间:2013-05-23 11:28:55

标签: java generics

我创建了一个非常简单的泛型类,它存储了相同类型的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是一个私有方法,用于检查这对夫妇是否已经在输出列表中,我已尝试在Comparable上实现MyClass,但编码更加复杂。< / p>

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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列表作为输入,并将具有相同类型的couple的MyClass列表作为输出。

包含上述代码的类 not 需要是通用的,因此match方法可以使用T的隐式规范调用,就像你在做什么一样我需要知道T或指定它,事实上,如果愿意,您只需在matchList<Object>(遗留代码)上致电List即可。唯一的限制是,当您在List<Match<K>>上调用match时,您将获得的回复列表为List<K>,但这是件好事 - 泛型适用于此处。< / p>

您甚至可以通过对谓词参数进行操作来自定义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;
}

作为最终建议,请避免忽略泛型类的类型参数 - 这是为遗留代码保留的实践,否则可能表明代码存在逻辑问题。这是最简单的事情 - 在任何地方放置Object?,但在大多数情况下,最好尝试为这些通用规范找到真正的匹配类型。