Вопрос шаблона Java - PullRequest
       2

Вопрос шаблона Java

1 голос
/ 01 июля 2010

Я создал объект, подобный этому:

GraphMatrixDirected<String, Integer> g

g передается функции, подобной этой:

floyd(g);

подпись Флойда выглядит так:

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>

Правка2:

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 ]

3 голосов
/ 01 июля 2010

Возможно, вы имели в виду floyd как универсальный метод?

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

В противном случае для любого универсального типа floyd необходимо указать значение <V,E> как <String,Integer>.

Если верно, что floyd принадлежит универсальному типу, и все же floyd также должен быть универсальным методом с его собственными параметрами типа, вы можете выбрать другие имена, чтобы не скрывать друг друга.

Ссылки


Об универсальном типе против универсальных методов

Выбор пути решения зависит от того, что делает floyd, и от других вещей. Один важный вопрос заключается в следующем: считаете ли вы floyd методом, относящимся конкретно к универсальному типу GraphMatrixDirected<V,E> (ответ, вероятно, нет), или это скорее универсальный служебный метод, который работает с любым Graph<V,E>? (ответ, вероятно, да).

Например, и руководство, мы также можем взглянуть на структуру Java Collections Framework:

  • interface List<E> - универсальный тип, определяющий основные функциональные возможности для типа
    • указывает boolean add(E e), E get(int index) и т. Д.
  • class Collections - предоставляет 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 действительно является реализацией алгоритма кратчайшего пути для всех пар Флойда-Варшалла , я бы сказал, что это должен быть static служебный метод, чтобы сказать Graphs класс и работает с любым Graph<V,E>.

См. Также, Effective Java 2nd Edition

Общие типы по сравнению с методами:

  • Item 26, Favoric generic types
  • Пункт 27, Универсальные методы Favor

Интерфейсы:

  • Пункт 18, Предпочитать интерфейсы абстрактным классам
  • Item 19, Используйте интерфейсы только для определения типов
  • Item 52, Ссылка на объекты по их интерфейсам
3 голосов
/ 01 июля 2010

Попробуйте

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>();

Обратите внимание, что я не одобряю этот дизайн, но это не имеет смысла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...