Domanda

Voglio usare un PriorityQueue per fare una sorta topologico su un grafico. Per brevità, mi piacerebbe utilizzare una classe interna anonima per il comparatore. Tuttavia, ho bisogno di accedere al g grafico al fine di determinare il grado in dei nodi che sto guardando. È possibile?

    /**
 * topological sort 
 * @param g must be a dag
 */
public static Queue<String> topoSort(DirectedGraph<String, DefaultEdge> g) {
    Queue<String> result = new PriorityQueue<String>(g.vertexSet().size(), 
            new Comparator<String>() {

                DirectedGraph<String, DefaultEdge> g;

                @Override
                public int compare(String arg0, String arg1) {
                    if (g.inDegreeOf(arg0) < g.inDegreeOf(arg1)) {
                        return -1;
                    }
                    if (g.inDegreeOf(arg0) > g.inDegreeOf(arg1)) {
                        return 1;
                    }
                    return 0;
                }
    });

    result.addAll(g.vertexSet());

    return result;
}

CORRETTO CODICE

/**
 * topological sort 
 * @param g must be a dag
 */
public static Queue<String> topoSort(final DirectedGraph<String, DefaultEdge> g) {
    Queue<String> result = new PriorityQueue<String>(g.vertexSet().size(), 
            new Comparator<String>() {          
                @Override
                public int compare(String arg0, String arg1) {
                    if (g.inDegreeOf(arg0) < g.inDegreeOf(arg1)) {
                        return -1;
                    }
                    if (g.inDegreeOf(arg0) > g.inDegreeOf(arg1)) {
                        return 1;
                    }
                    return 0;
                }
    });

    result.addAll(g.vertexSet());

    return result;
}
È stato utile?

Soluzione

Sì, lo rendono finale:

public static Queue<String> topoSort(final DirectedGraph<String, DefaultEdge> g) {

La parola finale sul finale di parola chiave :

  

anonimi Classi locali

     

La seconda situazione coinvolge finale   variabili è in realtà incaricati dalla   semantica del linguaggio. In tale situazione,   il compilatore Java non ti consente di utilizzare un   variabile a meno che non viene dichiarata finale.   Questa situazione si verifica con chiusure,   noto anche come classi locali anonime.   classi locali possono solo riferimento locale   variabili e parametri che sono   dichiarato finale.

public void doSomething(int i, int j)
{
  final int n = i + j; // must be declared final

  Comparator comp = new Comparator()
  {
    public int compare(Object left, Object right)
    {
      return n; // return copy of a local variable
    }
  };
} 
     

La ragione di questa restrizione   diventa evidente se far luce   su come le classi locali sono implementati.   Una classe locale anonimo può utilizzare locali   variabili perché il compilatore   dà automaticamente la classe di un   campo di istanza privata di tenere una copia   di ogni variabile locale la classe utilizza.   Il compilatore aggiunge anche nascosto   parametri di ogni costruttore   inizializzare questi creati automaticamente   campi privati. Così, una classe locale   in realtà non l'accesso locale   variabili, ma semplicemente il proprio privato   copie di essi. L'unico modo questo può   il lavoro è correttamente se il locale   variabili sono dichiarate finale, in modo che   sono garantiti di non cambiare.   Con questa garanzia in atto, il   classe locale è assicurato che la sua   copie interne delle variabili   corrispondere esattamente locale attuale   variabili.

Altri suggerimenti

Se una variabile locale viene utilizzato in una classe interna, il compilatore genera un campo istanza per la classe interna e copia il valore variabili locali ad esso. Ora, se i cambiamenti delle variabili locali, allora il valore della variabile instancs saranno ancora avendo vecchio valore. Così, al fine di rendere il valore delle variabili locali stesso campo di istanza e non mutabile, si è fatto finale.

Cordiali saluti, con google collezioni si ha anche la possibilità di

  Ordering.natural().onResultOf(
      new Function<String, Integer>() {
        public Integer apply(String arg) {
          return g.inDegreeOf(arg);
        }
      });

Questo non significa necessariamente risparmiare un sacco di battitura, come si può vedere, a meno che non si possono trovare altri usi per quella funzione, ma lo fa si proteggere dagli insetti che molto spesso si insinuano nelle vostre by-mano implementazioni di confronto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top