Mengapa sekolah mengajar susunan berdasarkan Daftar? [Tutup]


36

Sebagian besar tugas di sekolah saya untuk kelas pemrograman awal mengharuskan saya menggunakan array. Saya bekerja penuh waktu sekarang, dan saya tidak pernah menggunakan array untuk proyek apa pun yang saya kerjakan. Bahkan dalam proyek yang ada saya tidak pernah melihat penggunaan array di mana pun. Menurut pendapat saya, Daftar lebih mudah digunakan dan merupakan standar. Mengapa profesor memberi tahu siswa untuk menggunakan array dalam tugas mereka? Apakah hanya agar siswa memahami dasar-dasarnya?

Karena sebagian besar universitas mengajarkan Jawa, pertanyaan ini khusus untuk Jawa.


7
Array lebih mendasar.
user253751

Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Insinyur Dunia

Jawaban:


120

Karena array mengajarkan konsep seperti pengindeksan dan batasan, dua konsep yang secara fundamental penting dalam pemrograman komputer.

Daftar bukan "standar." Ada berbagai macam ruang masalah yang cocok untuk array.


Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Insinyur Dunia

48

Mereka mungkin ingin memulai dengan struktur data yang paling akurat mewakili cara kerja komputer, jadi Anda terbiasa dengan dasar-dasar sebelum mereka mulai memperkenalkan abstraksi tingkat tinggi seperti Daftar yang membuatnya lebih mudah untuk dikerjakan. Kalau tidak, Anda tidak akan memiliki cara untuk memahami mengapa struktur atau algoritma tertentu lambat / cepat untuk beberapa operasi dan bukan yang lain; jika memori komputer benar-benar terbuat dari daftar tertaut, dunia akan menjadi tempat yang sangat berbeda.

Untuk alasan yang hampir sama, kelas pemrograman pertama saya di perguruan tinggi adalah di C, dan seluruh kelas semua dalam C ++, Java dan bahasa lainnya. Bukan karena C entah bagaimana lebih baik atau lebih mudah, itu karena C (dan Array) tidak menyembunyikan apa pun dari Anda.


7
Daftar lebih mudah untuk dikerjakan dengan kode nyata, tetapi sebuah array lebih mudah untuk dipahami (sepenuhnya), dan lebih penting untuk dipahami karena mereka mendasar dan universal, sedangkan daftar (Java) tidak. Setidaknya itu menurut saya.
Ixrec

21
Tugas di mana Anda menyimpan barang-barang dalam array dan mengaksesnya nanti adalah tugas struktur data . Anda mungkin tidak menyadarinya. Anda harus bertanya pada diri sendiri, apa yang menghasilkan insinyur yang lebih baik, memahami model komputasi dasar, atau mempelajari perpustakaan standar bahasa? Konsensus umum (dan saya setuju, fwiw) adalah bahwa Anda tidak akan memahami banyak isi perpustakaan tanpa terlebih dahulu memahami dasar-dasar perhitungan.
Kent A.

12
LinkedList, ArrayList, OrderedList, dll. Daftar mana yang harus Anda pelajari terlebih dahulu? Bagaimana Anda menghargai apa yang mereka lakukan untuk Anda jika Anda tidak mengerti mengapa mereka ada di tempat pertama?
Kent A.

10
+1 ke @KentAnderson. Sekolah harus menghasilkan insinyur yang memahami struktur data pada tingkat rendah; idealnya, menghasilkan insinyur yang dapat dengan mudah menerapkan struktur dasar dalam C. Program lain hanyalah JavaSchool.
Christian Willman

2
"Mereka mungkin ingin memulai dengan struktur data yang paling akurat mewakili cara kerja komputer" - Jadi, bagaimana dengan komputer dengan memori terstruktur-daftar atau terstruktur-objek? "Bukan karena C entah bagaimana lebih baik atau lebih mudah, itu karena C (dan Array) tidak menyembunyikan apa pun darimu." - Kecuali jika komputer Anda tidak memiliki pointer, seperti AS / 400, di mana C pada dasarnya berjalan dalam VM dan menyembunyikan semuanya untuk Anda.
Jörg W Mittag

