Sortowanie - jakie i jak zaimplementowac

0

Czesc!

Musze posortowac to wg kryteriow -> Następnie napisz metodę, która przyjmie jako parametr tablicę pojazdów i posortuje
je przyjmując jako kryteria: moc, pojemność, ilość miejsc i nazwę.

a tu jest kod (wiem, ze jakosc jego boli) ->

import java.util.Random;

public class s18032_p02 {

  public static void main(String[] args) {
    PojazMechaniczny[] tab = new PojazMechaniczny[1000];
    Random r = new Random();

    //Random::nextInt(int);
    for (int i = 0; i < tab.length; i++) {
      int iloscMiejsc = Math.abs(r.nextInt());
      String nazwa = "pojazd " + Math.abs(r.nextInt());
      long pojemnosc = Math.abs(r.nextLong());
      int moc = Math.abs(r.nextInt());

      int positive = Math.abs(i);
      Silnik silnik = new Silnik(moc, pojemnosc);
      tab[i] = new PojazMechaniczny(iloscMiejsc, nazwa, silnik);
    }
  }



//================================================
static class Silnik {
  int moc;
  long pojemność;

  public Silnik(int moc, long pojemność) {
    this.moc = moc;
    this.pojemność = pojemność;
  }

  public String toString() {
    return moc +  " KM" +  " | " + pojemność + " cm3" + " | " ;
  }
}

//================================================
static class PojazMechaniczny  {

  int iloscMiejsc;
  String nazwa;
  Silnik silnik;

  public PojazMechaniczny(int iloscMiejsc, String nazwa, Silnik silnik) {
    this.iloscMiejsc = iloscMiejsc;
    this.nazwa = nazwa;
    this.silnik = silnik;
  }
  public String toString() {
    return iloscMiejsc +  " | "  + nazwa + " | " + silnik;
  }
}

Czy ktos bylby w stanie mi wytlumaczyc jak to zrobic?

1
  1. DLa każdego kryterium które napisałeś tworzysz klasę comparatora, np tak:
public class PowerSorter implements Comparator<PojazMechaniczny>
{
    public int compare(PojazMechaniczny p1, PojazMechaniczny p2)
    {
        return p1.getSilnik().getMoc().compareTo(p2.getSilnik().getMoc());
    }
}

Analogicznie robisz pozostałe (pamiętaj o dodaniu getterów do odpowiednich klas).

  1. Następnie:
        Collections.sort(list, new PowerSorter ()
                                .thenComparing(new kolejnySorter())
                                .thenComparing(new trzeciSorter()));
0

W tej części zadania które podałeś, nie ma obowiązku powoływania klas dodatkowych. mowa tylko o klasie Pojazd. JA BYM zrobił na jednym poziomie, i sorter jedno poziomowy

public class PojazdSorter implements Comparator<PojazMechaniczny>
{
public int compare(PojazMechaniczny p1, PojazMechaniczny p2)
{
    int wrk = p1.getSilnik().getMoc().compareTo(p2.getSilnik().getMoc());
    if(wrk!=0) return wrk;

   
   wrk = kolejne porównania
    if(wrk!=0) return wrk;
...
  return wrk;
}

}

0

czy motoda sortująca ma przyjmować jedno z 4 kryteriów czy ma sortować najpierw wg mocy, potem pojemności, itd ?

1

Ja bym zrobił dla każdego kryterium oddzielny Comparator. Dzięki czemu używając thenComparing od razu po kodzie (nazwie comparatora) widać po czym obiekty są sortowane.
Natomiast @AnyKtokolwiek zrobił to samo w jednym Comparatorze, przez co gdy kiedyś jak wrócisz do swojego kodu, będziesz musiał się wczytać w jakiej kolejności odbywa sie sortowanie.

Oba rozwiązania zadziałają, wybierz sobie to co Ci bardziej odpowiada.

0
kixe52 napisał(a):

Ja bym zrobił dla każdego kryterium oddzielny Comparator. Dzięki czemu używając thenComparing od razu po kodzie (nazwie comparatora) widać po czym obiekty są sortowane.
Natomiast @AnyKtokolwiek zrobił to samo w jednym Comparatorze, przez co gdy kiedyś jak wrócisz do swojego kodu, będziesz musiał się wczytać w jakiej kolejności odbywa sie sortowanie.

Oba rozwiązania zadziałają, wybierz sobie to co Ci bardziej odpowiada.

Twoje spojrzenie jest uprawnione, moje też.
Są sortowania które mają sens uniwersalny, (osoby po nazwisku, imieniu) warto je wyodrębnić "dla potomności" (nawet utrwalić do w Comparable). Natomiast jak są sortowania "dziwne" (na rzeczy jednej funkcjonalności - duży litraż i mało osób też ktoś może chcieć), prawdopodobnie będzie ich przybywać, pojedyncze komparatory będą się mnożyć jak króliki

2

@Iothin: @yoten

Można zrobić też tak, jeśli nie chcesz się bawić w tworzenie oddzielnych klas. Dodatkowo jak nie chcesz się bawić w konwertowanie tablicy na listę, użyj zamiast Collections.sort Arrays.sort.

Comparator<PojazMechaniczny> carComparator = Comparator.comparing((PojazMechaniczny p) -> p.getSilnik().getMoc())
				.thenComparing(p -> p.getSilnik().getPojemność())
				.thenComparing(p -> p.getIloscMiejsc())
				.thenComparing(p -> p.getNazwa());

Moim zdaniem kod z comparatorami w oddzielnych klasach jest "ładniejszy" i łatwiejszy w utrzymaniu.

ps pisz po angielsku. getEngine brzmi lepiej niż pobierzSilnik

0

Sprawa jest taka, ze musze sam napisac sortowanie a nie uzyc do tego metody sort ;/ z tego co wiem, babelkowe bedzie tu pasowac ale nie mam pojecia jak to zaimplementowac :/

0

to moj aktualny comparator @kixe52:

public static class PojazdSorter implements Comparator<PojazMechaniczny>
    {
        public int compare(PojazMechaniczny p1, PojazMechaniczny p2)
        {
            int wrk = p1.getSilnik().getMoc().compareTo(p2.getSilnik().getMoc());
            if(wrk!=0) return wrk;

            wrk = p1.getSilnik().getPojemność().compareTo(p2.getSilnik().getPojemność());
            if(wrk!=0) return wrk;

            wrk = p1.getIloscMiejsc().compareTo(p2.getIloscMiejsc());
            if(wrk!=0) return wrk;

            wrk = p2.getNazwa().compareTo(p1.getNazwa());
            if(wrk!=0) return wrk;

            return wrk;
        }
0

Błąd pokazywany przez IDE powinien być dokładniejszy niż "cannot resolve method".
Chodzi tutaj o to, że wartości zwracane przez Twoje gettery to typy prymitywne. A one nie wspierają metod typu compareTo

Możesz użyć Integer.compare albo po prostu zamiast x.compareTo(y) użyj x - y :)

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