Java模板问题

时间:2010-07-01 17:11:03

标签: java generics function

我已经实例化了一个像这样的对象:

GraphMatrixDirected<String, Integer> g

g传递给这样的函数:

floyd(g);

floyd的签名如下:

public void floyd(GraphMatrixDirected<V,E> g) 

Eclipse给我一个错误说:

The method floyd(GraphMatrixDirected<V,E>) in the type GraphMatrix<V,E> is not applicable for the arguments (GraphMatrixDirected<String,Integer>)

我需要做些什么来解决它?

Edit1:

abstract public class GraphMatrix<V,E> extends AbstractStructure<V> implements Graph<V,E>

EDIT2:

public interface Graph<V,E> extends Structure<V>

public abstract class AbstractStructure<E> implements Structure<E>

public interface Structure<E> extends Iterable<E>
/* JDT added extension of Iterable for Java 5 */

编辑3: 注意:功能已从floyd更改为AllPairsShortestPath

public void AllPairsShortestPath(GraphMatrixDirected<V,E> g) 
// post: g contains edge (a,b) if there is a path from a to b 
{
    Iterator<V> witer = g.iterator();
    while (witer.hasNext()) 
    {
        Iterator<V> uiter = g.iterator();
        V w = witer.next(); 

        while (uiter.hasNext())
        {
            Iterator<V> viter = g.iterator(); 
            V u = uiter.next(); 

            while (viter.hasNext()) 
            {
                V v = viter.next(); 

                if (g.containsEdge(u,w) && g.containsEdge(w,v)) 
                {
                    Edge<V,E> leg1 = g.getEdge(u,w);
                    Edge<V,E> leg2 = g.getEdge(w,v); 

                    Integer leg1Dist = (Integer)leg1.label(); 
                    Integer leg2Dist = (Integer)leg2.label(); 
                    Integer newDist = (Integer)leg1Dist+leg2Dist;

                    E newDistE = (E)newDist;

                    if (g.containsEdge(u,v)) 
                    {
                        Edge<V,E> across = g.getEdge(u,v);
                        Integer acrossDist = (Integer)across.label(); 

                        if (newDist < acrossDist)
                        {
                            across.setLabel(newDistE);
                        } 
                    } 
                    else 
                    {
                        g.addEdge(u,v,newDistE);
                    }
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:3)

尝试

public <V, E> void floyd(GraphMatrixDirected<V,E> g) 

(这应该也是静态的)。

否则,我们必须看看如何创建包含此方法的对象,特别是您为V和E分配的类型(如果V是String,E是Integer,它可以工作,但显然不是)。

我知道你有类似

的东西
class GraphMatrixDirected<V,E> extends GraphMatrix<V,E> { ... }

然后你可以保留方法签名(实际上如果它是在GraphMatrixDirected中定义的,它是一个实例方法,你可能不想要另一个GraphMatrixDirected参数,但只是使用this),然后使用:

GraphMatrixDirected<String, Integer> g = new GraphMatrixDirected<String, Integer>();

请注意,我并不赞同这种设计,但这已经超出了这一点。

答案 1 :(得分:3)

也许您认为floyd是一种通用方法?

public <V,E> void floyd(GraphMatrixDirected<V,E> g)

否则,无论泛型类型floyd是否需要将<V,E>参数化为<String,Integer>

如果floyd属于泛型类型,但floyd也需要是具有自己的类型参数的泛型方法,那么您可能需要选择不同的名称,以免彼此隐藏。

参考


关于泛型类型与泛型方法

选择哪种解决方案路线取决于floyd做什么和其他事情。一个基本问题是:您认为floyd是一个专门属于泛型类型GraphMatrixDirected<V,E>的方法(答案可能是否)或者它是一个适用于任何{{{}的通用实用方法1}? (答案可能是肯定的。)

例如和指导,我们还可以看看Java Collections Framework的结构:

  • interface List<E> - 定义类型基本功能的泛型类型
    • 指定Graph<V,E>boolean add(E e)
  • class Collections - 提供E get(int index)实用程序通用方法
    • static
    • static void shuffle(List<?> list) static <T extends Comparable<? super T>>
    • void sort(List<T> list) static <T extends Object & Comparable<? super T>>

假设T max(Collection<? extends T> coll)确实是Floyd-Warshall all-pairs shortest path algorithm的实现,我认为它应该是floyd实用方法来说static类,并且可以使用任何Graphs

另请参阅 Effective Java 2nd Edition

通用类型与方法:

  • 第26项,偏好通用类型
  • 第27项,赞成通用方法

接口:

  • 第18项,首选接口为抽象类
  • 第19项,仅使用界面来定义类型
  • 第52项,通过界面引用对象