21

Jawaban di atas memang bagus, tetapi ada satu lagi yang saya pikirkan. main()Metode Java berarti bahwa siswa menjumpai susunan dasar sangat awal, seringkali begitu hari pertama kelas. Mengapa?

public static void main(String[] args)

Ini hal pertama yang harus Anda hadapi untuk menulis Hello World dan seterusnya. (Saya telah melihat beberapa kursus menggunakan IDE pengajaran seperti BlueJ pada awalnya, yang memungkinkan Anda untuk menunjuk-dan-klik untuk menjalankan metode sewenang-wenang, tetapi kami akan mengesampingkannya ...) Meskipun mungkin ada baiknya untuk menggunakan beberapa kata kunci ini sebentar, cepat atau lambat sebagian besar guru akan ingin menjelaskannya. Memang, pertanyaan tes tingkat pemula klasik adalah meminta siswa untuk memberikan makna dari setiap kata kunci dalam program Hello World dasar. Dan apa yang kita temukan sebagai bagian dari tanda tangan metode utama kita? Array (Alasannya, sebagian, historis. ArrayList tidak ada di Java 1.0). Array adalah bagian dari set dasar pengetahuan itu. Daftar tidak.

Yang mengatakan, itu tidak biasa bagi kelas untuk memperkenalkan ArrayList sedikit kemudian ke dalam kursus, terutama sekali objek dan penggunaannya telah dibahas. Bahkan kurikulum Ilmu Komputer AP untuk Java mencakup ArrayList (saya tahu sudah terbiasa, dan Google tampaknya menunjukkan bahwa itu masih berlaku), meskipun mengabaikan fakta bahwa ArrayList mengimplementasikan Daftar dan sisa Kerangka Kerja Koleksi.

Akhirnya, pengalaman saya bahwa program CS universitas menggunakan Java sebagai sarana untuk menjelajahi konsep CS dan pemrograman daripada untuk mengajar siswa bagaimana menjadi pengembang Java yang baik. Beberapa program mungkin lebih fokus untuk menghasilkan pengembang profesional sementara yang lain lebih fokus pada teori, tetapi dalam banyak kasus, ada banyak yang harus dipelajari tentang bagaimana menggunakan Java dalam pekerjaan profesional nyata yang tidak akan diajarkan di sebagian besar kurikulum perguruan tinggi. Ini berkisar dari pola desain dan teknik seperti yang ada di Java Efektif hingga kerangka kerja seperti Spring, Hibernate, atau JUnit, atau bahkan hal-hal yang lebih umum seperti JSP atau JDBC. Dengan filosofi itu dalam pikiran, menekankan array pada ArrayList yang lebih umum digunakan lebih masuk akal.


3
@Dupuplikator yakin. Itu tidak relevan dengan poin saya tentang array, jadi saya menghilangkannya. Saya juga tidak memasukkan System.out.println ("Hello World!"); antara.
Zach Lipton

+1 untuk konsep vs. teknik yang efektif untuk "dunia nyata". Tidak ada yang mengajar kontrol versi, setidaknya tidak ketika saya masih di sekolah - tapi kemudian saya kuno :)
David

Saya mengambil kelas sistem operasi di mana kami harus mengimplementasikan berbagai bagian seperti penjadwal; kami fokus pada satu bagian seperti itu pada satu waktu (secara eksklusif) karena pada saat itu kami tidak mampu berbuat lebih banyak . Tetapi berpikir tentang mencoba membuat semua karya itu bekerja pada saat yang sama adalah apa yang memberi saya (permulaan) apresiasi terhadap kompleksitas pengembangan "dunia nyata" / "pemrograman dalam skala besar".
David

14

Salah satu alasan mengapa kelas-kelas pemrograman tahun pertama menggunakan array adalah warisan: itulah bagaimana para profesor awalnya mempelajarinya sebelum kita mulai menggunakan perpustakaan standar dengan daftar dinamis dimasukkan. Menggunakan tipe data primitif juga lebih umum berlaku: array ada di hampir semua komputer bahasa di bawah matahari (dan dapat diimplementasikan dalam beberapa instruksi perakitan). Ketika saya pertama kali belajar pemrograman, mengimplementasikan daftar tertaut adalah salah satu tugas.

