metoda w atrybucie - jesli dobrze to nazwałem...

1

(Początkujący) Hej stworzyłem sobie Klase samochód wyścig i Main do sprawdzenia wszystkiego. W klasie wyscig stworzyłem metodę dodajZawodnika, pokazZawodnikow i najszybszyZawodnik. Wszystko jest okay ale teraz sprawdzam wszystko w klasie Main i dupa. Tworząc obiekt Wyscig chcialbym aby tworzac ten obiekt Od razu w atrybucie byla moja metoda ktora znajduje najszybszego zawodnika pod wzgledem czasuDoSetki. Czyli tworze kilka aut. potem tworze wyscig (w którym ma byc ukryta metoda najlepszyZaowdnik), dodaje autka do wyscigu i Run. Wyskakuje mi blad. Coś źle robie z klasą Wyśgig i z jego atrybutem zwyciezca. Jak to naprawić ?

Klasa Samochód:

public class Samochod {

    private String marka;
    private String model;
    private int moc;
    private double czasDoSetki;

    public Samochod(String marka, String model, int moc, double czasDoSetki) {
        this.marka = marka;
        this.model = model;
        this.moc = moc;
        this.czasDoSetki = czasDoSetki;
    }

    public String getMarka() {
        return marka;
    }

    public void setMarka(String marka) {
        this.marka = marka;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public int getMoc() {
        return moc;
    }

    public void setMoc(int moc) {
        this.moc = moc;
    }

    public double getCzasDoSetki() {
        return czasDoSetki;
    }

    public void setCzasDoSetki(double czasDoSetki) {
        this.czasDoSetki = czasDoSetki;
    }
    public String toString(){
        return getClass().getSimpleName() + " " + marka + " " + model + " " + moc + " km " + czasDoSetki + " seukundy";
    }
}

Klasa Wyścig:

import java.util.ArrayList;
import java.util.List;

public class Wyscig {
    private Samochod zwyciezca;
    private static List<Samochod> zawodnicy = new ArrayList<>();

    public Wyscig() {
        this.zwyciezca = najlepszyZawodnik();
        System.out.println(zwyciezca);
    }

    public Samochod getZwyciezca() {
        return zwyciezca;
    }

    public void setZwyciezca(Samochod zwyciezca) {
        this.zwyciezca = zwyciezca;
    }

    public List<Samochod> getZawodnicy() {
        return zawodnicy;
    }

    public void setZawodnicy(List<Samochod> zawodnicy) {
        this.zawodnicy = zawodnicy;
    }

    public void dodajSamochod(Samochod samochod) {
        if (!zawodnicy.contains(samochod)) {
            zawodnicy.add(samochod);
        }
    }

    public void pokazZawodnikow() {
        for (Samochod samochod : zawodnicy) {
            System.out.println(samochod);
        }
    }

    public Samochod najlepszyZawodnik() {
        Samochod najszybszy = zawodnicy.get(0);
        for (Samochod samochod : zawodnicy) {
            if (najszybszy.getCzasDoSetki() > samochod.getCzasDoSetki()) {
                najszybszy = samochod;
            }
        }
        return najszybszy;
    }
}

Klasa Main:

public class Main {
    public static void main(String[] args) {
        Samochod samochod0 = new Samochod("Audi", "RS6", 550, 5.5);
        Samochod samochod1 = new Samochod("Nissan", "370Z", 330,6.3);
        Samochod samochod2 = new Samochod("BMW", "e38", 240, 7.8);


        Wyscig wyscig = new Wyscig(); // tutaj ma być ukryta atrybut z metodą -  najlepszyZaowdnik;

        wyscig.dodajSamochod(samochod0);
        wyscig.dodajSamochod(samochod1);
        wyscig.dodajSamochod(samochod2);

        wyscig.pokazZawodnikow();

       wyscig.najlepszyZawodnik();
    }
}
3

Wyskakuje mi blad.

JAKI BŁĄD?!

  1. W ogóle jakoś od d**y strony się za to zabierasz. Po co ci tam wszędzie jakieś gettery i settery? o_O Czemu nie tworzysz wyścigu przekazując w konstruktorze listy samochodów?
  2. W ogóle ten kod to jakiś cyrk. Czemu samochody nie są Comparable? Mógłbyś wtedy użyć istniejących narzędzi do wybrania maxa.
  3. Jeszcze jakiś static tam o_O
0

Taki bład

2
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;

class Samochod implements Comparable<Samochod> {
    private final String marka;
    private final String model;
    private final int moc;
    private final double czasDoSetki;

    public Samochod(String marka, String model, int moc, double czasDoSetki) {
        this.marka = marka;
        this.model = model;
        this.moc = moc;
        this.czasDoSetki = czasDoSetki;
    }

