Zaimplementowałem klasę w Javie, która wewnętrznie przechowuje listę . Chcę, aby klasa była niezmienna. Muszę jednak wykonywać operacje na wewnętrznych danych, które nie mają sensu w kontekście klasy. Dlatego mam inną klasę, która definiuje zestaw algorytmów. Oto uproszczony przykład:Niezmienne obiekty w Javie i dostęp do danych
Wrapper.java
import java.util.List;
import java.util.Iterator;
public class Wrapper implements Iterable<Double>
{
private final List<Double> list;
public Wrapper(List<Double> list)
{
this.list = list;
}
public Iterator<Double> iterator()
{
return getList().iterator();
}
public List<Double> data() { return getList(); }
}
Algorithm.java
import java.util.Iterator;
import java.util.Collection;
public class Algorithm
{
public static double sum(Collection<Double> collection)
{
double sum = 0.0;
Iterator<Double> iterator = collection.iterator();
// Throws NoSuchElementException if the Collection contains no elements
do
{
sum += iterator.next();
}
while(iterator.hasNext());
return sum;
}
}
Teraz moje pytanie brzmi, czy istnieje niezawodny sposób, aby uniemożliwić modyfikację moje wewnętrzne dane pomimo tego, że moja klasa ma być niezmienna? Chociaż udostępniłem metodę danych() tylko do odczytu, nic nie powstrzyma kogoś przed modyfikacją danych za pomocą metod takich jak clear() i remove(). Teraz zdaję sobie sprawę, że mogę zapewnić dostęp do moich danych wyłącznie za pośrednictwem iteratorów. Jednak powiedziano mi, że jest typowe, aby przekazać kolekcję . Po drugie, gdybym miał algorytm, który wymagałby więcej niż jednego przejścia przez dane, musiałbym podać wiele iteratorów, które wydają się śliskie.
Okay, mam nadzieję, że istnieje proste rozwiązanie, które rozwiąże moje obawy. Właśnie wracam do Javy i nigdy nie brałem pod uwagę tych rzeczy, zanim zajmiemy się const w C++. Z góry dziękuję!
Och! Jest jeszcze jedna rzecz, o której właśnie myślałem. Nie mogę praktycznie zwrócić kopii wewnętrznej listy . Lista zwykle zawiera setki tysięcy elementów.
Idealnie! Nie widziałem tego. Dziękuję Ci. –
Nadal musisz zająć się sposobem, w jaki tworzony jest obiekt Wrapper: ponieważ lista jest przekazywana do konstruktora, mogą istnieć odniesienia do niej gdzie indziej w kodzie. Jeśli chcesz, aby Wrapper był naprawdę niezmienny, musisz skopiować zawartość listy. –