Jauh lebih mudah untuk memulai dari prinsip pertama dan kemudian berkata "Itu struktur dasar. Bahasa ini (atau perpustakaannya) memberi Anda struktur data tingkat tinggi ini yang melakukan semua itu, tetapi memberi Anda x, y, dan z," daripada itu untuk mengatakan "Jadi itu struktur data tingkat tinggi ini, sekarang di sini apa yang ada di balik tudung." Mempelajari alasan untuk menggunakan LinkedList vs. ArrayList (atau HashSet vs. TreeSet) biasanya merupakan kursus Algoritma tahun kedua atau ketiga. Daftar dan Peta memiliki antarmuka yang sama dan memberikan hasil yang sama, tetapi dapat memiliki perilaku yang berbeda secara dramatis dalam aplikasi ukuran apa pun. Dan begitu Anda keluar dari Pemrograman 101, tidak ada jaminan bahwa Pemrograman 102 akan menggunakan bahasa yang sama. Jika Anda mulai dari konsep array, Anda bisa mengatakan "

Alasan lain untuk memilih "array" daripada "Daftar" dalam kursus pengantar adalah bahwa array pada dasarnya mudah dipahami: Array 20 bytesmembutuhkan 20 byte (ditambah pasangan untuk menunjukkan akhir array atau panjangnya, tergantung pada implementasi ).

"Daftar" adalah ketel ikan yang sama sekali berbeda dan dapat diimplementasikan dengan berbagai cara (ArrayList, LinkedList, dan mungkin pasangan yang saya lupa), dengan karakteristik kinerja yang berbeda secara fundamental. Tanpa memahami keberanian dari apa kelas Daftar berbeda lakukan, Anda tidak dapat memiliki diskusi bermakna ketika Anda harus menggunakan List foo = new ArrayList()vs List foo = new LinkedList(). Jika Anda mencoba membuat siswa menggunakan implementasi Daftar, seseorang akan bertanya mengapa Anda menggunakan ArrayList alih-alih salah satu implementasi lainnya. Dan "ArrayList" termasuk kata "Array" dan didukung oleh satu, jadi itu sebenarnya bukan lompatan logika besar dari "array" ke "ArrayList".

Berlawanan dengan kepercayaan populer, ADA situasi di mana masuk akal untuk menggunakan array di Daftar, terutama ketika Anda berurusan dengan daftar ukuran statis. Berikut adalah pasangannya:

  • Pencarian dan pengulangan sedikit lebih cepat karena Anda tidak berurusan dengan overhead pemanggilan metode: foo[n]dereferensi dan melakukan beberapa aritmatika penunjuk di belakang layar, sementara foo.get(n)harus melakukan dereferensi, melakukan pemanggilan metode, melakukan dereferensi kedua, dan kemudian mungkin melakukan aritmatika penunjuk (jika Anda menggunakan ArrayList; LinkedLists berpotensi perlu mengulangi setiap elemen Daftar).
  • Inisialisasi jauh lebih bersih: int[] foo = new int[]{1, 2, 3, 4, 5}vs saran dalam pertanyaan StackOverflow lain

Skenario lain ketika array mengalahkan array secara besar-besaran adalah ketika urutan di mana elemen menjadi tersedia cocok dengan urutan di mana posisi akhir mereka akan diketahui, tetapi tidak cocok dengan urutan akhir. Jika permadalah suatu int[256]yang memiliki permutasi, seseorang dapat dengan mudah membalikkannya dengan sebuah array: int[] inv = new int[256]; for (int i=0; i<256; i++) inv[perm[i]]=i; Saya tidak berpikir apa pun yang bisa dituliskan oleh seseorang ArrayList<>akan sebersih itu.
supercat

@supercat Itu tidak benar-benar dengan masalah dengan array dinamis, hanya implementasi tertentu; ArrayListbisa dengan mudah diberi konstruktor yang membuat daftar standar-inisialisasi ukuran tertentu.
Doval

