Hirdetés

Új hozzászólás Aktív témák

  • Szmeby
    tag

    Ezért ne kövesd el te azt a hibát, amit a java megalkotói, hogy túl általános típust használsz. :)
    Jó, tudom, csak kompatibilitás, de akkoris.

    Szóval a probléma a PolyLine.equals-ban van. Mivel a szignatúrája szerint Objectet vár, az ember bármit beadhat. És hidd el, be is fog. Amin aztán az egész cucc megfekszik (pl. ClassCastException-nel), ha nem figyelsz. Rosszabb esetben - mint most is - működik tovább hibásan.
    Javaslom, minden equals metódusodban ellenőrizni a bejövő paraméter típusát. Ha nem jó típus, akkor false, ha jó típus, akkor pedig tessék castolni, és aztán hasonlítgatni. Könnyebben kibukik, hogy a beadott PolyLine nem is ArrayList, amivel hasonlítani akarod.
    Egyébként az equals, hashcode metódusokat egy IDE szépen ki is generálja neked, van rá menüpont.

    Szóval listát a listával:

    public boolean equals(Object obj){
    if (obj == this) {
    return true;
    }
    if (obj == null) {
    return false;
    }
    if (getClass() != obj.getClass()) {
    return false;
    }
    PolyLine other = (PolyLine) obj;
    return points.equals(other.points);
    }

    Ha nem kellenek az ismétlődések, miért nem egy rendezett Setet használsz erre a célra? LinkedHashSet, vagy valami ilyesmi. Ő magától megcsinálja.

    Pár megjegyzés:
    - Osztályon belül felesleges gettereket használnod, simán lehet hivatkozni a field-ekre, pl.:
    return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));

    - Ha az objektum állapota nem változhat, akkor érdemes a field-eket final-ra állítani, így még véletlenül sem fogod tudni tönkretenni az objektumaidat. Továbbá egy ilyen tipikus value object esetén én még a getterek elhagyását is megkockáztatnám, valahogy így:
    public class Point{
    public final int x;
    public final int y;

    public Point(int x, int y){
    this.x = x;
    this.y= y;
    }

    public boolean equals(Object other){
    // ...
    }

    public double getDistance(Point other){
    // ...
    }

    public String toString(){
    // ...
    }
    }

    - Ne félj interfészt használni, ahol lehet, könnyebben cserélgetheted majd mögötte az implementációt. Ha nem akarod cserélgetni, akkor sem árt, mert idővel rááll a kezed, és nem kell folyton törnöd az APIt egy kis módosítás miatt.
    Erre gondolok:
    private ArrayList<Point> points = new ArrayList<Point>();
    // helyett
    private List<Point> points = new ArrayList<Point>();
    // esetleg (attól függ, milyen funkcionalitást vársz el tőle, legyen-e rendezett, stb)
    private Collection<Point> points = new ArrayList<Point>();

    - Ciklusban Stringeket konkatenálni + jellel nem szép dolog, brutálisan pazarló. Minden egyes konkatenáció egy újabb és egy újabb Stringet hoz létre, amit aztán a következő körben el is dob, mert csak átmenetileg volt rá szükség. StringBuilder javallott és annak append metódusa. Vaaagy használod a listák toString metódusát, mert van. :)

    Remek... letelt az időkorlát. -.-

    Szóval azt még elfelejtettem, hogy ha Set-re váltasz, akkor a Point.equals mellett a Point.hashcode-ot is implementálnod kell. Az IDE elvégzi helyetted, de a lényeg:

    A HashSet úgy működik, hogy a beletolt objektumra először hashcode-ot számol, ez csak egy szám. Ehhez a hashcode-hoz létrehoz egy izét, nevezzük vödörnek, és ebbe a vödörbe dobja bele az objektumodat.
    Ha egy újabbat adnál hozzá, akkor arra is hashcode-ot számol, és csak az adott hashcode-hoz tartozó vödörrel foglalkozik, végigmászik a vödör tartalmán, az equals-szal csekkolja, hogy benne van-e már, és ha talált, akkor nem teszi bele újra.
    Ha a hashcode számítást elcseszed, akkor előfordulhat olyan, hogy van 2 objektumod, ami az equals szerint azonos, de a hashcode szerint nem. Mindkettő bele fog kerülni a Set-be (!!), mert a másik az eltérő hashcode miatt másik vödörbe kerül. Ilyet sose csinálj.
    Vagy például megváltozik az objektumod állapota (mondjuk most nem, mert minden final, de máskor, mással, másnál igen :D), és a megváltozott állapot miatt megváltozhat a hashcode is. Na az az objektumod, ha benne volt egy set-ben, akkor ott is marad, sose találod meg. Vicces dolgok ezek. :)
    Gondolhatnád, hogy akkor legyen a hashcode mindig 1, abból baj nem lehet. Jó gondolat, de lassú lesz, épp azért szegmentálunk sok kis vödörre relatíve kis számításigényű megoldásokkal, hogy csak egy kis vödör tartalmán kelljen végigsuhanni, gyorsan el lehet dönteni, hogy valami benne van-e abban a Set-ben avagy sem.

Új hozzászólás Aktív témák