Hei! Dagens leksjon om
Det blir vanskeligere fordi vi i dag skal se under panseret
ArrayList
vil vÊre bÄde enklere og vanskeligere enn tidligere leksjoner.
ArrayList
og studere hva som skjer under ulike operasjoner. PÄ den annen side vil denne leksjonen nesten ikke ha noen kode. Det er mest bilder og forklaringer. Vel, la oss gÄ:) Som du allerede vet, ArrayList
har en vanlig array inni, som fungerer som et datalager. I de fleste tilfeller spesifiserer vi ikke den nÞyaktige stÞrrelsen pÄ listen. Men den interne matrisen mÄ ha en viss stÞrrelse! Og det gjÞr det. StandardstÞrrelsen er 10 .
public static void main(String[] args) {
ArrayList<Car> cars = new ArrayList<>();
}
La oss fÞrst se hvordan det ser ut Ä legge til nye elementer. Den fÞrste oppgaven er Ä sjekke om den interne matrisen har nok plass i den interne matrisen og om ett element til vil passe. Hvis det er plass, legges det nye elementet til pÄ slutten av listen. NÄr vi sier "til slutten", mener vi ikke den siste posisjonen i matrisen (det ville vÊrt rart). Vi mener posisjonen etter det siste gjeldende elementet. Indeksen vil vÊre cars.size()
. Listen vÄr er for Þyeblikket tom ( cars.size() == 0
). FĂžlgelig vil det nye elementet bli lagt til i posisjon 0.
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
cars.add(ferrari);
Det er tydelig nok. Hva skjer hvis vi setter inn i midten, altsÄ mellom andre elementer?
public static void main(String[] args) {
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
Car bugatti = new Car("Bugatti Veyron");
Car lambo = new Car("Lamborghini Diablo");
Car ford = new Car("Ford Modneo");
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
cars.add(1, ford);// add ford to cell 1, which is already occupied
}
Igjen, fÞrst er det en sjekk om det er nok plass i arrayet. Hvis det er nok plass, flyttes elementene til hÞyre , og starter med posisjonen der vi setter inn det nye elementet. Vi setter inn ved posisjon 1. Med andre ord, elementet fra posisjon 3 kopieres til posisjon 4, element 2 til posisjon 3, og element 1 til posisjon 2. Deretter settes vÄrt nye element inn pÄ plass. Det forrige elementet (bugatti) er allerede kopiert derfra til en ny posisjon. La oss nÄ se pÄ hvordan denne prosessen skjer hvis det ikke er noen steder Ä sette inn nye elementer i matrisen. Naturligvis er det fÞrst en sjekk for Ä se om det er nok plass. Hvis det ikke er nok plass, opprettes en ny matrise inne iArrayList
hvis stÞrrelse er stÞrrelsen pÄ den gamle matrisen ganger 1,5 pluss 1 I vÄrt tilfelle vil den nye matrisens stÞrrelse vÊre 16. Alle de gjeldende elementene vil bli kopiert dit umiddelbart. Den gamle matrisen vil bli slettet av sÞppelsamleren, og bare den nye, utvidede matrisen vil vÊre igjen. NÄ er det plass til et nytt element. Vi setter den inn i posisjon 3, som er opptatt. NÄ starter den kjente prosedyren. Alle elementene, som starter med indeks 3, flyttes en posisjon til hÞyre, og det nye elementet legges stille til. Og innsettingen er ferdig! Og vi er ferdige med innsetting. La oss nÄ snakke om Ä fjerne elementer . Du vil huske at vi fikk et problem nÄr vi jobbet med matriser: fjerning av elementer lager "hull" i en matrise.med hver fjerning, og vi mÄtte skrive vÄr egen kode hver gang for Ä utfÞre dette skiftet. ArrayList fÞlger samme prinsipp, men den implementerer allerede denne mekanismen. Slik ser det ut: Og til slutt fÄr vi det vi vil ha: Elementet lambo
er fjernet. Her fjernet vi et element fra midten. Det er klart at det gĂ„r raskere Ă„ fjerne et element fra slutten av listen, siden elementet ganske enkelt fjernes uten Ă„ mĂ„tte flytte alle de andre. La oss snakke igjen et Ăžyeblikk om dimensjonene til den interne matrisen og hvordan den er ordnet i minnet. Ă
utvide en matrise krever noen ressurser. FĂžlgelig, ikke lag enArrayList
med standardstÞrrelsen hvis du er sikker pÄ at den vil ha minst 100 elementer. Den interne matrisen mÄ utvides 6 ganger nÄr du satte inn det 100. elementet, og alle elementene mÄtte forskyves hver gang.
- fra 10 elementer til 16
- fra 16 elementer til 25
- fra 25 til 38
- fra 38 til 58
- fra 58 til 88
- fra 88 til 133 (dvs. stÞrrelsen pÄ den gamle matrisen ganger 1,5 pluss 1)
ArrayList<Car> cars = new ArrayList<>(100);
NÄ vil minnet for en matrise pÄ 100 elementer bli allokert pÄ en gang, noe som gjÞr matrisen mer effektiv (det trenger ikke Ä utvides). Denne strategien har ogsÄ en bakside. NÄr du fjerner objekter fra en ArrayList
, reduseres ikke stÞrrelsen pÄ den interne matrisen automatisk. Anta at vi har en ArrayList
med en helt full intern matrise pÄ 88 elementer: Mens programmet kjÞrer, fjerner vi 77 elementer, sÄ bare 11 gjenstÄr: Har du allerede gjettet hva problemet er? Du skjÞnner, ineffektiv bruk av minne! Vi bruker bare 11 posisjoner her, men vi har allokert minne for 88 elementer. Det er 8 ganger mer enn vi trenger! I dette tilfellet kan vi optimere minnebruken vÄr med en av ArrayList
klassens spesialmetoder:trimToSize()
. Denne metoden "trimmer" lengden pÄ den interne matrisen ned til antall elementer som for Þyeblikket er lagret i den. NÄ har vi bare tildelt sÄ mye minne som vi trenger! :)