ArrayList vs LinkedList vs Vector

Það er miklu auðveldara að landa starfi í hlutverki hugbúnaðarverkfræðinga en fólk heldur. En í sumum tilvikum brást meirihluti fólks með margra ára reynslu í þessari sérþekkingu framboð sitt. „Hvað er vandamál?“ Spurningin dælir upp í höfðinu á mér.

Ég hef notið tíma minnar þar sem hugbúnaðarverkfræðihlutverkið elska enn það sem ég er að gera með kóðann minn síðustu 6 ár. Á þeim tíma hef ég upplifað ótrúlega reynslu af viðtölum við marga umsækjendur um hugbúnaðarverkfræði. Í hverju viðtalsferli geri ég ekki aðeins ráð fyrir að frambjóðendurnir séu vel undirbyggðir í efnum eins og góðum hugbúnaðarhönnunarreglum, stigstærð kóðaarkitektúr og prófun heldur einnig þekkingu þeirra í grunngögnum gagnagerðar og reiknirit í hugbúnaðarverkfræði. Ég var svo sorgmædd þegar margir frambjóðendur skildu ekki grunninn.

Fyrir utan að vera fljótur námsmaður sem getur lært ný ramma, verkfæri eða jafnvel forritunarmál á skömmum tíma, þá hefur traustur skilningur á gagnauppbyggingu ein lykilþekking sem þú ættir að hafa ef þú vilt stunda feril sem hugbúnaðarverkfræðingur.

Uppbygging gagna er sérstök leið til að geyma og skipuleggja upplýsingar í tölvu svo hægt sé að sækja og nota sem afkastamestu. Mismunandi tegundir gagnagerðar eru ætlaðir fyrir mismunandi tegundir af forritum og sumir eru mjög sérhæfðir í tilteknum verkefnum. - Wikipedia

Af hverju gagnauppbygging verður ein mikilvæga þekkingin sem þarf að hafa? Uppbygging gagnanna og reiknirit bjóða upp á aðferðir til að meðhöndla gögnin á skilvirkan hátt. Ef frambjóðendurnir vita ekki um gagnaskipulag og reiknirit er hugsanlegt að þeir geti ekki skrifað skilvirkan kóða til að meðhöndla gögnin. Að vita hvernig gagnagerðin geymir gögn sín, hvernig þau standa sig og hvenær á að nota þau með fyrirfram skilgreindu tækniaðferð mun bæta tímann sem þarf til að leysa vandann. Ein af þeim spurningum sem frambjóðendur svara oft er ekki

Hvaða betri, ArrayList, LinkedList eða Vector?

Listi

Áður en þú svarar spurningunni er gott að vita hvað listinn er. Listi er einn af abstrakt gagnategund (ADT) sem geymir þætti þess í röð og gerir okkur kleift að bæta við, fjarlægja og fá aðgang að þætti þess með því að nota vísitölu. Array er eitt af gagnagerðunum sem útfærir ADT listann. Í Array getum við bætt við, eytt og fengið frumefni með því að nota vísitölu. ArrayList, LinkedList og Vector eru annað dæmi um gagnagerð sem innleiðir ADT List. Þó að Array hafi kyrrstöðu þegar það lýsti yfir, þá hafa ArrayList, LinkedList og Vector kraftmikla stærð (hægt að breyta stærð). Ef fylki er lýst með lengd 7, þá mun hún hafa lengdina 7 þar til lok gildissviðs hennar. Þó ArrayList, LinkedList og Vector geti geymt gögn eins mikið og mögulegt er, þar sem mörkin eru samtals tiltækt minni.

Java Collection Framework. Heimild: Wikipedia

Í Java Collection Framework er ADT listinn útfærður sem viðmót sem kallast List og ArrayList, LinkedList & Vector eru steypuflokkurinn sem útfærir Listi tengi. Þar sem þessir steypuflokkar útfæra sama viðmót, verða þessir flokkar að hafa sömu virkni vegna þess að fyrir alla flokka sem ekki eru abstraktir sem útfæra tengi, er krafist til að útfæra allar óhlutbundnar aðferðir sem lýst er yfir í viðmótinu.

