Dlaczego Klasa arraylist implementuje listę jak również rozszerza AbstractList?

Implementacja java.util.ArrayList implementuje List oraz rozszerza AbstractList. Ale w dokumentach java widać, że AbstractList już implementuje listę. Czy nie byłoby więc zbędne implementowanie List i rozszerzanie AbstractList?
Moje drugie pytanie

Proszę spojrzeć na następujący kod:

String str = "1,2,3,4,5,6,7,8,9,10";
String[] stra = str.split(",");
List<String> a = Arrays.asList(stra);

Metoda Arrays.asList() klasy Arrays zawiera własną implementację ArrayList. Ale ten tylko rozszerza listę abstrakcyjną, ale nie implementuje listy. Ale powyższy kod kompiluje.
ale gdy kod zostanie zmieniony na następujący

String str = "1,2,3,4,5,6,7,8,9,10";
String[] stra = str.split(",");
java.util.ArrayList<String> a = Arrays.asList(stra);

Dostaję błąd: cannot convert form List<String> to ArrayList<String>
Jaki jest tego powód?
edytuj
Arrays.asList() zwraca własną implementację ArrayList. Zobacz to .

Author: dasblinkenlight, 2013-09-01

8 answers

Na pierwsze pytanie spójrz na Dlaczego ArrayList ma "implements List"?


Aby odpowiedzieć na drugie pytanie

java.util.ArrayList<String> a = Arrays.asList(stra);

Jak wspomniałeś Arrays.asList zwraca swoją własną implementację AbstractList i niestety twórcy tego kodu nazwali tę klasę ArrayList. Teraz, ponieważ nie możemy rzucać poziomo, ale tylko pionowo zwracana lista tablic nie może być rzucana do java.utli.ArrayList, ale tylko do java.util.AbstractList lub jej super typów, takich jak java.util.List, dlatego twój pierwszy kod przykład działa.

 5
Author: Pshemo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:09:20

W takim razie nie byłoby zbędne implementowanie List i rozszerzanie AbstractList?

Tak, jest w 100% zbędny. Jednak implementatorzy Javy dodawali interfejsy bardzo konsekwentnie we wszystkich publicznych implementacjach biblioteki zbiorów:
  • LinkedList<E> i ArrayList<E> rozszerzają AbstractList<E>, które implementują List<E>, a następnie implementują List<E> siebie.
  • HashSet<E> i TreeSet<E> rozszerzają AbstractSet<E>, które implementują Set<E>, a następnie implementują Set<E> siebie.
  • HashMap<K,V> i TreeMap<E> rozszerzyć AbstractMap<K,V> który implementuje Map<K,V>, a następnie zaimplementować Map<K,V> siebie.

Rozumiem, że zrobili to dla celów dokumentacyjnych: autorzy chcieli pokazać, że ArrayList<E> jest przede wszystkim List<E>; fakt, że ArrayList<E> rozszerza AbstractList<E> jest mniej znaczącym szczegółem jego implementacji. To samo dotyczy innych rodzajów zbiórki publicznej.

Zauważ, że Arrays.ArrayList<E> klasa nie jest publicznie widoczna, więc jej autorzy nie dbali o to, aby włączyć List<T> wyraźnie.

Jeśli chodzi o nieudaną konwersję, nie powinno to dziwić, ponieważ Klasa wewnętrzna Arrays.ArrayList<E> i klasa Publiczna ArrayList<E> nie są ze sobą powiązane.

 25
Author: dasblinkenlight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-01 12:57:55

Tablice.asList zwraca listę . Tak więc oddanie go do ArrayList nie jest bezpieczne, ponieważ nie wiesz, jaki typ listy jest zwracany (zależy od typu tablicy, z której tworzy listę). Twój drugi fragment domaga się ArrayList bezwarunkowo. Dlatego nie powiedzie się, gdy twój pierwszy fragment kompiluje się dobrze, ponieważ oczekuje listy . You can do -

ArrayList<String> a = new ArrayList<String>(Arrays.asList(stra));
 3
Author: Sajal Dutta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-01 12:54:21

Odpowiedź na twoje pierwsze pytanie brzmi, że lista implementacyjna jest umową. Ta umowa może być zdefiniowana zarówno przez AbstractList, jak i ArrayList. ArrayList implementuje List, aby opublikować fakt, że będzie respektować umowę List w przyszłości, gdy może być konieczne rozszerzenie nie z AbstractList, które mogą lub nie mogą implementować listy.

