it-swarm.com.de

Bestimmte Objekte aus ArrayList abrufen, wenn Objekte anonym hinzugefügt wurden?

Ich habe ein kurzes Beispiel für mein Problem erstellt. Ich erstelle anonym eine Liste von Objekten und füge sie einer ArrayList hinzu. Sobald sich Elemente in der Variablen ArrayList befinden, komme ich später zurück und füge jedem Objekt in der Liste weitere Informationen hinzu. Gibt es eine Möglichkeit, ein bestimmtes Objekt aus der Liste zu extrahieren, wenn Sie dessen Index nicht kennen?

Ich kenne nur den 'Namen' des Objekts, aber Sie können keine list.get(ObjectName) oder irgendetwas tun. Was ist der empfohlene Weg, um damit umzugehen? Ich muss die gesamte Liste nicht jedes Mal durchlaufen, wenn ich ein bestimmtes Objekt abrufen möchte.

public class TestCode{

    public static void main (String args []) {
        Cave cave = new Cave();

        // Loop adds several Parties to the cave's party list
        cave.parties.add(new Party("FirstParty")); // all anonymously added
        cave.parties.add(new Party("SecondParty"));
        cave.parties.add(new Party("ThirdParty"));

        // How do I go about setting the 'index' value of SecondParty for example?
    }
}

class Cave {
    ArrayList<Party> parties = new ArrayList<Party>();
}

class Party extends CaveElement{
    int index;

    public Party(String n){
        name = n;
    }

   // getter and setter methods 

    public String toString () {
        return name;
    }
}


class CaveElement {
    String name = "";
    int index = 0;

    public String toString () {
        return name + "" + index;
    }
}
8
leigero

Bei Verwendung von List gibt es keine Möglichkeit, einen Wert "nachzuschlagen", ohne ihn zu durchlaufen ...

Zum Beispiel...

Cave cave = new Cave();

// Loop adds several Parties to the cave's party list
cave.parties.add(new Party("FirstParty")); // all anonymously added
cave.parties.add(new Party("SecondParty"));
cave.parties.add(new Party("ThirdParty"));

for (Party p : cave.parties) {
    if (p.name.equals("SecondParty") {
        p.index = ...;
        break;
    }
}

Das wird Zeit brauchen. Wenn sich das gesuchte Element am Ende der Liste befindet, müssen Sie bis zum Ende der Liste durchlaufen, bevor Sie eine Übereinstimmung finden.

Es könnte besser sein, eine Map einer Art zu verwenden ...

Also, wenn wir Cave aktualisieren, um wie folgt auszusehen ...

class Cave {
    Map<String, Party> parties = new HashMap<String, Party>(25);
}

Wir könnten so etwas machen ...

Cave cave = new Cave();

// Loop adds several Parties to the cave's party list
cave.parties.put("FirstParty", new Party("FirstParty")); // all anonymously added
cave.parties.put("SecondParty", new Party("SecondParty"));
cave.parties.put("ThirdParty", new Party("ThirdParty"));

if (cave.parties.containsKey("SecondParty")) {
    cave.parties.get("SecondParty").index = ...
}

Stattdessen...

Letztendlich hängt alles davon ab, was Sie erreichen wollen ...

13
MadProgrammer

List.indexOf() gibt Ihnen das, was Sie wollen, vorausgesetzt, Sie wissen genau, was Sie wollen, und vorausgesetzt, dass die equals()-Methode für Party genau definiert ist.

Party searchCandidate = new Party("FirstParty");
int index = cave.parties.indexOf(searchCandidate);

Hier wird es interessant - Unterklassen sollten nicht die privaten Eigenschaften ihrer Eltern untersuchen, daher definieren wir equals() in der Oberklasse.

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (!(o instanceof CaveElement)) {
        return false;
    }

    CaveElement that = (CaveElement) o;

    if (index != that.index) {
        return false;
    }
    if (name != null ? !name.equals(that.name) : that.name != null) {
        return false;
    }

    return true;
}

Es ist auch ratsam, hashCode zu überschreiben, wenn Sie equals überschreiben - der allgemeine Vertrag für hashCode schreibt vor, dass bei x.equals(y)x.hashCode () == y.hashCode () .

@Override
public int hashCode() {
    int result = name != null ? name.hashCode() : 0;
    result = 31 * result + index;
    return result;
}
7
Makoto

Wenn Sie Objekte anhand ihres String-Namens suchen möchten, handelt es sich hierbei um einen Textbuchfall für ein Map, beispielsweise ein HashMap. Sie könnten ein LinkedHashMap verwenden und es später in ein List oder Array umwandeln (Chris hat dies in den folgenden Kommentaren gut behandelt).

LinkedHashMap, weil Sie auf die Elemente in der Reihenfolge zugreifen können, in der Sie sie einfügen, wenn Sie dies wünschen. Ansonsten ist HashMap oder TreeMap ausreichend.

Sie könnten dies mit List zusammenarbeiten lassen, wie die anderen vorschlagen, aber das fühlt sich für Hacky an ... und dies wird sowohl auf kurze als auch auf lange Sicht sauberer sein.

Wenn Sie eine Liste für das Objekt MÜSSEN, MÜSSEN Sie trotzdem ein Map des Objektnamens im Index im Array speichern. Dies ist ein wenig hässlicher, aber Sie erhalten fast die gleiche Leistung wie ein einfaches Map.

5
Karthik T

Sie könnten list.indexOf(Object) bug in aller Ehrlichkeit verwenden, was Sie so beschreiben, als wären Sie mit einer Map besser dran.

Versuche dies:

Map<String, Object> mapOfObjects = new HashMap<String, Object>();
mapOfObjects.put("objectName", object);

Wenn Sie das Objekt später abrufen möchten, verwenden Sie 

mapOfObjects.get("objectName");

Vorausgesetzt, Sie kennen den Namen des Objekts, wie Sie es angegeben haben, wird dies sowohl sauberer als auch schneller sein, vor allem, wenn die Karte eine große Anzahl von Objekten enthält.

Wenn Sie die Objekte in der Map benötigen, um in Ordnung zu bleiben, können Sie verwenden 

Map<String, Object> mapOfObjects = new LinkedHashMap<String, Object>();

stattdessen

2
StormeHawke

Gemäß Ihrer Anforderung möchte ich vorschlagen, dass Map Ihr ​​Problem sehr effizient und problemlos löst.

In Map können Sie den Namen als Schlüssel und Ihr ursprüngliches Objekt als Wert angeben.

  Map<String,Cave> myMap=new HashMap<String,Cave>();
1
saurav

Sie können einfach eine Methode erstellen, um das Objekt anhand seines Namens zu erhalten.

public Party getPartyByName(String name) {
    for(Party party : parties) {
        if(name.equalsIgnoreCase(party.name)) {
            return party;
        }
    }
    return null;
}
0
user2608389

Ich würde vorschlagen, die equals(Object) Ihrer Party-Klasse außer Kraft zu setzen. Es könnte ungefähr so ​​aussehen:

public boolean equals(Object o){
    if(o == null)
        return false;
    if(o instanceof String)
        return name.equalsIgnoreCase((String)o);
    else if(o instanceof Party)
        return equals(((Party)o).name);
    return false;
}

Anschließend können Sie die indexOf(Object)-Methode verwenden, um den Index des durch seinen Namen angegebenen Teilnehmers abzurufen (siehe unten):

int index = cave.parties.indexOf("SecondParty");

Gibt den Index der Party mit dem Namen SecondParty zurück. 

Hinweis: Dies funktioniert nur, weil Sie die equals(Object)-Methode überschreiben.

0
Josh M