Hvernig gögn eru geymd

Grundvallarmunur gagnagrunna þriggja hér að ofan er hvernig þeir geyma gögn sín sem veldur mismunandi afköstum fyrir mismunandi aðgerðir. Í Java (og einnig notað í Kotlin), ArrayList og Vector notar Array til að geyma þætti þess, á meðan LinkedList geymir þætti þess í tvöfalt tengdum lista.

Í tölvunarfræði er tvöfaldur tengdur listi tengdur gagnaskipulag sem samanstendur af mengi af raðtengdum gögnum sem kallast hnútar. Hver hnútur inniheldur tvo reiti, kallaðir hlekkir, sem eru tilvísanir í fyrri og næsta hnút í röð hnúta. - Wikipedia
ArrayList (efst) vs LinkedList (neðst). Heimild https://dzone.com/storage/temp/895349-arraylist-linkedlistt.png

Í LinkedList getur fyrsti hnúturinn vitað um hinn hnútinn. Seinni hnúturinn þekkir fyrsta og þriðja hnútinn. Þriðji hnúturinn þekkir annan og fjórða hnútinn. Og svo framvegis, hnút getur vitað fyrri hnút og næsta hnút. Sérstaklega fyrir fyrsta hnútinn í LinkedList verður enginn fyrri hnút og einnig síðasti hnúturinn í LinkedList verður enginn næsti hnútur.

Hérna er kóðinn hvernig ArrayList geymir þætti sína í Array.

/ **
 * Array biðminni sem þættir ArrayList eru í
 * geymd. Afkastageta ArrayList er lengd þessa
 * fylki biðminni. Allir tómir ArrayList með elementData ==
 * DEFAULTCAPACITY_EMPTY_ELEMENTDATA verður stækkað til
 * DEFAULT_CAPACITY þegar fyrsta þættinum er bætt við.
 * /
tímabundinn hlutur [] elementData; // ekki einkaaðila til að einfalda hreiður
                                // bekkjaraðgang

Og hér er hvernig Vector geymir þætti sína einnig í Array.

/ **
 * Fylkisstuðpúði sem íhlutir vektorar eru í
 * geymd. Geta vigursins er lengd þessarar fylkis
 * stuðpúði, og er að minnsta kosti nógu stór til að innihalda allar vektoranna
 * þættir.
 *
 * 

Allir fylkisþættir sem fylgja síðasta þættinum í Vector  * eru núll.  *  * @rað  * / verndaður hlutur [] elementData;

Í ofangreindum kóðaútgáfu getum við séð að bæði ArrayList og Vector geyma þætti þess í breytu sem heitir elementDatawith Object [] sem gerð. Af hverju mótmæla []? Object er ofurflokkur allra flokka í Java. Með því að skilgreina elementData sem Object [], þá gæti elementData geymt ýmsar gerðir af þáttum, það gæti verið String, Heiltala, Tvöfaldur, Flot eða sérsniðinn flokkur eins og Pair, TextView og svo framvegis.

Af hverju ArrayList og Vector notar Array til að geyma gögn þess? Eins og áður sagði, þó að ArrayList og Vector noti fylki til að geyma gögn sín, þá hafa ArrayList og Vector getu til að hafa kvikar stærðir (hægt er að breyta stærð). Þegar fylkingin sem notuð er í ArrayList og Vector er full geta þau „vaxið“ til að auka getu hennar. ArrayList og Vector auka getu sína með því að búa til nýja Array með stærri stærð en fyrri stærð, og afritaðu síðan alla þætti úr gamla Array í nýja Array með því að nota skipunina Arrays.copyOf. Hérna er kóðatöflu forritsins á ArrayList til að stækka getu þess (heimild: ArrayList.java).