Apakah Anda memiliki sumber untuk mendukung klaim bahwa daftar array harus berurusan dengan overhead metode pemanggilan? Secara teori memang, tetapi dalam praktiknya saya akan terkejut jika getdan settidak mendapatkan inline.
Doval

@Doval: Tidak ada alasan bahasa / kerangka kerja yang dirancang dengan baik tidak boleh menyediakan tipe array dinamis yang dapat dengan mudah menambahkan item di luar urutan, tetapi Java tidak menyediakan tipe seperti itu.
supercat

@Doval: Sekalipun getdan setbisa disatukan , sesuatu seperti tidak myList.set(23,myList.get(23)+1)akan seefisien apa pun myArray[23]+=1. Lebih jauh, bahkan untuk jenis yang tidak perlu tinju, saya akan sangat terkejut jika ada JITter yang bisa setara dengan for (i=0; i<1000; i++) myList2.set(i+2000,myList2.get(i+3000));apa pun yang kinerjanya hampir System.arrayCopy(myArray1,3000,myArray2,2000,1000); sama. tetapi Java tidak.
supercat

7

Java memungkinkan variabel jenis apa pun untuk disimpan ke dalam array. Sebaliknya, ArrayListhanya memungkinkan penyimpanan referensi. Dengan demikian, orang mungkin tidak dapat berdiskusi ArrayListtanpa membahas terlebih dahulu bagaimana tinju otomatis akan mengubah primitif menjadi tipe referensi, dan bagaimana terkadang unboxing otomatis akan mengkonversi tipe referensi menjadi primitif:

for (int i=10; i<=10000; i*=10)
{
    ArrayList<Integer> l = new ArrayList<Integer>();
    l.add(i);
    l.add(i);
    l.add(l.get(0));
    System.out.print("i=" + i);
    System.out.print(" #0==i:" + (l.get(0)==i));
    System.out.print(" #1==i:" + (l.get(1)==i));
    System.out.print(" #2==i:" + (l.get(2)==i));
    System.out.print(" #0=#1:" + (l.get(0)==l.get(1)));
    System.out.print(" #1=#2:" + (l.get(1)==l.get(2)));
    System.out.println(" #0=#2:" + (l.get(0)==l.get(2)));
}

Jika kode tersebut menggunakan int[3]bukan daripada ArrayList, tidak akan ada kejutan. Ketiga elemen akan membandingkan sama isatu sama lain. Menggunakan ArrayList, bagaimanapun, meskipun semua tiga unsur daftar akan selalu membandingkan sama dengan i, dan yang ketiga pertama dan akan selalu membandingkan sama satu sama lain, dua elemen pertama hanya akan sama satu sama lain ketika iadalah 1, 10, atau 100, tapi (pada sebagian besar implementasi) bukan kapan i1000 atau 10000.


Bisakah Anda menjelaskan mengapa # 0 dan # 1 akan sama ketika mereka 1 atau 10 atau 100? Saya mengikuti sampai titik itu.
Matius Baca

2
@MatthewRead: IntegerKelas memiliki kelas bersarang yang disebut IntegerCacheyang menampung Integerobjek yang diinisialisasi untuk rentang nilai yang biasanya meluas -128..127; tinju nilai di luar rentang itu akan membutuhkan membuat objek baru, tetapi tinju nilai dalam rentang yang di-cache hanya akan mengembalikan referensi ke salah satu objek pra-diinisialisasi yang disimpan di IntegerCache.cache. Setiap programmer Java yang baik perlu menyadari bahwa dua Integervariabel tipe yang merangkum nilai yang sama dapat atau tidak bisa dibandingkan, tetapi memperkenalkan gagasan itu terlalu dini dapat membuat siswa melarikan diri dalam ketakutan.
supercat

Huh, tidak akan pernah menduga itu karena benda yang sudah diinisialisasi. Terimakasih atas infonya!
Matius Baca

