Trochę jak widze do przodu poszła dyskusja. Ok, na początek pytanie czy jeżeli obiekty mają takie samo value i są to różne obiekty to czy naprawdę ważna jest ich kolejność przy sortowaniu? Jeżeli nie, a jednocześnie nie chcesz, aby były oznaczane jako równe przez compareTo, to samo compareTo może zawierać fragment:
public int compareTo(ComparableObject co){
//...
if(this != co && this.value.equals(co.value)){
if(Math.random()>0.5)
return 1;
else
return -1;
}
}
Metoda z ID będzie się sprawdzać o ile obiekty po wczytaniu będą w jakiś magiczny sposób otrzymywały identyfikatory w takiej samej kolejności jak przed zapisaniem (serializacją). W przeciwnym wypadku powstanie sytuacja gdzie serializacja i zapis obiektów będą prowadziły do zamiany ich kolejności. Spowodowane jest to przez transistent pola ID. W takiej sytuacji wracamy do sytuacji, w której kolejność nie jest istotna. Metoda przedstawiona powyżej może okazać się zła jeżeli zależy nam na tym by dane były w trakcie działania aplikacji sortowane zawsze w tej samej kolejności, ale tylko w ramach danego uruchomienia programu. Można więc nadawać ID w taki sposób:
this.ID = Math.random() * (new Date()).getTime();
każdy identyfikator jest unikatowy, a jednocześnie nie powtarza się. Wywołanie jest w konstruktorze.
Jeżeli chcemy, aby zawsze ID było takie samo to należy serializować pole ID. Pytanie jeszcze jak dobrać się do ID obiektu w sposób bezpieczny. Tworzenie publicznego settera nie ma sensu ponieważ w taki sposób każdy fragment programu będzie mógł namieszać w ID. Należy zatem użyć modyfikatora domyślnego w ten sposób do metody uzyskają dostę tylko obiekty z klas znajdujących się w jednym pakiecie z naszą klasą. Można też zastosować refleksję w celu wybrania prywatnego pola, ale jest to moim zdaniem armata na muchę.