Na drugie pytanie: Tablice.aslist zwraca listę. Może się zdarzyć, że w bieżącej implementacji zwraca ArrayList. W kolejnej wersji może zwrócić na przykład inną listę LinkedList, a umowa (określona przez podpis metody) nadal będzie przestrzegana.

 2
Author: raisercostin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-01 13:09:46

Wierzę, że jest powód. To tylko moja myśl i nie znalazłem go nigdzie w JLS.

Jeśli jestem programistą, który pisze API, które ma być szeroko stosowane, dlaczego mam to zrobić?

Nie ma absolutnie żadnego powodu, aby to robić, ale rozważ ten scenariusz, w którym napisałem interfejs List i dostarczyłem ArrayList implementację dla interfejsu List.

Do tej pory nie napisałem jeszcze żadnej klasy abstrakcyjnej AbstractList.

Jeden dnia pojawia się wymóg, w którym jestem poproszony o napisanie kilku kolejnych implementacji interfejsu List, gdzie większość z nich ma podobne lub te same konkretne metody dla metod abstract w interfejsie List.

Napiszę AbstractList z niezbędną implementacją dla wszystkich tych metod. Ale teraz nie spodoba mi się, że połowa moich klas zaimplementuje interfejs List, a połowa rozszerza AbstractList.

Poza tym nie mogę po prostu usunąć ' listy implementacji` z klasy, które pisałem wcześniej, może dlatego, że nie jest to odpowiedni czas lub nie chcę, aby cudzy kod zerwał z moim nowym wydaniem.

Uwaga jest to wyłącznie moje zdanie.

 2
Author: dharam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-01 14:46:44

1) ArrayList implements List jest zbędne, ale nadal legalne. Tylko projektanci JCF (Java Collection Framework) mogli odpowiedzieć dlaczego. Ponieważ główny projektant JCF J. Bloch nie mówi, dlaczego tak jest w "efektywnej Javie", wydaje się, że nigdy się nie dowiemy dlaczego.

2) tablice.aslist returns

public class Arrays {
   ...

    private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
...
To nie java.util.ArrayList i nie może być do niego rzucany
 2
Author: Evgeniy Dorofeev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-29 16:39:23

Będę prosta i bezpośrednia w moich odpowiedziach.

Czy nie byłoby zbędne zaimplementowanie listy, jak również rozszerzenie Streszczenia?

Tak, jest, ale zrobili to tylko po to, aby wyjaśnić kod, aby łatwo było zauważyć, że klasa implementuje interfejs List.

Tablice.metoda asList() klasy Arrays zawiera własną implementacja ArrayList. Ale ten tylko rozszerza listę abstrakcji ale nie implementuje listy.

Jak widać, to było zbędne, nie trzeba ponownie deklarować implementacji interfejsu List, jeśli AbstractList już deklaruje tę implementację.

Pojawia się błąd : nie można przekonwertować listy formularzy do ArrayList Jaki jest tego powód?

Tablice.asList () zwraca listę, może to być dowolny typ listy. ArrayList zaimplementowany w tym kodzie nie jest tą samą Arraylistą Javy.util.ArrayList, po prostu mają tę samą nazwę, ale nie są tym samym kodem.

 1
Author: ceklock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-01 15:47:22

Chcę tylko uzupełnić odpowiedzi na pytanie 2

java.util.ArrayList<String> a=Arrays.asList(stra);

Kompilator zna tylko typ zwracany Arrays.asList to List, ale nie zna jego dokładnej implementacji, która może nie być java.util.ArrayList. Więc masz ten błąd w czasie kompilacji.

Type mismatch: cannot convert from List to ArrayList

Możesz wymusić górny rzut w ten sposób,

java.util.ArrayList<String> a =(java.util.ArrayList<String>)Arrays.asList(stra);

Kod zostanie skompilowany pomyślnie, ale wystąpi wyjątek runtime,

Java.lang.ClassCastException: java.util.Arrays$ArrayList nie może być cast to java.util.ArrayList

Dzieje się tak dlatego, że java.util.Arrays$ArrayList (Typ implementacji, który zwraca Arrays.asList) nie jest podtypem java.util.ArrayList.

 0
Author: Kang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 09:47:21