2009-05-21 13 views
1

Ich bin ein Neuling, ich habe eine Frage.Java Iterator

Ich habe eine Karte. Ich muss die Karte durchlaufen und den Iterator erstellen.

Beispiel:

public Iterable<Test> getTests(Map<String, Test> testMap, 
    Set<String> strings) 
{ 
    //loop tru the set of strings and build iterator. 
    for(final String test1 : strings) 
    { 

     Test test = testMap.get(test1); 

     //build a iterator. not a list. 
    } 

    return iterator 
} 

Wie kann ich das tun?

+0

Können Sie das nur ein wenig verdeutlichen? – user101884

+0

Ihre Frage besagt, dass Sie einen Iterator erstellen möchten, aber der Rückgabewert von getTests() gibt ein Iterable zurück. Welches ist es? Und können Sie genau angeben, was das erwartete Verhalten des Iterierens über den von getTests() zurückgegebenen Wert ist? – NamshubWriter

Antwort

2

Da Collection erweitert Iterable, die richtige Lösung wäre, die Tests zu einer Art von Sammlung hinzufügen, wie ein ArrayList.

Collection<Test> tests = new ArrayList<Test>(); 
for (String key : strings) { 
    Test t = testMap.get(key); 
    if (t != null) 
    tests.add(t); 
} 
return tests; 
6

Zunächst einmal ist Ihre Methode eine Iterable Rückkehr, kein Iterator. Map, Set und List implementieren alle Iterable, so könnte es einfacher sein als Sie denken.

Zweitens ist eine Iterable nur eine Klasse, die eine iterator()-Methode hat, die eine Iterator zurückgibt.

Also würde ich einfach eine List der Ergebnisse erstellen und dann zurückgeben. Wenn Sie wirklich eine Iterator zurückgeben möchten, würde ich stattdessen iterator() auf der Liste aufrufen und die zurückgeben.

+0

'Map' implementiert' Iterable' nicht. –

0

Ein Iterable ist etwas anderes als ein Iterator. Ein Iterable ist etwas, das Sie durchlaufen können, wie eine Liste. Sie verwenden dafür einen Iterator. Ihre Fragen sind nicht klar, was Sie von getTests() zurückgeben möchten.

Ihre beste Aufnahme wäre, ein Iterable (wie eine Liste oder ein Vektor) zu erstellen und das zurückzugeben oder seinen Iterator zurückzugeben.

3

Skipping über Ihre Iterator/Iterable Verwirrung (und Iterable ist im Grunde ein Iterator Fabrik ..., so dass Sie einen Iterator oder so schreiben müssen), ich glaube, Sie so etwas wie dies bedeuten:

Iterator<Test> getTests(final Map<String,Test> testMap, final Set<String> strings) { 
    return new Iterator<Test>() { 
     private final Iterator<String> keyIter = strings.iterator(); 
     private String lastKey; 
     public boolean hasNext() { return keyIter.hasNext(); } 
     public Test next() { lastKey = keyIter.next(); return testMap.get(lastKey); } 
     public void remove() { testMap.remove(lastKey); } 
    }; 
    } 

Und wenn Sie wollen ein Iterable zurückzukehren, na ja, das hat nur eine Fabrik für die sein:

Iterable<Test> getTests(final Map<String,Test> testMap, final Set<String> strings) { 
    return new Iterable<Test>() { 
     public Iterator<Test> iterator() { 
      return new Iterator<Test>() { 
       private final Iterator<String> keyIter = strings.iterator(); 
       private String lastKey; 
       public boolean hasNext() { return keyIter.hasNext(); } 
       public Test next() { lastKey = keyIter.next(); return testMap.get(lastKey); } 
       public void remove() { testMap.remove(lastKey); } 
       }; 
     } 
    }; 
} 

für zusätzliche Kredite, können Sie diese Methode selbst parametrisieren und eine generische Art und Weise über eine Auswahl von Iterieren von einer Karte haben:

Map<String, Action> map; 
Set<String> keys; 
for (Action x : filterMap(map, keys)) { 
} 
+0

Der faule Iterator Weg ... Ich dachte daran, aber war zu faul, um es tatsächlich zu schreiben. : P –

+0

remove() sollte wahrscheinlich den Test von der Karte entfernen (entweder das oder die UnsupportedOperationException werfen). Es sollte das übergebene Set nicht ändern. In der Tat sollten Sie fast sicher eine Kopie des übergebenen Sets machen. – NamshubWriter

+0

Ja, ich habe versucht, zu clever zu werden und hätte wahrscheinlich nicht versuchen sollen, remove() zu unterstützen. Ich denke, es ist fair zu kopieren kopiert die übergebene als die Verantwortung des Anrufers. Ohne zu wissen, wie dies tatsächlich verwendet wird, ist es schwer zu sagen, aber wenn die Ergebnisse nur verwendet werden, um schnell einmal über die Karte zu schleifen, dann ist das Duplizieren der Schlüssel übertrieben. – araqnid

1

Wenn Sie wirklich wollen, Iterable einfachste Weg zurückzukehren ist diese

public Iterable<Test> getTests(Map<String, Test> testMap, Set<String> strings) 
{ 
    testMap = new HashMap<String, Test>(testMap); 
    testMap.keySet().retainAll(strings); 
    return testMap.values(); 
} 

Wenn Sie einen Iterator zurückwechseln wollen, mit

return testMap.values().iterator(); 

die letzte Zeile ersetzen Wenn Sie kümmern sich nicht Über Änderungen an der übergebenen Karte überspringen Sie die anfängliche temporäre Kartenkonstruktion.

EDIT: entfernt Verwendung von Klon auf der Map-Schnittstelle, die es nicht hat.

+0

Karte hat keine öffentliche clone() -Methode, oder? –

+0

Die Map-Schnittstelle verlangt nicht, dass sie klonbar ist. Angenommen, die übergebene testMap hat einen öffentlichen Klon() ist nicht sicher. –

1

Als Stich im Dunkeln, was Sie suchen können, ist Map.entrySet.iterator(). Es ermöglicht Ihnen, über die Einträge der Karte zu iterieren.

Hinweis: Ich weiß, dass dies keine Antwort auf die Frage des OP ist, aber es ist meine Vermutung zu beantworten, wonach sie eigentlich suchen. Wenn sich diese Vermutung als falsch herausstellt, lösche ich diese Antwort erneut, um den Leuten die Verwirrung zu ersparen.