1
@MatthewRead: Saya berharap Java telah melarang beberapa jenis konversi implisit dengan ==. Mengingat kemungkinan bahwa auto-unboxing dapat melempar, saya cenderung untuk tidak mengizinkannya sama sekali, tetapi perilakunya dengan ==sangat mengerikan. The ==Operator juga berperilaku buruk dalam kasus-kasus seperti 16777217==16777216f[laporan yang benar], dan konversi implisit untuk long v=Math.Round(123456789), w=Math.Round(123456789012345)cenderung menjadi tak terduga [Anda bisa menebak apa yang orang-orang ekspresi akan menghasilkan?]
supercat

Adapun IntegerCache, tentu ada saat-saat itu dapat membantu kinerja, tetapi sering dapat menyebabkan kode yang Just Plain Wrong untuk pekerjaan agak-agak. Dalam beberapa hal, saya berharap ada mode di mana tinju akan secara acak mengembalikan objek dari dua cache integer dan kuasi secara acak mengganti item cache dengan yang baru, sehingga kode yang mengandalkan perilaku tinju nilai -128..127 akan menjadi tidak mungkin berhasil untuk waktu yang lama.
supercat

6

Saya pikir masuk akal untuk mengajarkan cara menggunakan array terlebih dahulu karena fakta yang ArrayListmenggunakan array secara internal. The ArrayListkelas memiliki variabel anggota yang disebut elementDatayang merupakan Objectarray yang.

Dari ArrayList kode sumber JDK :

/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer.
 */
private transient Object[] elementData;

Ketika Anda menambahkan, memperbarui, mengambil atau menghapus elemen dari ArrayListitu menggunakan array internal ini untuk melakukan operasi itu. Seperti yang telah ditunjukkan oleh pengguna Ixrec - ArrayListhanyalah abstraksi tingkat tinggi yang biasanya lebih mudah untuk dikerjakan.


Tetapi sebuah array menggunakan pointer ke blok memori, secara internal. Mengapa memulai pada tingkat abstraksi tertentu?

Pertanyaan ini ditandai sebagai Java- Ia bertanya mengapa mengajarkan array ketika biasanya Anda dapat menggunakan ArrayList. Java tidak memiliki pointer. Benar atau salah, saya berpendapat bahwa C / C ++ adalah bahasa yang lebih baik untuk memulai siswa daripada di Jawa. Banyak topik dalam pemrograman dapat lebih dipahami dengan memiliki pengetahuan tentang C / C ++.
Derek W

3

Dengan asumsi daftar itu memang lebih mudah untuk dikerjakan, seperti yang Anda katakan - itu tidak masalah. Belajar lebih tentang "dasar ke rumit" daripada "mudah ke susah". Jika dasar-dasarnya tidak penting, maka ilmu komputer tidak akan menjadi bidang akademik. Anda bisa belajar bagaimana mengklik bersama aplikasi menggunakan kerangka / pustaka yang ada dari tutorial online. (Tentu saja, seseorang harus menulis perpustakaan itu ... dan seseorang harus mengimplementasikannya ArrayListsejak awal ....)


Dalam banyak kasus yang menggunakan ArrayListbisa lebih baik ditangani dengan menggunakan array yang terpisah dan "liveItems" menghitung, kecuali bahwa tidak ada cara mudah untuk bekerja dengan array dan menghitung bersama kecuali dengan menjumlahkannya.
supercat

2

Itu karena hal terpenting dalam pendidikan akademik adalah mengajarkan Anda untuk menggunakan terminologi yang benar untuk menggambarkan hal-hal yang Anda lakukan.

Daftar adalah sesuatu yang lain array itu. dan Anda tidak dapat menggunakan java.util.Listdi Jawa karena itu adalah antarmuka. Anda biasanya menggunakan java.util.ArrayListyang menjadi implementasi Daftar, bukan daftar, tetapi pembungkus objek di sekitar array dinamis. Jadi Anda mengatakan Anda menggunakan 'Daftar' tetapi Anda menggunakan array.

Sangat masuk akal untuk melewati kekacauan terminologis itu dan cukup menggunakan array untuk mempelajari apa itu array. Jika Anda menggunakan array di Jawa, setidaknya Anda menggunakan array.

