Objekte in ArrayList finden

Nisbo

Bekanntes Mitglied
Servus,

ich wollte mal fragen ob es eine einfachere Möglichkeit gibt um zu prüfen ob es einen Eintrag in einer ArrayList mit Objekten gibt.

Ich habe eine ArrayList vom Typ GpsData
Java:
public ArrayList<GpsData> gpsDataArrayList     = new ArrayList<GpsData>();

Das Objekt GpsData
Java:
public class GpsData {
    private String dmrId    = "";
    private String callSign = "";
    private int lastActive  = 0;
   
    public GpsData (String dmrId, String callSign, int lastActive){
        setDmrId(dmrId);
        setCallSign(callSign);
        setLastActive(lastActive);
    }

    /**
     * @return the dmrId
     */
    public String getDmrId() {
        return dmrId;
    }

    /**
     * @param dmrId the dmrId to set
     */
    public void setDmrId(String dmrId) {
        this.dmrId = dmrId;
    }

    /**
     * @return the callSign
     */
    public String getCallSign() {
        return callSign;
    }

    /**
     * @param callSign the callSign to set
     */
    public void setCallSign(String callSign) {
        this.callSign = callSign;
    }

    /**
     * @return the lastActive
     */
    public int getLastActive() {
        return lastActive;
    }

    /**
     * @param lastActive the lastActive to set
     */
    public void setLastActive(int lastActive) {
        this.lastActive = lastActive;
    }
}

zum "Befüllen" der ArryList
Java:
this.gpsDataArrayList.add(new GpsData(dmrid, call, getUnixTime()));

Soweit kein Problem, überprüfen ob es ein Objekt schon gibt da wollte ich jetzt wissen ob das evtl besser bzw einfacher geht. Ich mache das über Streams und Filter

Java:
GpsData cachedCallSign = checkIfChallSignIsCached(dmrid);
        if(cachedCallSign != null){
            return cachedCallSign.getCallSign();
        }

und hier die Methode checkIfChallSignIsCached
Java:
    private GpsData checkIfChallSignIsCached(String dmrid){
        List<GpsData> result = this.gpsDataArrayList.stream()
                .filter(line -> line.getDmrId().equals(dmrid))
                .distinct()
                .sorted(Comparator.comparing(GpsData::getCallSign))
                .collect(Collectors.toList());
               
        for (GpsData entry : result){
            if(entry.getDmrId().equals(dmrid)){
                return entry;
            }
        }
       
        return null;
    }

Also passt das so oder sollte man es evtl anders lösen ?
 
Danke für die Antwort aber da kann ich Dir gerade leider nicht folgen 🙁
kann sich ja eigentlich dann nur auf
.filter(line -> line.getDmrId().equals(dmrid))
beziehen
 
Du hast doch schon deine Liste gefiltert und weißt, dass da welche drinnen sein müssen. Verwende doch einfach Stream::findFirst:
Java:
private GpsData checkIfChallSignIsCached(String dmrid) {
  return gpsDataArrayList.stream().filter(line -> line.getDmrId().equals(dmrid)).distinct()
      .sorted(Comparator.comparing(GpsData::getCallSign)).findFirst().orElse(null);
}
 
List<GpsData> result = this.gpsDataArrayList.stream()
.filter(line -> line.getDmrId().equals(dmrid))
.distinct()
.sorted(Comparator.comparing(GpsData::getCallSign))
.collect(Collectors.toList());
Ich verstehe ja schon in nüchternem Zustand nicht warum du das da überhaupt machst ? Reicht denn nicht eine einfache Schleife über deine this.gpsDataArrayList und Abfrage auf getDmrId().equals(dmrid) ?
Also das was du in deiner Schleife darunter sowieso machst, nur mit einer vorgefilterten Liste ?
 
Eigentlich reicht auch ein
return gpsDataArrayList.stream().filter(line -> line.getDmrId().equals(dmrid)).findAny().orElse(null);

Ob der Stream sortiert und distinct ist, ist da doch ziemlich egal, sinniger weise sollte jede ID nur einmal vorkommen (und wenn mehrmals, sollte es das gleiche Objekt sein). uU ist da auch ein (Sorted)Set sinnvoll...

Oder wenn man GpsData noch um eine Methode zum ID vergleichen ergänzt:
return gpsDataArrayList.stream().filter(line -> line.hasId(dmrid)).findAny().orElse(null);
 
OK danke für den Hinweis mit dem findFirst() bzw findAny(), die ID gibt es nur einmal allerdings ist das dann immer noch mit Lambda was DerWissende angeführt hatte

@JStein52
jetzt wo Du es sagst frage ich mich das auch gerade 😀
evtl war ich da schon wieder weiter im Code gewesen beim Auslesen nach ActiveTime in Kombination mit der ID
 
Eine andere Überlegung wäre hier statt einer Liste eine Map zu verwenden.
Wenn die Reihenfolge deiner Liste eh egal ist und du nur per "dmrId" zugreifst, wäre das der perfekte Anwendungsfall.

Java:
Map<String,GpsData> gpsDataMap = new HashMap<>();

speichern kannst du dann mit gpsDataMap.put(dmrid,new GpsData(dmrid, call, getUnixTime()));
und herausholen kannst du mit gpsDataMap.get(dmrid);
Falls du über alle GpsData iterieren willst, gibt es gpsDataMap.values();
Siehe https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html für mehr Infos.
Achja, falls du tatsächlich eine HashMap verwenden willst, solltest du hashCode und equals überschreiben, aber hierzu findest du auch viele Infos bei Google...
 
OK danke für den Hinweis mit dem findFirst() bzw findAny(), die ID gibt es nur einmal allerdings ist das dann immer noch mit Lambda was DerWissende angeführt hatte
Das solltest du einfach ignorieren.

speichern kannst du dann mit gpsDataMap.put(dmrid,new GpsData(dmrid, call, getUnixTime()));
Oder mit Map#putIfAbsent, wenn nicht überschrieben werden soll

Achja, falls du tatsächlich eine HashMap verwenden willst, solltest du hashCode und equals überschreiben, aber hierzu findest du auch viele Infos bei Google...
Der Schlüssel wäre String, da muss man nichts in der anderen Klasse für überschreiben 😉
(Unabhängig von der Map ist es aber trotzdem sinnvoll...)
 

Neue Themen


Zurück
Oben