Internet Info, s.r.o. Lupa Měšec Podnikatel Root Zdroják DigiZone Slunečnice Vitalia TopDrive KupDnes Navrcholu NovýTarif Dobrý web Weblogy Woko Jagg Computer.cz SK: MojeLinky

Hlavní navigace

Názory k článku
Novinky v JDK 7 (5) – projekt Lambda a anonymní funkce v příkladech

Martin Štekl aura:100
9. 12. 2010 7:58 Nový

Arrays.sort

celé vlákno

Trochu mě zarazilo, proč musí být při použití Arrays.sort překryta metoda equals tak, aby vracela true pro compareTo(...) == 0. Pokud vím, compareTo je součástí interfacu Comparable a tedy při použití komparátoru toto nepoužiji. Nebo se mýlím? Předpokládám, že v komparátoru, který funkci Arrays.sort předávám, nepotřebuji metodu compareTo nebo equals. Od toho tuším komparátor je.

Přiznámvám se ale, že v Javě natolik zběhlý nejsem, proto pokud je tam nějaký důvod, který nevidím, budu rád, když se jej dovím.

Pavel Tišnovský aura:98
9. 12. 2010 10:24 Nový

Re: Arrays.sort

celé vlákno

Mate pravdu, v textu ma byt compare() nikoli compareTo(), omlouvam se za zmateni.

Pri pouziti Arrays.sort() NEMUSI byt equals() prekryta, a to ani pri pouziti komparatoru ani v pripade, ze trida, jejiz instance se radi, implementuje rozhrani Comparable a tedy i metodu compareTo().

Konkretne zde je implementace Arrays.sort() zavolana v pripade, ze se teto metode preda krome pole i komparator. Zadne equals() se zde nevola, pouze compare():

private static void mergeSort(Object[] src,
                              Object[] dest,
                              int low, int high, int off,
                              Comparator c) {
    int length = high - low;

    // Insertion sort on smallest arrays
    if (length < INSERTIONSORT_THRESHOLD) {
        for (int i=low; i<high; i++)
            for (int j=i; j>low && c.compare(dest[j-1], dest[j])>0; j--)
                swap(dest, j, j-1);
        return;
    }

    // Recursively sort halves of dest into src
    int destLow  = low;
    int destHigh = high;
    low  += off;
    high += off;
    int mid = (low + high) >>> 1;
    mergeSort(dest, src, low, mid, -off, c);
    mergeSort(dest, src, mid, high, -off, c);

    // If list is already sorted, just copy from src to dest.  This is an
    // optimization that results in faster sorts for nearly ordered lists.
    if (c.compare(src[mid-1], src[mid]) <= 0) {
       System.arraycopy(src, low, dest, destLow, length);
       return;
    }

    // Merge sorted halves (now in src) into dest
    for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
        if (q >= high || p < mid && c.compare(src[p], src[q]) <= 0)
            dest[i] = src[p++];
        else
            dest[i] = src[q++];
    }
}
Maaartin
Maaartin (neregistrovaný) 188.120.198.---
10. 12. 2010 21:57 Nový

Re: Arrays.sort

celé vlákno

Ta metoda Comparator.equals je na zmateni nepritele, a tentokrat se to povedlo. Slouzi k porovnani dvou comparatoru a nema VUBEC nic spolecnyho s metodou compare.

To ze je equals uvedeny v interfejsu Comparator nedava skoro zadny smysl, pridanou hodnotou (a to spornou) je pouze komentar k ni. Vzhledem k tomu ze equals je podedeny od Object, je Comparator stale (takovy divny) SAM interfejs.

mc1100 aura:43
9. 12. 2010 13:49 Nový

Vratit rozdiel dvoch int hodnot ako vysledok metody compare byva casto cesta do pekla

celé vlákno

Tu si to autor mohol dovolit. Teda ak predpokladame, ze ani vek ani plat nemoze byt zaporny. Ak by ale mohol, pri odcitavani moze dojst k preteceniu. Kto neveri nech vyskusa toto:

public static void main(String[] args) {
int i1 = Integer.MIN_VALUE;
int i2 = 1;
System.out.prin­tln(i1 - i2); // tu by compare vratilo nespravny vysledok!
System.out.prin­tln((long) i1 - (long) i2);
}

Pavel Tišnovský aura:98
9. 12. 2010 14:34 Nový

Re: Vratit rozdiel dvoch int hodnot ako vysledok metody compare byva casto cesta do pekla

celé vlákno

Je to tak, v realne aplikaci by se urcite musely dat kontroly v tomto pripade do konstruktoru. Pravdepodobne nejenom pro zaporna cisla, ale i pro nejaky vhodny rozsah veku a platu.

Ale je urcite dobre, ze jste na to upozornil, pokud kontroly pro hodnoty atributu chybi, je zadelano na problem.

Jan Lender
Jan Lender (neregistrovaný) ---.skoda-auto.cz
9. 12. 2010 13:52 Nový

equals a compareTo

celé vlákno

"...je žádoucí přetížit i metodu equals(), a to takovým způsobem, aby tato metoda vracela hodnotu true v případě, že metoda compareTo() vrací nulu."
Tohle platí, ovšem přesně obráceně: Jestliže equals vrátí true, compareTo musí vrátit nulu.
Kdyby měla být aplikována autorova poučka na jeho příklad s rodnými čísly (compareTo vrací nulu v případě shody číslic před lomítkem), pak by equals vracela true pro lidi stejného pohlaví narozené v tentýž den (+ lidi narozené v okolních stoletích). Což je v případě použití rodného čísla například jako klíče v java.util.Map docela děsivá představa.

Pavel Tišnovský aura:98
9. 12. 2010 15:39 Nový

Re: equals a compareTo

celé vlákno

Pokud se pouze pretizi equals(), tak to pracovat bude, protoze se pri pristupu k prvkum nejdrive kontroluje hashCode(), ktery musi byt shodny soucasne s equals(). I kdyz se samozrejme jedna o krehky kod, ktery zavisi na tom, ze hashCode() pro kazda dve sestimistna cisla je rozdilny - coz je, ale pro jine JDK to nemusi platit ;-)

yanas
yanas (neregistrovaný) ---.net.upcbroadband.cz
10. 12. 2010 18:29 Nový

Re: equals a compareTo

celé vlákno

Je dobré neplést pojmy "přetížit" (overload) a "překrýt" (override). Přetížení metody equals() nevede k očekávanému výsledku (naopak může vést k velmi špatně vystopovatelné chybě), překrytí ano. Z kontextu je jasné, jak to myslíte, ale může to být dosti zavádějící.

Dále z textu není patrné, zda by měl člověk překrýt metodu equals() na komparátoru, nebo ve třídě Employee. Metoda Comparator.equ­als(Object) já trošku jinou sémantiku než Object.equals(Ob­ject).

A když už jsem za hnidopicha, tak ještě jedna drobnost. :-) Pojmy "třídit" a "řadit" v češtině znamenají něco jiného. Třídíme odpad, řadíme studenty podle jména.

KapitánRUM
KapitánRUM (neregistrovaný) ---.profico.cz
9. 12. 2010 16:49 Nový

hmmm

celé vlákno

Článek super, změny hnus.

atarist
atarist (neregistrovaný) ---.redhat.com
9. 12. 2010 17:05 Nový

Re: hmmm

celé vlákno

blame Oracle :-)

Situace okolo JCP je docela bidna afaik.

Pavel Tišnovský aura:98
9. 12. 2010 20:25 Nový

Re: hmmm

celé vlákno

Kdyz uz jsme u JCP, tady je jedna cerstva zpravicka https://blogs.apache.org/foundation/entry/the_asf_resigns_from_the

Apache foundation melo dost dobre napady, jakym smerem Javu rozsirovat, tak uvidime, co udelaji dale.

Zasílat nově přidané příspěvky e-mailem