    @Override
    public String toString() {
        return "Samochod{" +
                "marka='" + marka + '\'' +
                ", model='" + model + '\'' +
                ", moc=" + moc +
                ", czasDoSetki=" + czasDoSetki +
                '}';
    }

    @Override
    public int compareTo(Samochod o) {
        return Comparator.<Samochod>comparingDouble(x -> x.czasDoSetki)
                .reversed()
                .compare(this, o);
    }
}

class Wyscig {
    private final List<Samochod> zawodnicy;
    private final Samochod zwyciezca;

    public Wyscig(List<Samochod> zawodnicy) {
        this.zawodnicy = zawodnicy;
        this.zwyciezca = Collections.max(zawodnicy);
    }

    public void pokazZawodnikow(Consumer<String> sink) {
        for (Samochod samochod : zawodnicy) {
            sink.accept(samochod.toString());
        }
    }

    public Samochod najlepszyZawodnik() {
        return zwyciezca;
    }
}

public class Samochody {
    public static void main(String[] args) {
        Samochod samochod0 = new Samochod("Audi", "RS6", 550, 5.5);
        Samochod samochod1 = new Samochod("Nissan", "370Z", 330, 6.3);
        Samochod samochod2 = new Samochod("BMW", "e38", 240, 7.8);

        Wyscig wyscig = new Wyscig(List.of(samochod0, samochod1, samochod2));
        wyscig.pokazZawodnikow(System.out::println);
        System.out.println(wyscig.najlepszyZawodnik());
    }
}

Błąd wynikał z tego że nie rozumiesz co robisz. Zgaduje ze tego kodu sam nie napisałeś, tylko probujesz zmieniać jakiś kradziony kod. Wołasz w konstruktorze swoją bardzo słabo napisaną metodę która szuka maxa w tablicy ZANIM dodałeś jakieś samochody. A twoja funkcja nie działa dla pustej listy bo zakładasz że istnieje przynajmniej 1 element o indeksie 0.

0

Dzięki wielkie za podesłanie gotowca, też go przenalizuje. Jednak chciałbym wiedzieć co mogę zrobić w swoim kodzie aby po prostu dział... Usunałem część setterów i getterów aby kod był bardziej czytelny . Biblioteki Comparable, stremów jeszcze nie znam.

2
KotAli napisał(a):

Usunałem część setterów i getterów aby kod był bardziej czytelny .

No i dobrze. Wiekszosc nie byla uzywana. Method 'setZwyciezca(Samochod)' is never used

KotAli napisał(a):

Biblioteki Comparable, stremów jeszcze nie znam.

Comparable to taki interface, nauczysz sie go zaraz po dziedziczeniu i polimorfizmie.

0

Ja tak czysto teoretycznie zasugerowalbym ze moze comparable nie jest tutaj najlepszym rozwiazaniem bo 'samochody' mozemy porownywac na rozne sposoby dlatego jedna implementacja nie ma tu sensu. Dla czego mielibysmy brac pod uwage tylko 'CzasDoSetki' a nie 'moc' :) .. z perspektywy samochodu oba atrybuty sa wazne. Z perspektywy 'wyscigu' jest juz inaczej i dlatego to tam powinnismy zastanawic sie kto jest 'zwyciezca' wyscigu.

Twoj kod nie jest zly jak na kogos kto sie uczy, aby naprawic twoj kod tak jak sobie to sam ustawiles musisz upewnic sie ze lista zawodnikow jest zapelniona zanim odpalisz funkcje najlepszyZawodnik(). A zrobic to mozez dosyc prosto zmieniaja konstruktor:

 public Wyscig(List<Samochod> zawodnicy) {
        this.zawodnicy = zawodnicy;
        this.zwyciezca = najlepszyZawodnik();
        System.out.println(zwyciezca);
    }

Wtedy w mainie najpierw musisz zbudowac liste zawodnikow i podac ja przy inicjacji 'wyscigu'.

0

@Shalom: a nie lepiej:

 public void pokazZawodnikow(Consumer<Samochod> sink) {
        zawodnicy.forEach(sink);
    }

a samo compare:

 Comparator<Samochod> comparator = (auto_x, auto_y) -> Comparator.<Samochod>comparingDouble(x -> x.czasDoSetki).reversed().compare(auto_x, auto_y);
 this.zwyciezca = Collections.max(zawodnicy, comparator);
0

Dodatkowo, nie musisz robic getterów i setterow na wszystko, czasem settery moga tez byc prywatne lub chronione.
Nie powinienes takze, explicitly kasowac obiektu setterem na List, a stworzyc np. reset czy flush cos w tym sylu byle nie jawnie. jo nyggaz (shalom alajkum)

1 użytkowników online, w tym zalogowanych: 0, gości: 1