2015-06-14 20 views
5

Jestem zaznajomiony ze standardowymi porównaniami przy użyciu interfejsu Porównywalne, chociaż dziś mam problemy, gdy chcę porównać kilka różnych zmiennych.Używanie porównywalnego do porównywania różnych zmiennych

Zasadniczo chcę zaimplementować metodę compareTo który daje wynik tylko -1 gdy następujący jeśli stwierdzenie jest prawdziwe:

if (o.maxX > minX && o.maxY > minY && o.minZ < maxZ) 

Chociaż nie jestem pewien, czy jest to możliwe za pomocą porównywalne lub po prostu nie jest mi tak dobrze, jak się wydaje. Ponieważ przy próbie podejścia

public int compareTo(IsoSprite o) { 
    if (o.maxX > minX && o.maxY > minY && o.minZ < maxZ){ 
     return -1; 
    }else if(o.maxX < minX && o.maxY < minY && o.minZ > maxZ){ 
     return 1; 
    } 
    return 0; 
} 

Otrzymuję błąd „metoda Porównanie narusza jego ogólną umowę!”. Chcę wyjaśnić, że nie potrzebuję pomocy w zrozumieniu, co ten błąd oznacza, ponieważ przeczytałem kilka pytań na ten temat. Chociaż nadal nie mogę się skupić na tym konkretnym problemie, ponieważ rozwiązania innych pytań, które przeczytałem, były banalne.

Byłbym wdzięczny za pomoc przy porównaniu, byłoby to ratunkiem życia. Dowolne wejście jest również doceniane.

Edycja: Po przetestowaniu wokół, mam coś, co prawie działa (nie we wszystkich przypadkach), ale nie mogę zrozumieć, dlaczego:

public int compareTo(IsoSprite o) { 
    if (o.maxX > minX && o.maxY > minY && o.minZ < maxZ) { 
     return -1; 
    } else if (o.maxX > minX && o.maxY > minY && o.minZ > maxZ) { 
     return 1; 
    }else if (o.maxX < minX && o.maxY > minY && o.minZ > maxZ) { 
     return 1; 
    }else if (o.maxX < minX && o.maxY < minY && o.minZ > maxZ) { 
     return 1; 
    }else if (o.maxX < minX && o.maxY > minY && o.minZ < maxZ) { 
     return 1; 
    }else if (o.maxX > minX && o.maxY < minY && o.minZ > maxZ) { 
     return 1; 
    }else if (o.maxX < minX && o.maxY < minY && o.minZ > maxZ) { 
     return 1; 
    }else if (o.maxX > minX && o.maxY < minY && o.minZ < maxZ) { 
     return 1; 
    }else if (o.maxX < minX && o.maxY > minY && o.minZ < maxZ) { 
     return 1; 
    }else if(this != o){ 
     return 1; 
    } 
    return 0; 
} 
+1

http://stackoverflow.com/questions/8327514/comparison-method-violates-its-general-contract Najlepsza odpowiedź może być przydatna – twentylemon

+3

Wiesz, że Twój kod narusza ogólne zamówienie porównywalne (możliwe, że nie działa reguła przechodniości) , wtedy nie można go użyć do sortowania. Kropka. Twoje pytanie może być [XY Problem] (http://mywiki.wooledge.org/XyProblem), gdzie pytasz, jak rozwiązać konkretny problem z kodem, gdy najlepszym rozwiązaniem jest użycie zupełnie innego podejścia. Lepiej, abyś powiedział nam ogólny problem, który próbujesz rozwiązać, a nie jak obecnie próbujesz go rozwiązać. –

+0

@HovercraftFullOfEels To nie tylko ten konkretny problem, wcześniej też miałem podobne problemy, wydaje mi się, że można je rozwiązać za pomocą porównywalnego w jakiś sposób – Deminth

Odpowiedz

2

Jeśli używasz tego do sortowania obiektów, wtedy Twój Porównywalny lub Komparator musi być dobrze zachowany i musi respektować przechodnie i inne zasady. Jeśli nie, twój kod jest uszkodzony. Zaleca się, aby twoje metody porównywania były zgodne z równymi, co oznacza, że ​​a.compareTo (b) zwraca 0 wtedy i tylko wtedy, gdy a.equals (b), ale w przeciwieństwie do tego, co stwierdzono w usuniętej odpowiedzi, nie jest to bezwzględne wymaganie .

Kod nadal łamie przemiennym jak reguły porównywania, a mianowicie, że

a.compareTo(b) == -b.compareTo(a) 

Spójrzmy na regułach:

public int compareTo(IsoSprite o) { 
    // Comparison A 
    if (o.maxX > minX && o.maxY > minY && o.minZ < maxZ) { 
     return -1; 
    // Comparison B 
    } else if (o.maxX > minX && o.maxY > minY && o.minZ > maxZ) { 
     return 1; 
    // Comparison C 
    }else if (o.maxX < minX && o.maxY > minY && o.minZ > maxZ) { 
     return 1; 
    // Comparison D 
    }else if (o.maxX < minX && o.maxY < minY && o.minZ > maxZ) { 
     return 1; 
    // Comparison E 
    }else if (o.maxX < minX && o.maxY > minY && o.minZ < maxZ) { 
     return 1; 
    // Comparison F 
    }else if (o.maxX > minX && o.maxY < minY && o.minZ > maxZ) { 
     return 1; 
    // Comparison G 
    }else if (o.maxX < minX && o.maxY < minY && o.minZ > maxZ) { 
     return 1; 
    // Comparison H 
    }else if (o.maxX > minX && o.maxY < minY && o.minZ < maxZ) { 
     return 1; 
    // Comparison I 
    }else if (o.maxX < minX && o.maxY > minY && o.minZ < maxZ) { 
     return 1; 
    // Comparison J 
    }else if(this != o){ 
     return 1; 
    } 
    return 0; 
} 

spojrzeć na "Comparison C":

}else if (o.maxX < minX && o.maxY > minY && o.minZ > maxZ) { 

, która zwraca 1. Konwersja tego powinna powrócić -1, ale tak nie jest, ponieważ znajdujemy rozmowę w "C ORÓWNANIE H ":

}else if (o.maxX > minX && o.maxY < minY && o.minZ < maxZ) { 

Ale to też zwraca 1. Tak więc tutaj (i ewentualnie w innym miejscu) a.compareTo (b) nie równa się - z b.compareTo (a).

+0

Masz rację, nie można go rozwiązać jako porównywalnego – Deminth