Hva er forskjellen mellom
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
der ia
er en rekke heltall.
Jeg fikk vite at noen operasjoner ikke er tillatt i list2
. hvorfor er det slik?
hvordan lagres den i minnet (referanser/kopiering)?
Når jeg blander listene, list1
påvirker ikke den opprinnelige matrisen, men list2
gjør det. Men fortsatt er list2
noe forvirrende.
Hvordan ArrayList
som blir upcasted til liste skiller seg fra å lage en ny ArrayList
?
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
La oss først se hva dette gjør:
Arrays.asList(ia)
Den tar en array ia
og lager en wrapper som implementerer List<Integer>
, som gjør den opprinnelige arrayen tilgjengelig som en liste. Ingenting kopieres, det opprettes bare et enkelt wrapper-objekt. Operasjoner på listeinnpakningen overføres til den opprinnelige matrisen. Det betyr at hvis du stokker om på listeinnpakningen, stokker du også om på den opprinnelige matrisen, hvis du overskriver et element, blir det overskrevet i den opprinnelige matrisen osv. Noen List
-operasjoner er selvfølgelig ikke tillatt på innpakningen, som å legge til eller fjerne elementer fra listen, du kan bare lese eller overskrive elementene.
Legg merke til at listeomslaget ikke utvider ArrayList
- det er en annen type objekt. ArrayList
har sin egen, interne matrise som de lagrer elementene i, og de kan endre størrelsen på de interne matrisene osv. Wrapperen har ikke sin egen interne matrise, den videreformidler bare operasjoner til matrisen den har fått.
På den annen side, hvis du senere oppretter en ny matrise som
ny ArrayList<Integer>(Arrays.asList(ia))
oppretter du en ny ArrayList
, som er en fullstendig, uavhengig kopi av den opprinnelige. Selv om du også her oppretter innpakningen ved hjelp av Arrays.asList
, brukes den bare under konstruksjonen av den nye ArrayList
og samles opp etterpå. Strukturen til denne nye ArrayList
er helt uavhengig av den opprinnelige matrisen. Den inneholder de samme elementene (både den opprinnelige matrisen og denne nye ArrayList
refererer til de samme heltallene i minnet), men den oppretter en ny, intern matrise som inneholder referansene. Så når du blander den, legger til eller fjerner elementer osv., forblir den opprinnelige matrisen uendret.
Dette skyldes at ArrayList
som er resultatet av Arrays.asList()
ikke er av typen java.util.ArrayList
. Arrays.asList()
oppretter en ArrayList
av typen java.util.Arrays$ArrayList
som ikke utvider java.util.ArrayList
, men bare java.util.AbstractList
.
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
I dette tilfellet er list1
av typen ArrayList
.
List<Integer> list2 = Arrays.asList(ia);
Her returneres listen som en List
-visning, noe som betyr at den bare har de metodene som er knyttet til dette grensesnittet. Derfor er det noen metoder som ikke er tillatt på list2
.
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
Her oppretter du en ny ArrayList
. Du gir den bare en verdi i konstruktøren. Dette er ikke et eksempel på casting. Ved casting kan det se mer ut som dette:
ArrayList list1 = (ArrayList)Arrays.asList(ia);