/ **
  * Eykur getu til að tryggja að það geti haldið að minnsta kosti
  * fjöldi þátta sem tilgreindir eru með lágmarksgetu rifrildi.
  *
  * @ Param mín. Hæfileiki tilætluð lágmarksgetu
  * /
  einkarekið tóm vaxa (mill. mín. getu) {
      // flóð-meðvitund kóða
      int oldCapacity = elementData.length;
      int newCapacity = oldCapacity + (oldCapacity >> 1);
      if (newCapacity - minCapacity <0)
          newCapacity = minCapacity;
      ef (newCapacity - MAX_ARRAY_SIZE> 0)
          newCapacity = largeCapacity (minCapacity);
      // minCapacity er venjulega nálægt stærð, svo þetta er sigur:
      elementData = Arrays.copyOf (elementData, newCapacity);
  }

Og hér er hvernig Vector stækkar getu sína (uppspretta: Vector.java)

einkarekið tóm vaxa (mill. mín. getu) {
    // yfirborðsmeðvitað kóði
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + ((getuIncrement> 0)?
                                     getuIncrement: oldCapacity);
    if (newCapacity - minCapacity <0)
        newCapacity = minCapacity;
    ef (newCapacity - MAX_ARRAY_SIZE> 0)
        newCapacity = largeCapacity (minCapacity);
    elementData = Arrays.copyOf (elementData, newCapacity);
}

Útfærsla vektor er næstum því eins og ArrayList og eini munurinn er að allar aðgerðir í Vector eru samstilltar sem gerir allar aðferðir sem snerta innihald Vector er þráður öruggur.

Svo hver betri, ArrayList, LinkedList eða Vector? Til að svara þessari spurningu er hægt að bera saman árangur fyrir algengar aðgerðir í ArrayList og LinkedList. Þar sem útfærsla ArrayList og Vector er nánast eins, væri árangur þeirra næstum sá sami.

Árangurssamanburður á milli ArrayList og LinkedList

Af töflunni hér að ofan getum við séð að það eru engin silfurskotholti fyrir allar aðgerðir. ArrayList er betri en LinkedList í handahófi (fá). ArrayList betri en LinkedList vegna þess að ArrayList geymir þætti sína í Array á meðan LinkedList geymir þætti þess í tengdum hnút. Til dæmis, til að fá 5. þáttinn, þá geta ArrayList og Vector beint fengið þættinn með því að nota vísitölu þar sem ArrayList og Vector er í raun fylki, en LinkedList verður að vera ítrekað til að komast að því að fimmta þátturinn, því í LinkedList getum við aðeins vitað fyrsta og síðasti þátturinn.

Fyrir insertFirst og deleteFirst er LinkedList betri en ArrayList. ArrayList krefst mikillar fyrirhafnar til að bæta við þætti í upphafi (fyrsta vísitalan) eða eyða fyrsta þættinum vegna þess að ArrayList verður að færa eftirfarandi þætti eftir viðbót eða eyðingu. Þó að LinkedList þurfi aðeins að skipta um / setja ábendingar sínar. Eins og fyrir aðrar aðgerðir hafa bæði ArrayList og LinkedList tiltölulega sömu frammistöðu.

Svo hver betri, ArrayList, LinkedList eða Vector? Fer eftir þínum þörfum. Ef þú notar handahófskennt aðgang (fá) oftar, þá er ArrayList og Vector góður kostur. Veldu vektor ef þig vantar þráð-öruggt safn. En ef þú gerir oft viðbót eða eyðingu á fyrstu stöðunni (vísitölunni), þá er LinkedList betra val.

Það er annað ADT sem er almennt notað við þróun forrita eins og Set, Map og PriorityQueue. Til að vita hvernig þeir geyma gögn sín, hvernig þau vinna og hvenær á að nota, haltu áfram að fylgjast með Mediuminu mínu.