2016-05-03 15 views
5

So arbeite ich an einer Breathth-First-Suchfunktion für ein Programm, das ich für die Schule bearbeite, und wenn ich durch die ausgehenden Kanten für einen bestimmten Knoten gehe, aufgrund dessen, wie ich durch meine möglichen Kanten gehe , sieht es so etwas wie dieses:Wie kann ich eine ArrayList <ArrayList <String>> sortieren?

[[A, 1], [D, 1], [C, 2], [D, 2]] 

Aber was ich wirklich will, ist dies:

[[A, 1], [C, 2], [D, 1], [D, 2]] 

Wo der erste Index eines Paares der Name des Knotens ist, dass die Randpunkte zu, und die Der zweite Index ist die Bezeichnung für die Kante. Im Wesentlichen möchte ich diese Kanten alphabetisch durchlaufen, zuerst nach Knotennamen, dann nach Markennamen, aber ich bin nicht sicher, wie das geht, da Collections.sort() nicht für eine 2D-ArrayList funktioniert. Irgendwelche Hinweise/Ideen auf eine gute Methode, um das zu sortieren? Danke allen!

EDIT: Ich bin mit JRE 1.7 für diese Zuordnung nicht 1,8

+0

'[[A 1], [D, 1], [C, 2], [D, 2]] 'ist kein gültiges Beispiel für' ArrayList

+0

Sie könnten eine HashMap anstelle einer ArrayList verwenden ... – RoiEX

+1

RoiEX, konnte HashMap nicht verwenden, da er einen Key haben kann, der verschiedene Werte hat oder eine HashMap sein muss ... das macht eine ziemlich komplizierte Struktur für etwas Einfaches. – jeorfevre

Antwort

2

hier ist der komplette Arbeitscode. Arbeiten mit Lambda-Ausdruck in Java SDK8.

Wie Sie sehen werden, habe ich eine einfache Klasse und einen Komparator hinzugefügt. Dies ist einfach und leistungsstark.

package com.rizze.test.labs.sof; 

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List; 

import org.junit.Test; 

public class SOF {  

    public static class Link { 
     public String name; 
     public int id; 

     public static Link build(String n, int i){ 
      Link l = new Link(); 
      l.name = n; 
      l.id=i; 
      return l; 
     } 

     public String toString(){ 
      return String.format("[%s , %d]", name,id); 
     }   
    }  

    @Test 
    public void test() { 

     List<Link> links = new ArrayList<Link>(); 

     //SSETUP [[A, 1], [C, 2], [D, 1], [D, 2]] 
     links.add(Link.build("D", 1)); 
     links.add(Link.build("A", 1)); 
     links.add(Link.build("D", 2)); 
     links.add(Link.build("C", 2)); 


     Collections.sort(links, new Comparator<Link>() {  
      @Override 
      public int compare(Link p1, Link p2) { 
       int ret = p1.name.compareTo(p2.name); 
       if(ret == 0) { 
        ret= p1.id - p2.id; 
       } 
       return ret;    
      }    
     }); 
     System.out.println(links);   
    }  
} 

// Konsolenausgabe

Before : [[D , 1], [A , 1], [D , 2], [C , 2]] 
Sorted: [[A , 1], [C , 2], [D , 1], [D , 2]] 

// GIST Link https://gist.github.com/jeorfevre/cbcd7dac5d7fabde6a16db83bdfb7ef5

2

@jeorfevre Antwort ist vollkommen ok. Sie haben die Version von Java nicht erwähnt, aber ich würde mit den statischen Methoden Comparator gehen.

wird die Lösung deklarative und Ihnen in einer prägnanten Art und Weise mehr Kontrolle und Klarheit geben: Gibt Ihnen

  Comparator<Edge> comparator = Comparator 
       .comparing(Edge::getName) 
       .thenComparing(Edge::getLabel) 
       .reversed(); 

:

public class Test { 
    public static class Edge { 
     private String name; 
     private int label; 
     public Edge(String name, int id) { 
      this.name = name; 
      this.label = id; 
     } 
     public String toString() { 
      return String.format("[%s , %d]", name, label); 
     } 
     public String getName() { return name; } 
     public int getLabel() { return label; } 
    } 


    public static void main(String[] args) { 
     List<Edge> edges = new ArrayList<>(); 
     edges.add(new Edge("D", 1)); 
     edges.add(new Edge("A", 1)); 
     edges.add(new Edge("D", 2)); 
     edges.add(new Edge("C", 2)); 

     Comparator<Edge> comparator = Comparator 
       .comparing(Edge::getName) 
       .thenComparing(Edge::getLabel); 

     edges.sort(comparator); 

     System.out.println(edges); 
    } 
} 

Wenn Sie umgekehrte Reihenfolge wollen

[[D , 2], [D , 1], [C , 2], [A , 1]] 

Und

  Comparator<Edge> comparator = Comparator 
       .comparing(Edge::getName) 
       .reversed() 
       .thenComparing(Edge::getLabel); 

Ausgabe ist: [[D, 1], [D, 2], [C 2], [A, 1]]

+0

Das sieht gut aus! Es ist ziemlich genau das, was ich über die Implementierung (Edge-Klasse) dachte und es gibt mir ein wenig mehr Perspektive darüber, wie ich meine Kanten verwalten soll. Meine nächste Frage ist, da ich mit diesen Kanten nicht innerhalb einer Edge-Klasse arbeite, sondern in einer ganz anderen Klasse, wo würde ich den Komparator setzen? Würde es in die Funktion passen, mit der ich gerade arbeite?Entschuldigung, ich bin relativ neu in Java und sehr neu für Komparatoren. –

+0

Außerdem habe ich ein Problem mit den Befehlen Edge :: getName und Edge :: getLabel, weil mein Professor für diese Aufgabe möchte, dass wir JRE 1.7 und nicht 1.8 verwenden. Gibt es eine andere Möglichkeit, dies mit JRE 1.7 zu implementieren? –

Verwandte Themen