Günstigstes Element aus einer ArrayList ausgeben

scudi

Mitglied
Hallo! Ich habe leider ein Problem und weiss nicht, wie ich es am besten löse.

Also:
Ich habe folgende Klasse:

Java:
public class UsedCar{

public UsedCar(string model, int price, int age){
this.model = model;
this.price = price;
this. age = age;
}
}

Jetzt habe ich eine ArrayList<Car> list = new ArrayList<Car>();
Ich fülle diese Liste jetzt mit Objekten vom Typ UsedCar. (zB. list.add(new UsedCar("Opel", 20000, 10)

Jetzt möchte ich gerne folgende Methode realisieren:

public static Car getCheapestCarUnder5Years(ArrayList<Car> cars);

Also ich möchte aus meiner Liste das günstigste Auto, das jünger als 5 Jahre ist auswählen.

Wie gehe ich hier vor? Ich weiss nicht, wie ich eine Liste nach diesen Kriterien sortieren soll bzw. wie ich dieses Element finde.

Wenn es kein Auto gibt, dass diese Kriterien erfüllt, soll ich null zurückgeben.

Kann mir da jemand helfen?
 
Zuletzt bearbeitet von einem Moderator:
Ich würde einen Comperator für den Preis schreiben, und dann die Liste nach Preis sortieren (aufsteigend).
Wenn du die sortierte liste hast, würde ich von oben (index 0, also das billigste element) solange durch die liste gehen,
bis das aktuelle element jünger als 5 jahre ist. wenn eins unter 5 jahre ist, musst du das nur zurückgeben. hast du die komplette liste durchgeschaut,
musst du null zurückgeben, weil alle autos zu alt sind.
 
Hi,
um einen Comparator zu schreiben muss dein Car Object das Interface Comparable implementieren. Das erreichst du mit
Code:
class Car implements Comparable { ...
. Das Interface verlangt nun eine Methode
Code:
public int compareTo(...){
, in dieser gibst du an nach welchen Kriterien sortiert werden soll. In deinem Fall wäre es dann Preis und Datum. Mit Collections.sort(...) kannst du danach deine Liste<Car> sortieren und so vorgehen, wie von BRoll beschrieben.

Einfach mal nach "Java custom comparator" suchen, da gibts 1000e Beispiele.

lg
 
WArum soll er denn jedesmal wenn er eine Abfrage macht die Liste komplett sortieren? Das dauert ja ewig.

Du setzt einfach eine Variable foundCar = null; Dann iterierst du durch die Liste und wenn ein Auto jünger als 5 Jahre ist, dann schaust du ob dein foundCar = null ist. Wenn ja, dann wird foundCar gleich dem aktuellen Car. Wenn foundCar != null ist, schaust du ob der aktuelle Car billiger ist als der foundCar. Wenn nein, dann weiter, ansonsten wird das aktuelle Car das foundCar. Bist du durch die Liste durch gibst Du foundCar zurück.

Dürftre um Faktor 100 schneller sein und noch dazu viel einfacher.

Gruß

Claus
 
Ich würde das folgendermaßen lösen (Achtung: kein valider Code, nur zur Erklärung der Logik, muss semantisch angepasst werden, wollte keine vollständige Lösung liefern):

Code:
public Car getCheapestCarUnder5Years(ArrayList<Car> cars) {
     int cheapest = -1; // Kein Auto gefunden
     for (int i=0; i <= Länge von ArrayList; i++) {
          if (Alter von Car < 5){
               if ((Kein Auto gefunden) || (Preis von Car(i) < Preis von Car(cheapest)) {
                    cheapest = i;
               }
          }
     }
     if (Kein Auto gefunden) {
        return null;
     } else {
        return Car(cheapest);
     }
}
 
Oder auch als Einzeiler:
Java:
    Car cheapest = list.stream().filter(c -> c.age < 5).min(Comparator.comparing(c -> c.price)).orElse(null);
 
Oder auch als Einzeiler:
Java:
    Car cheapest = list.stream().filter(c -> c.age < 5).min(Comparator.comparing(c -> c.price)).orElse(null);

Wenn Du Zeit hast, dann vergleich die Lösung doch mal mit meiner und schreib auf wie lange beide bei sagen wir mal einer Liste mit 5000 Einträgen braucht.

Gruß

Claus
 
@Thallius Nö, ich weiß ja, was dabei herauskommt! 🙂 Natürlich ist der klassische Ansatz da deutlich schneller, falls du darauf hinaus willst. Die Laufzeit wächst aber trotzdem nur linear mit der größe der Liste, genau wie bei deinem.
War ja auch nur als zusätzliche Alternative gedacht. Ich hab es manchmal ganz gerne, wenn man einen leicht verständlichen Einzeiler als Code hat, bei dem man sofort sieht, was er macht, als auf jede Millisekunde bei der Laufzeit zu achten. Ist natürlich immer eine Einzelfallenstscheidung.
 
@Thallius Nö, ich weiß ja, was dabei herauskommt! 🙂 Natürlich ist der klassische Ansatz da deutlich schneller, falls du darauf hinaus willst. Die Laufzeit wächst aber trotzdem nur linear mit der größe der Liste, genau wie bei deinem.
War ja auch nur als zusätzliche Alternative gedacht. Ich hab es manchmal ganz gerne, wenn man einen leicht verständlichen Einzeiler als Code hat, bei dem man sofort sieht, was er macht, als auf jede Millisekunde bei der Laufzeit zu achten. Ist natürlich immer eine Einzelfallenstscheidung.

Im Prnzip gebe ich Dir recht, nur nicht das Dein Einzeiler für einen Anfänger leicht zu verstehen ist 🙂 Da finde ich eine schleife aber sowas von klarer 🙂

Gruß

Claus
 
Hallo ihr beiden!
Danke für eure Antwort!

Ich werde mal die etwas längere Variante versuchen. Der Einzeiler ist grad ein bisschen zu "hardcore" für mich 😀

Vielen Dank für die Inputs und Hilfe!
 

Zurück
Oben