Wzięłaś sobie za dużo problemów na raz. Po pierwsze Java nie zezwala na tworzenie tablic typów generycznych dlatego new ArrayList<E>[10]
nie da się nawet skompilować. Można z tym sobie poradzić tworząc new Object[10]
i każdorazowo przy dostępie robiąc konwersję na właściwy typ:
ArrayList<Integer>[] test = (ArrayList<Integer>[])new Object[10];
, jednak przy każdej takiej instrukcji otrzymuje się ostrzeżenia Unchecked cast
i można je tylko wygasić, jeżeli autor kodu wie co robi. Dlatego generalnie nie miesza się kolekcji Javy z tablicami. Mimo to niemal każda z kolekcji jest wewnętrznie oparta o obiekty tablicowe, ale jest nie to do zrobienia przez nikogo początkującego bo na to trzeba znać Javę przynajmniej dobrze. Dlatego zadanie zrobienia tablicy kolekcji jako zadanie dla początkujących chyba ktoś niezbyt dobrze przemyślał. :)
Można też zamiast tablicy obiektów przydzielić na stercie tablice typów nie generycznych takich jak new ArrayList[10]
i jest to alternatywa, która wykorzystałaś. Tak naprawdę nie ma znaczenia jakiego typu elementów jest tablica ponieważ faktycznie każda tablica obiektów jest tablicą referencji do obiektów, a każdy obiekt musi dziedziczyć po klasie Object
. Jest to więc tylko kwestia zapisu konwersji typu referencji przy tworzeniu, odczycie i zapisie.
Następna sprawa, to kwestia iteratora. Twoja klasa ma implementować interfejs Iterable
, ale Iterable
, to obecnie też typ generyczny, a więc powinno to być Iterable<Integer>
. Bez względu na to czy użyje się tej wersji parametrycznej, czy wersji Iterable (RAW, bez parametru), czy Iterable<Object>
, to każda z nich będzie iterować po po obiektach. I tu jest potrzebne określenie po jakich obiektach. Czy po listach, które są elementami Twojej tablicy (wtedy class Table implements Iterable<ArrayList<Integer>>
) czy po elementach tych list, które powinny być obiektami Integer
(wtedy class Table implements Iterable<Integer>
), czy w ogóle zrobisz sobie problem i napiszesz class Table implements Iterable
, co jest równoważne class Table implements Iterable<Object>
. I od razu napiszę, że iterowanie po elementach podrzędnych list jest bardzo trudne do zrobienia dla osoby początkującej - nawet w przypadku prostego iteratora.
Jest to do zrobienia pod warunkiem, że nie użyjesz iteratorów list (a każda ma swojego), lecz będziesz iterować wyłącznie po kolejnych elementach kolejnych list. Od razu zapomnij o jakiejkolwiek pętli for w metodach next
lub hasNext
. Indeksy bieżące muszą być polami klasy obiektu iterującego, czyli musisz stworzyć dwa pola int - indeks bieżącej listy i indeks elementu w bieżącej liście, które będą służyły wyłącznie do obsługi tych dwóch metod. Metoda hasNext
musi sprawdzać czy indeks bieżącej listy doszedł do jej końca, a w takim wypadku musi zmienić indeks bieżącej listy na następny, co też musi sprawdzić (czy liczba list nie została przekroczona) oraz kolejny raz sprawdzić czy indeks tej kolejnej listy też doszedł do końca (bo lista może mieć zero elementów). Dlatego w hasNext
będzie musiała być pętla bo przecież może być kilka pustych list po sobie. Metoda next
też nie będzie banalna bo najpierw musi wyciągnąć obiekt Integer
z bieżącej pozycji wskazywanej przez indeks elementów na liście wskazywanej przez bieżący indeks listy, ale na koniec musi zwiększyć indeks obiektu na liście, a jeżeli się skończy, to wyzerować indeks obiektu i zwiększyć indeks listy. I tu znowu trzeba pamiętać, że kolejne listy też mogą być puste więc trzeba w pętli iterować kolejne listy, żeby napotkać na pierwszy element kolejnej niepustej listy. W każdym razie dla początkującego kupa problemów z napisaniem takiej obsługi iteracji.
Co do tego kodu, który widzę, to next
nie może być typu void
bo musi zwracać element Integer
. Następną rzeczą jest to, że jeżeli klasa jest Iterable<X>
, to musi mieć metodę Iterator<X> iterator()
, która zwróci obiekt iteratora. Ten obiekt musi być zrobiony jako klasa wewnętrzna i klasa tego właśnie obiektu musi mieć dwa pola indeksowe (listy i elementu na niej). Konstruktor takiego iteratora może być pusty bo choć normalnie musiałby wyzerować oba pola indeksów na starcie, to Java robi to z automatu dla każdego z pól klasy. Dlatego jawnego konstruktora klasy implementującej Iterator
nie musi być.
Najlepiej byłoby, żebyś obejrzała implementację jakiegoś prostego kontenera, ale kod źródłowy standardowych kolekcji Javy jest tak fatalny i tak nieczytelny, że lepiej tego nie robić bo można się nauczyć złych nawyków.