Jujur, itu juga argumen mengapa mengajar pemrograman dengan Java bukanlah ide yang baik. Sulit untuk mempelajari konsep dasar pemrograman dengan benar.


bagaimana dengan hashmap? sebuah array hanyalah sebuah tipe dari hashmap, dengan cara ..
Thufir

@ Thufir bagaimana sebuah array menjadi sebuah hashmap? Itu adalah struktur data yang sangat berbeda.
Danubian Sailor

Anda bisa mewakili array dengan hashmap. mana yang lebih "mendasar"? Saya berpendapat bahwa hashmap lebih menarik secara konsep.
Thufir

1
@Thufir tidak, kamu tidak bisa. Anda hanya bisa meniru. Secara internal setiap struktur data akan seperti apa adanya. Itu adalah hal-hal yang secara fundamental dan konseptual berbeda. Inilah sebabnya mengapa ide buruk untuk mulai belajar pemrograman dengan bahasa yang sangat abstrak seperti Java atau JavaScript. Tidak jelas di sana, apa struktur data sebenarnya.
Danubian Sailor

1

Anda benar-benar tidak pernah melihat atau menggunakan array sama sekali? Kami menggunakannya sepanjang waktu, di samping daftar. Kami biasanya tidak menggunakan Java, tetapi kami menggunakan banyak bahasa lain yang memiliki kesamaan.

Antara array dan Daftar, bobot seseorang lebih ringan dan, selain itu, lebih to-the-point, sedangkan yang lain mendapat lebih banyak fungsi. Sebagai aturan umum dalam pemrograman, ketika ada dua jenis yang serupa yang pada dasarnya dibagi di sepanjang garis-garis itu, Anda harus memilih yang lebih ringan kecuali Anda benar-benar membutuhkan yang lebih bagus. Selain mengurangi overhead, ini sebenarnya membantu menjaga jumlah kekacauan dan kondisi dalam program dan khususnya kodenya . Jika terjadi kesalahan selama pengujian, Anda memiliki lebih sedikit tempat untuk dilihat; dan yang lebih penting dalam hal susunan vs. Daftar, orang-orang mendapatkan gagasan yang lebih baik tentang ruang lingkup terbatas dari apa yang sebenarnya Anda gunakan dan coba lakukan dengannya.

Dan ya, dari sudut pandang akademis, ada alasan tambahan untuk mengajarkan dasar-dasar kepada siswa. Namun ini sedikit lebih dalam. Array dan Daftar adalah contoh yang baik dari jenis bulkier yang sering hanya dibangun di atas, dan sering hanya membungkus, contoh-contoh yang mendasari dari jenis yang lebih ringan. Bahkan ketika Daftar tidak memiliki array yang mendasarinya, mereka berperilaku secara lahiriah seperti mereka. Salah satu bagian dari mengajar seseorang apa itu Daftar adalah untuk mengajar mereka apa itu array.

Saya bisa melihat ini mungkin keluar dari tangan dalam bahasa seperti C ++, di mana array pada dasarnya tidak bisa lebih dilucuti daripada mereka, tetapi dalam bahasa tingkat yang lebih tinggi, mereka hampir Daftar untuk diri mereka sendiri. Jika mereka sesuai dengan kebutuhan Anda dengan sempurna dalam situasi tertentu, mengapa Anda harus menggunakan sesuatu yang lain?


Saya tidak akan mengatakan daftar memiliki fungsionalitas "lebih", sama seperti ia memiliki fungsionalitas "berbeda". Yang baru T[]akan siap, tepat di luar gerbang, untuk menerima item dalam urutan apa pun, sementara yang ArrayList<T>mengharuskan item ditambahkan, agar, sebelum mereka dapat dimodifikasi. A T[]dapat menyalin rentang item yang sewenang-wenang ke kisaran ukuran yang sama dari item lain secara T[]relatif cepat, sementara ArrayList<T>akan membutuhkan membaca item secara terpisah dari satu daftar dan menyimpannya ke yang lain - jauh lebih lambat dan kurang nyaman.
supercat
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.