Hello! Kabeh ceramah anyar wis dikhususake kanggo sinau dhaptar ArrayList . Struktur data iki trep banget lan ngidini sampeyan ngatasi akeh masalah. Nanging, Jawa nduweni akeh struktur data liyane. Kenging punapa? Kaping pisanan, amarga sawetara tugas sing wis ana amba banget, lan kanggo macem-macem tugas, struktur data sing beda-beda paling efektif . Dina iki kita bakal kenal karo struktur anyar - dhaptar link ganda LinkedList . Ayo ngerteni cara kerjane, kenapa diarani dobel disambungake, lan kepiye bedane karo ArrayList . Ing LinkedList, unsur-unsur kasebut sejatine minangka tautan ing rantai. Saben unsur, saliyane data sing disimpen, nduweni pranala menyang unsur sadurunge lan sabanjure . Link iki ngidini sampeyan pindhah saka siji unsur menyang liyane. Iki digawe kaya mangkene:
public class Main {
public static void main(String[] args) {
String str1 = new String("Hello World!");
String str2 = new String("My name is Earl");
String str3 = new String("I love Java");
String str4 = new String("I live in Moscow");
LinkedList<String> earlBio = new LinkedList<>();
earlBio.add(str1);
earlBio.add(str2);
earlBio.add(str3);
earlBio.add(str4);
System.out.println(earlBio);
}
}
Kesimpulan:
[Hello World! My name is Earl, I love Java, I live in Moscow]
Iki minangka struktur dhaptar kita: Ayo ndeleng kepiye unsur anyar ditambahake. Iki ditindakake kanthi nggunakake add()
.
earlBio.add(str2);
Ing wektu baris kode iki, dhaptar kita kalebu siji unsur - string str1
. Ayo ndeleng apa sing kedadeyan ing gambar sabanjure: Akibaté str2
, lan str1
dadi disambungake liwat pranala sing disimpen ing wong-wong mau next
lan previous
: Saiki sampeyan kudu ngerti gagasan utama dhaptar sing disambung kaping pindho. Unsur-unsur kasebut LinkedList
minangka dhaptar siji kanthi tepat amarga rantai tautan iki. Ora ana array ing njero LinkedList
, kaya ing ArrayList
, utawa sing padha. Kabeh karya karo ArrayList (saka lan gedhe) teka mudhun kanggo nggarap array internal. Kabeh karya LinkedList
teka mudhun kanggo ngganti pranala. Iki katon kanthi jelas kanthi nambahake unsur ing tengah dhaptar:
public class Main {
public static void main(String[] args) {
String str1 = new String("Hello World!");
String str2 = new String("My name is Earl");
String str3 = new String("I love Java");
String str4 = new String("I live in Moscow");
LinkedList<String> earlBio = new LinkedList<>();
earlBio.add(str1);
earlBio.add(str3);
earlBio.add(1, str2);
System.out.println(earlBio);
}
}
Nalika sampeyan bisa ndeleng, cara overloaded add()
ngidini sampeyan nemtokake indeks tartamtu kanggo unsur anyar. Ing kasus iki, kita pengin nambah baris str2
antarane str1
lan str3
. Iki sing bakal kelakon nang: Lan minangka asil ngganti pranala internal, unsur str2
kasil ditambahake menyang dhaftar: Saiki kabeh 3 unsur disambung. Saka unsur pisanan ing sadawane chain next
sampeyan bisa pindhah menyang pungkasan lan mburi. Kita wis luwih utawa kurang ngerteni sisipan kasebut, nanging kepiye mbusak unsur? Prinsip operasi padha. Kita mung nemtokake maneh pranala saka rong unsur "ing sisih" sing dicopot:
public class Main {
public static void main(String[] args) {
String str1 = new String("Hello World!");
String str2 = new String("My name is Earl");
String str3 = new String("I love Java");
String str4 = new String("I live in Moscow");
LinkedList<String> earlBio = new LinkedList<>();
earlBio.add(str1);
earlBio.add(str3);
earlBio.add(1, str2);
earlBio.remove(1);
System.out.println(earlBio);
}
}
Iki bakal kelakon yen kita mbusak unsur karo indeks 1 (ana ing tengah dhaftar): Sawise redefining pranala, kita entuk asil sing dikarepake: Boten kados mbusak, ArrayList
ora ana owah-owahan saka unsur Uploaded lan kaya. Kita mung nemtokake maneh referensi str1
lan unsur str3
. Saiki padha nuding siji liyane, lan obyek kasebut str2
"mudhun" saka rantai pranala iki lan ora ana maneh ing dhaptar.
Ringkesan cara
WisLinkedList
akeh podho karo ArrayList
cara. Contone, cara kayata add()
, remove()
, indexOf()
, clear()
, contains()
(yaiku unsur sing ana ing dhaptar), set()
(nglebokake unsur kanthi panggantos) size()
ana ing loro kelas kasebut. Senajan (kaya sing kita temokake ing conto add()
lan remove()
) akeh sing kerjane beda-beda ing njero, nanging pungkasane nindakake perkara sing padha. Nanging, LinkedList
ana cara sing kapisah kanggo nggarap wiwitan lan pungkasan dhaptar, sing ora ana ing ArrayList
:
addFirst()
,addLast()
: cara kanggo nambah unsur ing wiwitan / pungkasan dhaftar
public class Car {
String model;
public Car(String model) {
this.model = model;
}
public static void main(String[] args) {
LinkedList<Car> cars = new LinkedList<>();
Car ferrari = new Car("Ferrari 360 Spider");
Car bugatti = new Car("Bugatti Veyron");
Car lambo = new Car("Lamborghini Diablo");
Car ford = new Car("Ford Mondeo");
Car fiat = new Car("Fiat Ducato");
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
System.out.println(cars);
cars.addFirst(ford);
cars.addLast(fiat);
System.out.println(cars);
}
@Override
public String toString() {
return "Car{" +
"model='" + model + '\'' +
'}';
}
}
Kesimpulan:
[Car{model='Ferrari 360 Spider'}, Car{model='Bugatti Veyron'}, Car{model='Lamborghini Diablo'}]
[Car{model='Ford Mondeo'}, Car{model='Ferrari 360 Spider'}, Car{model='Bugatti Veyron'}, Car{model='Lamborghini Diablo'}, Car{model='Fiat Ducato'}]
Akibaté, Ford dadi ing ndhuwur dhaptar, lan Fiat ing pungkasan.
peekFirst()
,peekLast()
: bali pisanan / unsur pungkasan dhaftar. Bali manehnull
yen dhaptar kosong.
public static void main(String[] args) {
LinkedList<Car> cars = new LinkedList<>();
Car ferrari = new Car("Ferrari 360 Spider");
Car bugatti = new Car("Bugatti Veyron");
Car lambo = new Car("Lamborghini Diablo");
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
System.out.println(cars.peekFirst());
System.out.println(cars.peekLast());
}
Kesimpulan:
Car{model='Ferrari 360 Spider'}
Car{model='Lamborghini Diablo'}
pollFirst()
,pollLast()
: bali unsur pisanan / pungkasan dhaftar lan mbusak saka dhaftar . Bali manehnull
yen dhaptar kosong
public static void main(String[] args) {
LinkedList<Car> cars = new LinkedList<>();
Car ferrari = new Car("Ferrari 360 Spider");
Car bugatti = new Car("Bugatti Veyron");
Car lambo = new Car("Lamborghini Diablo");
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
System.out.println(cars.pollFirst());
System.out.println(cars.pollLast());
System.out.println("What's left on the list?");
System.out.println(cars);
}
Kesimpulan:
Car{model='Ferrari 360 Spider'}
Car{model='Lamborghini Diablo'}
What осталось в списке?
[Car{model='Bugatti Veyron'}]
toArray()
: ngasilake array saka unsur dhaftar
public static void main(String[] args) {
LinkedList<Car> cars = new LinkedList<>();
Car ferrari = new Car("Ferrari 360 Spider");
Car bugatti = new Car("Bugatti Veyron");
Car lambo = new Car("Lamborghini Diablo");
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
Car[] carsArray = cars.toArray(new Car[3]);
System.out.println(Arrays.toString(carsArray));
}
Kesimpulan:
[Car{model='Ferrari 360 Spider'}, Car{model='Bugatti Veyron'}, Car{model='Lamborghini Diablo'}]
Saiki kita ngerti cara kerjane LinkedList
lan kepiye bedane ArrayList
. Apa gunane nggunakake LinkedList
? Kaping pisanan, ing nggarap tengah dhaptar . Nglebokake lan mbusak ing tengah LinkedList
luwih gampang tinimbang ing ArrayList
. Kita mung nemtokake maneh pranala saka unsur tetanggan, lan unsur sing ora perlu "mudhun" saka rantai pranala. Nalika ing ArrayList
kita:
- priksa manawa ana cukup spasi (nalika nglebokake)
- yen ora cukup, gawe larik anyar lan salin data ing kana (nalika nempel)
- mbusak / masang unsur, lan ngalih kabeh unsur liyane menyang tengen / ngiwa (gumantung ing jinis operasi). Kajaba iku, kerumitan proses iki gumantung banget karo ukuran dhaptar. Iku siji bab kanggo nyalin / mindhah 10 unsur, nanging cukup liyane kanggo nindakake padha karo yuta unsur.
LinkedList
iku kudu luwih cepet saka ArrayList
.
Ing teori
public class Main {
public static void main(String[] args) {
List<Integer> list = new LinkedList<>();
for (int i = 0; i < 5_000_000; i++) {
list.add(new Integer(i));
}
long start=System.currentTimeMillis();
for(int i=0;i<100;i++){
list.add(2_000_000, new Integer(Integer.MAX_VALUE));
}
System.out.println("Time to run for LinkedList (in milliseconds) = " + (System.currentTimeMillis()-start));
}
}
Kesimpulan:
Время работы для LinkedList (в мorсекундах) = 1873
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 5_000_000; i++) {
list.add(new Integer(i));
}
long start=System.currentTimeMillis();
for (int i=0;i<100;i++){
list.add(2_000_000, new Integer(Integer.MAX_VALUE));
}
System.out.println("Time to run for ArrayList (in milliseconds) = " + (System.currentTimeMillis()-start));
}
}
Kesimpulan:
Время работы для ArrayList (в миллисекундах) = 181
Dumadakan! Katon yen kita nindakake operasi sing LinkedList
mesthine luwih efisien - nglebokake 100 unsur ing tengah dhaptar. Lan dhaptar kita gedhe banget - 5.000.000 unsur: ArrayList
kita kudu ngalih sawetara yuta unsur saben dilebokake! Apa sebabé kamenangané? Kaping pisanan, unsur diakses ing ArrayList
wektu sing tetep. Nalika sampeyan nuduhake:
list.add(2_000_000, new Integer(Integer.MAX_VALUE));
banjur ing kasus ArrayList
[2_000_000] iki alamat tartamtu ing memori, amarga wis Uploaded nang. Nalika LinkedList
array ora. Bakal nggoleki nomer unsur 2_000_000 ing sadawane rantai pranala. Kanggo dheweke, iki dudu alamat ing memori, nanging link sing isih kudu digayuh:
fistElement.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next.next………
Akibaté, saben selipan (pambusakan) ing tengah dhaftar, ArrayList
wis ngerti alamat pas ing memori sing kudu diakses, nanging LinkedList
isih kudu "nemokake" menyang Panggonan tengen. Kapindho , perkara kasebut ana ing struktur ArrayList
'a dhewe. Ngembangake array internal, nyalin kabeh unsur lan unsur owah-owahan ditindakake kanthi fungsi internal khusus - System.arrayCopy()
. Kerjane cepet banget amarga dioptimalake khusus kanggo proyek iki. Nanging ing kahanan sing ora perlu "stomp" menyang indeks sing dikarepake, LinkedList
pancen nuduhake dhewe luwih apik. Contone, yen sisipan dumadi ing wiwitan dhaptar. Ayo nyoba nglebokake sejuta unsur ing kana:
public class Main {
public static void main(String[] args) {
getTimeMsOfInsert(new ArrayList());
getTimeMsOfInsert(new LinkedList());
}
public static long getTimeMsOfInsert(List list) {
//write your code here
Date currentTime = new Date();
insert1000000(list);
Date newTime = new Date();
long msDelay = newTime.getTime() - currentTime.getTime(); //calculate the difference
System.out.println("Result in milliseconds: " + msDelay);
return msDelay;
}
public static void insert1000000(List list) {
for (int i = 0; i < 1000000; i++) {
list.add(0, new Object());
}
}
}
Kesimpulan:
Результат в миллисекундах: 43448
Результат в миллисекундах: 107
A asil temen beda! Butuh luwih saka 43 detik kanggo nglebokake yuta unsur ing wiwitan dhaptar ArrayList
, nalika LinkedList
rampung ing 0,1 detik! Iku sabenere kasunyatan sing ing kahanan iki LinkedList
kita ora kudu "mbukak" liwat chain pranala menyang tengah dhaftar saben wektu. Dheweke langsung nemokake indeks sing dibutuhake ing wiwitan dhaptar, lan ana prabédan ing prinsip operasi wis ana ing sisih dheweke :) Nyatane, diskusi " ArrayList
lawan LinkedList
" nyebar banget, lan kita ora bakal ngerti babagan saiki. tingkat. Ingkang utama sampeyan kudu ngelingi:
- Ora kabeh kaluwihan koleksi tartamtu "ing kertas" bakal bisa ditindakake kanthi nyata (kita ndeleng iki nggunakake conto saka tengah dhaptar)
- Sampeyan ora kudu ekstrem nalika milih koleksi ("
ArrayList
mesthi luwih cepet, gunakake lan sampeyan ora bakal salah.LinkedList
Ora ana sing wis suwe nggunakake ").
LinkedList
Joshua Bloch ujar :) Nanging, sudut pandang iki adoh saka 100% bener, lan kita yakin babagan iki. Ing conto sadurunge kita LinkedList
bisa 400 (!) kaping luwih cepet. Liyane bab iku ana tenan sawetara kahanan nalika LinkedList
iku bakal dadi pilihan sing paling apik. Nanging ana, lan ing wektu sing tepat, LinkedList
dheweke bisa nulungi sampeyan kanthi serius. Aja lali babagan apa sing diomongake ing wiwitan kuliah: struktur data sing beda paling efektif kanggo tugas sing beda. Sampeyan ora bisa ngomong kanthi yakin 100% struktur data sing bakal luwih apik nganti kabeh kondisi masalah kasebut dingerteni. Mengko sampeyan bakal ngerti liyane babagan koleksi iki, lan bakal luwih gampang kanggo nggawe pilihan. Nanging pilihan sing paling gampang lan paling efektif mesthi padha: nyoba loro data nyata saka program sampeyan. Banjur sampeyan bisa ndeleng kanthi mripat dhewe asil saka dhaptar kasebut lan sampeyan mesthi ora bakal salah :)
GO TO FULL VERSION