beginning java [thai]

246
ลั่นฟา ชุมสาย ภาควิชาคอมพิวเตอรธุรกิจ วิทยาลัยฟารอีสเทอรน เริ่มตนกับ Java ฉบับเริ่มตน (จริง )

Upload: atong-vongnat-

Post on 27-Oct-2014

912 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Beginning JAVA [Thai]

ลนฟา ชมสาย

ภาควชาคอมพวเตอรธรกจ

วทยาลยฟารอสเทอรน

เรมตนกบ Java ฉบบเรมตน (จรง ๆ)

Page 2: Beginning JAVA [Thai]

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

คานา หนงสอเลมนเขยนขนมาเพอเปนแนวทางใหนกศกษา วทยาลยฟารอสเทอรน ใชเปนคมอในการเรยนวชา หลกการเขยนโปรแกรมคอมพวเตอร (เบองตน) เนองจากวาในระยะเวลา สองถงสามปทผานมา หนงสอททางภาควชาคอมพวเตอรธรกจใชเปนหนงสออางองในการเรยนการสอนนน โดยสวนใหญแลวจะเปน หนงสอทแตงโดยชาวตางชาต ทาใหการใชหนงสอเหลานนในการประกอบการเรยนของนกศกษาเปนไปดวยความลาบาก เพราะตองใชเวลานานในการแปล ถงแมวาไดรบความชวยเหลอจาก อาจารยหลาย ๆ ทานในภาควชา ในการชวยชแนะ ชวยแปล แตกเปนไปไดเพยงนอยนดเทานน ผเขยนไดเลงเหนถงความสาคญของการมหนงสอไวอานเอง ในเวลาทไมสามารถเขาหาอาจารยได จงไดพยายามเขยนหนงสอเลมนขน เพอใหเปนคมอทนกศกษาสามารถนาไปใชในการคนควาหาความรในเรองของการเขยนโปรแกรมอกทางหนง หนงสอเลมน เปนไดเพยงคมออางองเบองตน ในการเขยนโปรแกรมคอมพวเตอรดวยภาษา Java เทานน เนองจากวา Java เปนภาษาท ถาผอานตองการทจะรถงการใชอยางละเอยด จะตองใชเวลาในการศกษาคนความากพอสมควร ยงมหนงสออกหลายเลมทสามารถนามาใชเปนแบบอยางในการเขยนโปรแกรมได ผเขยนหลายทานไดนาเอาบทความ ตารา และขอชแนะในการใชภาษา Java ขนไปเกบไวใน web site หลายแหงผอานควรใช web site เหลานชวยในการศกษา คนควาเพอใหการเขยนโปรแกรมดวยภาษา Java เปนไปไดอยางรวดเรว และแมนยามากยงขน ถอยคาและสานวนในหนงสอเลมนอาจดแปลก ๆ สาหรบหลาย ๆ ทาน สาเหตกเนองจากวาผเขยนใชสานวนทตวเองถนด และเปนสานวนทผเขยนเองไดสมผสมาจากตางประเทศ ซงอาจไมเปนทถกใจของผอานหลาย ๆ ทาน แตผเขยนขอสญญาวาจะพยายามทาใหสานวนเหลานเปนสานวนไทย ๆ ใหไดในอนาคต อกสงหนงทผเขยนไมสามารถหลกเลยงไดในการเขยนหนงสอเลมน กคอ การใชภาษาองกฤษควบคไปกบภาษาไทยทงนกเพราะวา ศพททงหลายทเกยวของกบคอมพวเตอรนน เราไดมาจากภาษาองกฤษ และผเขยนเองเหนวาควรทจะใชศพทเหลานโดยตรง โดยไมตองแปล หรอใชศพททนกภาษาศาสตรชาวไทยไดแปลออกมาใช เพราะจะทาใหเสยเวลาเพราะอยางไรเรากทบศพทเหลานอยแลว ผเขยนหวงวาหนงสอเลมน จะชวยใหการเรยนเขยนโปรแกรมภาษา Java เปนไปอยางราบรนและประสพผลสาเรจสาหรบทก ๆ ทาน ผเขยนขอขอบคณอาจารยในภาควชาทกทาน ทไดชวยเปนกาลงใจและชวยชแนะในเรองของเนอหาในหนงสอเลมน วาควรจะครอบคลมเรองตาง ๆ มากนอยแคไหน ขอบคณอาจารย ชยรตน ขนแกว ทชวยอานและแกไขคาผด และขอขอบคณอาจารยอกหลาย ๆ ทานทไดชวยเหลอและสนบสนนใหผเขยน ไดมโอกาสเขยนหนงสอเลมน ลนฟา ชมสาย เมษายน 2546

Page 3: Beginning JAVA [Thai]

i

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

สารบญ บทท 1 กอนจะถง Java 1 ทาไมถงเลอก Java เปนภาษาในการเขยน code 1 เตรยมความพรอม 2 ตดตง JDK การกาหนด path เขยน code แบบ application หรอ applet 4 การสรางโปรแกรม Java ทเปน application 5 การ execute โปรแกรม HelloWorld 6 การสรางโปรแกรม Java ทเปน applet 7 การเขยนโปรแกรม Java ดวย EditPlus 8 ทมาของ Java โดยสงเขป 12 บทท 2 ขอมล ตวแปร และ การประมวลผล 13 ขอมล และ ตวแปร 13 ชนดของขอมล 14 Keyword Primitive datatype ตวอยางการประกาศตวแปร 15 การกาหนดคาใหกบตวแปร การกาหนดคาใหกบตวแปรภายในโปรแกรม 16 การใช final ในการกาหนดคาใหกบตวแปร 18 อาย และ ขอบเขตการใชงาน ของตวแปร 19 การสรางประโยค 23 การประมวลผล 26 การประมวลผลขอมลทเปน integer 26 การใช operator ตาง ๆ 29 การประมวลผล short และ byte 32 การเปลยนแปลงขอมลดวยการ cast 33 การประมวลดวยตวแปรทมจดทศนยม 35 การประมวลผลขอมลตางชนดกน 37 การใช Mathematical Functions ตาง ๆ 39 การใชขอมลทเปน Character 43 การใชตวแปรชนด boolean 45 Logical operator Relational operator การประมวลระดบ bit (shift และ bitwise) 49 การกาหนดคาใหตวแปรผานสอนาเขามาตรฐาน 51 บทท 3 การประมวลผลแบบวน (Repetition) 58 การตดสนใจ และ การเปรยบเทยบ ประโยคทใช if 58 การใช if ในประโยคทมมากกวาหนงประโยค 60 if – else การใช Conditional operator ? : 68 การใช switch 69 การทางานแบบวน 72 การใช for loop 73 การใช StreamTokenizer 77 การใช while loop 80 การใช do … while 83

Page 4: Beginning JAVA [Thai]

ii

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การใช break และ continue 86 การใช Nested loop 88 การใช labeled continue และ labeled break 90 บทท 4 การใช Array และ String 96 การใช Array การกาหนดคาเบองตนใหกบ Array 97 การอางถง array ดวยการ clone และการ copy array 101 การใช array แบบยดหยน 104 การคนหาขอมลใน array 106 การคนหาแบบตามลาดบ 106 การคนหาแบบหารสอง 108 การเรยงลาดบขอมล 109 การสราง array ทมขอมลเปน array 111 การใช array ทมขอมลในแตละแถวไมเทากน 113 การใช String 115 Array of characters String ใน Java 116 การเปรยบเทยบ String 118 มากกวา นอยกวา 120 การเขาหาตวอกษรทอยใน String 121 การใช StringBuffer 125 การกาหนดใหขอมลของ array เปน String 129 บทท 5 Objects และ Classes 133 Class และ การสราง class ตวแปรทเปนสมาชกของ class 134 Method 136 การเขาหาตวแปร และ method ของ class 136 การสราง method 138 กระบวนการทเกดขนเมอมการใช parameter list 140 การสงคาแบบ pass by value 141 การสงคาแบบอางอง 143 การกาหนดนโยบายการเขาหาสมาชกของ class 149 Constructor อกครง 150 การเรยก constructor จาก constructor 153 การ overload method 155 การสราง class ภายใน class 156 Package 162 การสราง package บทท 6 การสราง class ใหมจาก class เดม และ

การถายทอดคณสมบต 168 การใช this และ super() 168 การใช protected การ override method 171 Polymorphism 175 การสง และ รบ object 179 การสราง interface 181

Page 5: Beginning JAVA [Thai]

iii

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

บทท 7 การตรวจสอบและดกจบ Error (Exceptions) 188 การ throw exception 188 การใช try และ catch 190 การใช try และ catch ใน loop 192 การใช printStacktrace() 192 การใช throw กบ try 195 การสราง exception ใชเอง 198 บทท 8 Streams I/O 204 การใช File 205 การใช FileNameFilter 208 Input และ Output streams 210 การใช FileReader การใช FileInputStream และ read() 211 การใช StreamTokenizer กบ FileReader 213 ขอดของการใช BufferedReader 217 การใช delimiter กบ text file 218 การใช FileWriter และ PrintWriter 218 Binary file 221 การใช DataInputStream และ FileInputStream การใช DataOutputStream และ FileOutputStream การใช writeUTF() และ readUTF() การใช PrintWriter เพอผลลพธทสวยงาม 224 การใช writeChars() 228 การสรางและใช Random-access file 229 การใช seek() 233 การ update record 234 ตารางตาง ๆ 240 ตาราง ASCII และ UNICODE (บางสวน) ตาราง Constant ทใชบอย ๆ ในโปรแกรม ตาราง ชนดของขอมล ตาราง Escape sequences ตาราง Format ตาง ๆ สาหรบขอมลทเปนตวเลข

Page 6: Beginning JAVA [Thai]

ในบททหนงนเราจะมาดการตดตงเครองมอทใช ในการพฒนาโปรแกรมดวยภาษา Java ตวอยางการเขยนโปรแกรมในรปแบบของ application และ การเขยนโปรแกรมในรปแบบของ applet หลงจากจบบทนแลว ผอานจะไดทราบถง

o การตดตงเครองมอทใชในการพฒนาโปรแกรมในภาษา Java o การเขยนโปรแกรมในรปแบบของ application o การเขยนโปรแกรมในรปแบบของ applet o การเขยน HTML ไฟลทใชในการ execute applet o การเขยนโปรแกรม Java ดวย EditPlus o ประวตคราว ๆ ของภาษา Java

ทาไมถงเลอก Java เปนภาษาในการเขยน code Java เปนภาษาทนกพฒนาโปรแกรมสามารถทจะเขยน code เพยงครงเดยว แลวนาไปใชไดกบเครอง computer ชนด (platform) ตาง ๆ ได โดยไมตอง compile ใหม เชน ถาเราเขยนโปรแกรมบนเครอง pc เราสามารถทจะนาเอา code ทได compile เรยบรอยแลวไป execute ในเครองอน ๆ ทไมใช pc ได เชน apple, linux, unix, หรอ อน ๆ ทม JVM หรอ Java Virtual Machine อย Java เปนภาษาทไดถกพฒนาขนเพอสนองตอการพฒนาโปรแกรมในรปแบบของการเขยนโปรแกรมทเรยกวา OOP หรอ Object-Oriented Programming ซงเปนภาษาทชวยใหการพฒนาโปรแกรมมความยดหยนสง ผเขยน หรอ ผพฒนาสามารถทจะสนองตอบความตองการของผใช (user) ไดมากกวาการพฒนาในลกษณะของการเขยนโปรแกรมแบบเดม (procedural language programming) และทสาคญอกอยางหนงกคอ Java เปนภาษาทไมตองเสยคาใชจายใด ๆ เลย เราสามารถทจะ download โปรแกรมสาหรบการพฒนาไดจากบรษท Sun Micro System หรอทอน ๆ ททาง Sun ไดอนญาตใหมการ download ได กอนทเราจะเขยนโปรแกรมดวย Java เราตองมอะไรบาง 1. เชนเดยวกนกบการเขยนโปรแกรมในภาษาอน ๆ เราตองม Text Editor ทใชสรางและเกบ source

code 2. JDK (Java Development Kit) ซงมหลาย version ลาสดในขณะทเขยนตาราเลมน คอ J2SE 1.4

ซง download ไดท http://sun.java.com เราตองใช JDK ในการ compile โปรแกรมทเราไดเขยนขน

3. Java VM หรอทเรยกวา Java Virtual Machine ซงเปนตวกลางทเปลยน code ทไดจากการ

compile เปน code ทสามารถ execute บนเครองตาง ๆ (code ทเครองนน ๆ รจก – machine code) โดยปกต VM จะถกตดตงพรอมกบ JDK

ถาเรามอปกรณทงหมดทไดกลาวมาแลว ขนตอนตอไปทเราตองทาเพอใหการพฒนาโปรแกรมของเรา เปนไปไดดวยความเรยบรอย (ไมมอปสรรคทคาดไมถง) เราตองเตรยมความพรอมของเครองกอน

Page 7: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 2 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

เตรยมความพรอม (สาหรบ pc) 1. ตดตง JDK 2. กาหนด path ภายในเครองเพอใหการ compile และ execute (run) โปรแกรมเปนไปได – ถาเราไม

กาหนด path เครองของเราจะไมรจกคาสงตาง ๆ ท Java ใช ตดตง JDK เมอ download JDK มาแลวการตดตงกทาไดงาย เนองจาก JDK เปนไฟลทเราเรยกวา self-extracting file คอ ไฟลทจะตดตงโดยอตโนมตเมอเรา execute (doubling click หรอ ดวยวธการอน ๆ เชน click บน icon ของ file แลวกด enter) สาหรบไฟล j2se1.4.1 นนมขนาดประมาณ 35.9 MB ซงเปนไฟลทใหญพอสมควร และใชเวลานานในการ download (ถา speed ในการ download ไมดพอ) ซงเมอขยายออกจะมขนาดประมาณ 64.6 MB เพราะฉะนนเราตองเตรยมเนอทไวใหเหมาะสมในการ install JDK ถาหากวาเนอทในการจดเกบมนอย เรากควรใช JDK version อน ๆ ทมขนาดเลกกวา การกาหนด path ถาการพฒนาโปรแกรมเปนการพฒนาบนเครอง Windows 9x การกาหนด path กสามารถทจะทาไดดวยวธการตาง ๆ ดงน 1. เปดไฟล autoexec.bat แลวเพม path ทไดตดตง JDK ไว ซงถาเราตดตง J2SDK 1.4.1 ไวใน

drive c การกาหนด path ในไฟล autoexec.bat กทาไดดงน

ใสคาสง set path=c:\j2sdk1.4.1\bin ในบรรทดใหมถายงไมมมคาสง set path อยเลย แตถามการใช คาสง set path อยแลวกใหใส ; (semicolon) หลงตวสดทายของ path แลวจงใส c:\j2sdk1.4.1\bin

2. หรอเราอาจกาหนด path ทกครงกอนการเขยนโปรแกรม (ถาเราไมไดกาหนดในไฟล autoexec.bat)

โดยไปท Command Prompt (หรอทรจกกนในคนรนเกาวา dos window) แลวก set path บน (dos) Command Prompt

3. ทาการพฒนาโปรแกรมใน directory ทม JDK อย เชนเปลยน drive ไปท c:\j2sdk1.4.1\bin แลว

เรมทางานใน directory น ไฟลทกตวทเกยวของกบการเขยนโปรแกรมจะตองเกบไวทน – วธน ไมแนะนา เพราะจะทาให directory ของ java เปรอะไปดวยไฟลทเราเขยนขนเอง

ถาเราใช Windows XP หรอ Windows 2000 การกาหนด path ทาไดดวยขนตอนตอไปน (Windows XP และ Windows 2000 ใชคาสงทแตกตางกนนดหนอย ตวอยางททาใหดน เปนการกาหนด path บนเครองทใช Windows XP) 1. กดปมขวาของ mouse บน icon My Computer (หรอ ไปทปม start ทมมลางซายของจอแลวเลอก

My Computer) แลวเลอก Properties

Page 8: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 3 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

2. กดปม advanced บน System Properties

3. กดปม Environment Variables

4. ใน System Variables เลอกขอความทขนตนดวยคาวา Path

5. เมอกดปม Edit กจะไดหนาจอดงทเหน

Page 9: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 4 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

6. เตม ; (semicolon) ถายงไมม แลวจงใส path ทได install JDK ไว เสรจแลวกดปม OK เพอใหระบบ

บนทกการเปลยนแปลงทไดทาขน หลงจากทไดกาหนด path ใหกบเครองทเราจะใชในการเขยนโปรแกรมแลว ขนตอนตอไปกขนอยกบผเขยน การพฒนาโปรแกรมกทาไดโดยไมตองวนวายกบการกาหนด path ตาง ๆ อก (ยกเวนเสยแตวา path ทไดกาหนดขนไมมอยจรง – เรากตองกลบไปเรมตนใหม พรอมกบ path ทมอยจรง) ทงนทงนน ผพฒนาโปรแกรมตองเลอกเองวา วธไหนเหมาะสมทสด ถาตองใช Java อยบอย ๆ และ สมาเสมอกควรทจะเลอกกาหนด path แบบถาวร เพอจะไดไมตองเสยเวลากบการกาหนด path สงทสาคญอกสงหนงทขาดไมไดในการทดสอบและ execute code ทเขยนขนดวย Java กคอ JRE หรอทเรยกวา Java Run-time Environment ถาเรานาเอา code ทไดผานการ compile จาก JDK แลวไป execute บนเครองทยงไมไดตดตง JRE ผลลพธกคอ execute ไมได แตถาเครองนนไดรบการตดตง JDK กจะไดรบการตดตง JRE พรอมกนไปดวย ดงทไดกลาวไวกอนหนาน สาเหตท Sun ทาแบบนกเพราะวา หลาย ๆ คนอาจไมใชผพฒนา Java โปรแกรมแตเปนผใชโปรแกรมทเขยนขนดวย Java กได ดงนนหากเครองใด ๆ ตองใชโปรแกรมทเขยนขนดวย Java บอย ๆ กตอง download JRE มาไวทเครองดวย เขยน code ทเปน application หรอเขยน code ทเปน applet Applet เปน code ทเขยนขนมาเพอใหสามารถทจะ execute ใน web browser ผานทาง HTML ไฟล ซงโดยทวไปมกจะมขนาดเลก เพอใหการ download applet ทาไดรวดเรวยงขน สวน application เปนการ execute ไฟลผานทาง command line ดงนนขนาดจงไมเปนอปสรรค (เพราะไมตองมการ download) หนงสอเลมนจะแสดงโปรแกรมตวอยางดวยการเขยน code ในรปแบบของ application เครองมอ หรอ คาสง (SDK tools) ทตองใชในการพฒนาโปรแกรม Java Development Kit ไดถกเปลยนใหมชอเปน J2SDK – Java 2 Software Development Kit ดงนนเราจะใชชอเครองมอในการพฒนาโปรแกรมนสลบกนไปมา แตใหตงสมมตฐานวาทงสอง ตางกเปนเครองมอทใชในการพฒนา Java โปรแกรมเชนเดยวกน javac เปนเครองมอทใชในการ compile (compiler) ททาการเปลยน source code ทเรา

เขยนขนใหเปน byte code java เปนเครองมอทใชในการ execute byte code สาหรบโปรแกรมทเขยนขนในแบบของ

application appletviewer เปนเครองมอทใชในการ execute โปรแกรมทเขยนขนในแบบของ applet ยงมเครองมออกหลายตวท java มให แตตอนนเราจะใชเฉพาะเครองมอทไดกลาวไวแคสามตวน เทานน การพฒนาโปรแกรมทงทเปน application และ applet นนจะมขนตอนทแตกตางกนพอสมควร ดงแสดงใหเหนในภาพท 1-1 และในภาพท 1-2 ในการเขยน code นนเราจะตองม editor ทเปน text editor กลาวคอเปน editor ทไมมการเกบ format ตาง ๆ ของตวอกษรดงเชนท Microsoft Word เกบ แตจะเกบเปนรหส ASCII ท SDK สามารถอานและ execute ได สมมตวาเราม text editor และ SDK แลวการพฒนากเปนไปตามขนตอนทแสดงในภาพทงสอง

Page 10: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 5 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

ภาพท 1-1 ขนตอนการพฒนาโปรแกรมทเปน application

ภาพท 1-2 ขนตอนการพฒนาโปรแกรมทเปน applet การสรางโปรแกรม Java ทเปน application สมมตวาเราเลอกใช text editor ตวใดตวหนงทมอยมากมาย ทงท free และทงทตองจายเงนซอมา เรากมาลองเรมเขยนโปรแกรมตวแรก กนเลยดกวา เพอใหเขาใจไดงายถงขนตอนและทมาทไปในการเขยนโปรแกรมดวยภาษา Java เราจะเขยนโปรแกรมทไมทาอะไรมากมายนก เพยงแตสงขอมลไปยงหนาจอเมอ user เรยกใช (execute) โปรแกรมน เราจะตงชอโปรแกรมนวา HelloWorld.java และมขอมลดงน class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); } } ผอานยงไมตองกงวลกบความหมายของ keyword ตาง ๆ ทเหนในตอนน หลงจากทเขยนโปรแกรมไดสกพกหนง ผอานกจะเขาใจถงความหมายเหลานดขน แตตอนนตองเขาใจวาไฟลทเราเขยนขน มนยามของ

Text Editor Javac

appletviewer

Java Source File First.java

Java Class File First.class

Java Program Output

HTML file First.html

Text Editor Javac

Java

Java Source File First.java

Java Class File First.class

Java Program Output

Page 11: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 6 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

class ทเราเขยนขนชอ HelloWorld ซง Java กาหนดไววา ชอของ class และชอของไฟลทเกบ code ของ class นจะตองเปนชอเดยวกน class นม method อยหนงตวชอ main() เมอเรา execute โปรแกรมน JRE จะคนหา method ทชอ main() เพอทาการ execute ทงน method main() จะตองม keyword ทชอ public, static, และ void อย รวมไปถง parameter ทเปน array ทเกบ String ดวย ถาผอานเคยเขยนโปรแกรมดวย ภาษา C หรอ ภาษา C++ มากอนกจะเหนถงความคลายคลงกนของ method main() น Parameter ของ method main() ทเปน String[] args หมายถง command-line argument ตาง ๆ ทผใชโปรแกรมสงผานไปยงตวโปรแกรมเพอเอาไวใชในการทางานตาง ๆ ซงเราจะยงไมกลาวถงในเวลาน ในตว method main() เองมประโยคทขนตนดวย System.out.println("…") ซงเปนคาสงทใชสงขอความไปยง System.out ทโดยทว ๆ ไปกคอ console window หรอทเรยกกนตดปากวา dos window หรอ dos prompt ดงตวอยางทแสดงใหเหนในภาพท 1-3

ภาพท 1.3 การ compile และ run โปรแกรม การ compile โปรแกรม HelloWorld ดงเชนทแสดงใหเหนในภาพท 1-3 การ compile ไฟลทเขยนขนตองใชคาสง javac ตามดวยชอไฟล พรอมกบนามสกล ดงน javac HelloWorld.java ในการ compile ทกครงเราจะตองไมลมใสนามสกลใหกบไฟลทเราไดเขยนขน ไมเชนนนแลว compiler จะฟอง โดยการสง error message ใหเราเชน ถาเรา compile ไฟล HelloWorld โดยไมใส .java เรากจะได error ดงน E:\bc221Book\source>javac HelloWorld javac: invalid flag: HelloWorld Usage: javac <options> <source files> where possible options include: -g Generate all debugging info -g:none Generate no debugging info -g:{lines,vars,source} Generate only some debugging info … … … (ผเขยนไดตดขอความบางสวนท java ฟองออก - ใช … แทน) การ execute โปรแกรม HelloWorld สมมตวาเรา compile โปรแกรม HelloWorld โดยไมม error ใด ๆ เกดขนการ execute โปรแกรมกทาไดดวยคาสง java ตามดวยชอไฟล ดงน java HelloWorld และกจะได output ดงทเหนในภาพท 1-3

Page 12: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 7 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

ในการ execute โปรแกรมนนเราจะไมใส .class ตามหลงชอไฟล (ถงแมวาเราตองมไฟลนกตาม) ถาเราใส compilerกจะฟองดวย error ทบอกวา หาไฟลไมเจอ (java.lang.NoClassDefFoundError) ดงทเหนน

สรปขนตอนของการพฒนาโปรแกรมทเปน application 1. compile ดวยคาสง javac ตามดวยชอไฟล พรอมกบนามสกล 2. execute ดวยคาสง java ตามดวยชอไฟลโดยไมมนามสกลใด ๆ ตอทาย การเขยนโปรแกรมทดนน ผเขยนควรใสคาอธบาย (comment) ถงการทางานของโปรแกรมทเขยนขน เพอใหผทนาโปรแกรมไปใช หรอผอานคนอน เขาใจถงวธการใชทถกตอง ในการเขยน comment ดวยภาษา Java นน มการทาไดสองวธ คอ 1. การใช // 2. การใช /* … */ การใชในแบบทหนงนน เปนการใส comment ไดไมเกน 1 บรรทด สวนการใชในแบบทสอง ผใชสามารถทจะใส comment ไดมากกวาหนงบรรทด แต comment ตองอยภายในเครองหมาย /* … */ เทานน ดงตวอยางจากการนาโปรแกรม HelloWorld มาเขยนใหมดวย comment // My first Java program - HelloWorld class HelloWorld { /* Java launcher will call this method (main). This will display a message to the screen. */ public static void main(String[] args) { System.out.println("Hello World"); } } การสรางโปรแกรม Java ทเปน applet ในการเขยนโปรแกรมทเปน Java applet นนเราจะตองมไฟลอยอยางนอย 2 ไฟล ซงหนงในนนคอ Java source file และอกไฟลหนงคอ HTML file เราลองมาเขยน applet เลก ๆ ทสงขอความไปยง web browser เหมอนกบทเราเขยน application กอนหนาน //my first Java applet - HelloWorldApplet import java.applet.Applet; import java.awt.Graphics; public class HelloWorldApplet extends Applet { public void paint(Graphics g) { g.drawString("Hello World", 25, 25); } }

Page 13: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 8 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

เนองจากวาเราตองการ applet สาหรบการสงขอความไปยง web browser ดงนนเราจงตองดงเอาเครองมอทชวยใหเราสามารถแสดงขอความทวา ดวยการใชการถายทอดคณสมบต (inheritance) ท Java มใหดวยการเพมคาวา extends Applet ทางดานหลงของ class HelloWorldApplet เราจะยงไมพดถงรายละเอยดเกยวกบการถายทอดคณสมบตของ Java ตอนน อกสงหนงทขาดไมไดในการเขยน applet ของเราตอนนกคอ method paint() ซงเปน method ททาการวาดขอความลงบน applet ดวยการเรยกใช method drawstring() จาก class Graphics ในตาแหนงทกาหนดไว จากคาสงน g.drawString("Hello World", 25, 25); เมอ compile โปรแกรม HelloWorldApplet ดวยคาสง javac แลวเรากสามารถทจะ execute applet ไดดวยการเรยก HTML ไฟลทเขยนขน ดงน <html> <applet code="HelloWorldApplet.class" width="200" height="80"></applet> </html> ดวยการใช applet tag ใน HTML ไฟลพรอมกบการใสชอของ Java ไฟลท compile แลวในสวนของ field ทชอ code และกาหนดขนาดความกวางของ applet ใน field ทชอ width และความยาว (สง) ใน field ทชอ height การ execute ไฟล HelloWorldApplet.html กสามารถทาไดดวยการใชคาสง appletviewer ตามดวยชอไฟล เรากจะได output ดงน

สรปขนตอนการเขยนโปรแกรมแบบ applet 1. สราง Java source file ดวยการ extends Applet 2. สราง HTML file ทม applet tag และขอมลทสาคญในการแสดง applet คอ (1) class file ของ

Java โปรแกรม (2) ขนาดของ applet – width และ height เราจะกลบมาดวธการเขยน applet อกครงหนงหลงจากทเรา ไดศกษาถงโครงสรางตาง ๆ ของภาษา Java ขนตอนการออกแบบ และการเรยกใช class รวมไปถงเทคนคและวธการใช method ตาง ๆ ท Java มให การเขยน Java program ดวย EditPlus ตวอยางของโปรแกรม HelloWorld.java ทเราไดเขยนขนกอนหนานใชภาษาองกฤษทงหมดในการเขยน ผลลพธทไดจากการ run โปรแกรมกเปนภาษาองกฤษ ผานทาง Dos Window ถาเราตองการทจะเขยนโปรแกรมเพอใหแสดงผลลพธ หรอ ขอความทเปนภาษาไทยนน จะตองใช Operating System ทรองรบการปอนและสงขอมลทเปนภาษาไทย เชน Windows ตาง ๆ ทสรางขนมาเพอคนไทยโดยเฉพาะ ซงจะสงเกตไดจากคาวา Thai Edition หรอ คาวา ไทย ตอทาย แตกม OS หลาย ๆ ตวทยอมใหมการปอนและสงขอมลทเปนภาษาไทยผานทางชองทางอน ๆ ทไมใช Dos Window ในการฝกฝนการเขยนโปรแกรม Java ใหม ๆ นนเราจาเปนทจะตองมชองทางในการแสดงผลทสามารถใชไดทงภาษาไทย และภาษาองกฤษ ดงนนเพอใหการปอนและสงขอมลใชไดทงภาษาไทยและภาษาองกฤษ เราจะเลอกใช Text Editor ทรองรบภาษาไทย เชน EditPlus (ม Text Editor หลายตวทรองรบภาษาไทย แตเราจะพดถงเฉพาะ EditPlus เทานน)

Page 14: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 9 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

กอนอนเราตองหา EditPlus มาตดตงในเครองทเราใชในการสรางโปรแกรมดวยภาษา Java เสยกอน ซงสามารถทจะไป download มาไดจาก www.editplus.com โปรแกรมตวนเปน shareware ทมอายการใชงานเพยงแค 30 วนหลงจากนนกคงตองควกกระเปาจายใหกบเจาของโปรแกรมตามระเบยบ ซงกไมแพงเทาไรนก เมอ install เรยบรอยแลวกใหเขาไปใน menu ทชอวา Tools

เลอก Preferences

click ท Fonts และเลอก Default (edit window) จาก Drop-down menu ในชองทชอ Area เสรจแลวใหเลอก font ทสามารถใชภาษาไทยได เชน Tahoma ดงทเหนในรป เสรจแลวกเรมทาในลกษณะเดยวกนกบ Output window

Page 15: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 10 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

หลงจากท set คาใหกบ editor และ output window เรยบรอยแลว เรากตองมา set ให EditPlus รจกกบการ compile และ execute โปรแกรมในภาษา Java เรมตนดวยการ click ท User tools ใน Preferences และกดปม Add Tool>> เพอเลอก Program

เสรจแลวใหใสขอมลดงตวอยางทเหน Menu Text: Compile Java Source File Command: ททผอานได install Java ไว เชน c:\j2sdk1.4.1\bin\javac.exe Argument: $(FileName) เลอกจาก drop-down list Initial directory: $(FileDir) เลอกจาก drop-down list พรอมกบใสเครองหมาย ในชอง Capture output

Page 16: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 11 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

เสรจแลวใหเพมคาสงให EditPlus รจกการ run หรอ execute โปรแกรมทได compile เรยบรอยแลว ดวยการกดปม Add tool>> อกครงหนง พรอมกบใสขอมลทเหนน

เมอทาทกอยางเรยบรอยแลวใหกดปม OK เพอทาการบนทกคาสงทเราสรางขนให EditPlus รจก และเมอไดเปลยนแปลงไฟล HelloWorld.java ดวยการเพมขอความทเปนภาษาไทยเขาไปในประโยค System.out.println(…) เชนในตวอยางน class HelloWorld { public static void main(String[] args) { System.out.println("Hello World! สวสดครบ โลกเกา ๆ ใบน"); } } เราก compile ดวยการกด Ctrl + 1 และเมอ compile เสรจเรากจะไดรบขอความดงทเหนน

หลงจากนนเราก run ดวยการกด Ctrl + 2 กจะไดผลลพธดงทเหนน

Page 17: Beginning JAVA [Thai]

บทท 1 กอนจะถง Java 12 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

EditPlus ยงม features ตาง ๆ อกมากมายทเราสามารถทจะ set ไวชวยในการทางานของเราได ทงนผอานสามารถทจะหาขอมลเพมเตมไดจาก help file ของตว EditPlus เอง แตถาผอานอยากใช Text Editor ตวอนผเขยนขอแนะนาอกตวหนงคอ Crimson ซงเปน editor ทไมตองเสยคาใชจายใด ๆ เลย และสามารถทจะ download ไดจากหลาย ๆ ทใน WWW ทมาของภาษา Java โดยสงเขป Java เปนภาษาทเกดขนจากการพฒนาของบรษท Sun Microsystems โดยมทมาจากภาษาทชอวา Oak ซงเปนภาษาทใชภายใน Sun เองแตหลงจากท Sun ไดพฒนา Oak และใชมาอกระยะหนง Sun กไดนาเอา Oak ออกมาสสายตาชาวบานทวไป แตเนองจากวา ชอของ Oak ไดมผใชอยกอนแลว Sun จงตองหาชอใหมใหกบภาษาน ซงในตอนแรกกไดทดลองหลายชอ เชน Silk, Ruby, และ WRL (Web Runner Language) แตชอเหลานกไมไดถกเลอก ในทสด Java กกลายเปนชอของภาษาน (ทง ๆ ทไมมอะไรเกยวของกบ กาแฟ จาก ชวา หรออะไรทเกยวของกบเกาะชวาเลย) Java มอยมากมายหลาย version แต version ลาสดของ Java ขณะทเขยนตาราเลมน คอ J2SDK1.4.1 ผอานสามารถตดตาม version ใหม ๆ และ download ไดท web site ของ Sun ทไดใหไวกอนหนาน ในบททสองเราจะมาทาความรจกกบขอกาหนด ตาง ๆ ของ โปรแกรม ขอมล (data) ตวแปร (variable) และ การประมวลผล (calculation – evaluation)

Page 18: Beginning JAVA [Thai]

ในบททสองนเราจะมาทาความเขาใจในเรองของชนดขอมลท Java มไวในการรองรบการเขยนโปรแกรม ทงขอมลทเปนตวเลข และขอมลทเปนตวอกษร เราจะทดลองเขยนโปรแกรมดวยขอมลชนดตาง ๆ น หลงจากจบบทเรยนนแลว ผอานจะไดทราบถง

o วธการประกาศตวแปร (variable declaration) ทมชนดเปน integer และ floating-point o วธการประกาศตวแปรทมชนดเปน character และ boolean o วธการกาหนด (assignment) คาใหกบตวแปรตาง ๆ o การสรางประโยค (statement หรอ expression) o การประมวลผล (calculation และ evaluation) ทเกยวกบตวแปรชนดตาง ๆ o การเปลยนแปลง (casting) ชนดของขอมล o การใชฟงคชนทางคณตศาสตร (Mathematical Functions) ท Java มให

ขอมล และ ตวแปร (data and variable) โดยทวไปถาเราตองการคานวณหาคาทางคณตศาสตร เชน 354 + 45 * 12 เรามกจะใชเครองคดเลข หรอไมกใชวธคดในกระดาษ ซงวธคดแบบทสองนเราใชกระดาษเปนตวกลางในการหาคานน ๆ กลาวคอ เราใชกระดาษเปนทเกบตวเลขทตองการหาคา รวมไปถงผลลพธของการหาคานน ๆ ดวย เชนเดยวกบการเขยนโปรแกรมทางคอมพวเตอร คาตาง ๆ เหลานจาเปนจะตองมทเกบ และทเกบขอมลเหลานตองเปนทเกบทสามารถรองรบการประมวลผล หรอ การคานวณไดอยางพอเพยง ดงนนในการเขยนโปรแกรม เราจงตองใชตวแปรเปนทเกบขอมลตาง ๆ ทเราจะตองใชในการประมวลผล ตวแปรทวานเปนสญลกษณแทนหนวยความจา (memory) ทอยในเครอง และ compiler จะเปนผกาหนดวาอยทใด มขนาดเทาใด (address เรมตน และ offset) ทเกบขอมลนจะเกบขอมลไดเพยงชนดทเราไดกาหนดไว เพยงชนดเดยวเทานน ขอมลถกแบงออกตามชนดของขอมล หลก ๆ คอ ขอมลทเปนตวเลข และ ขอมลทไมใชตวเลข แตจะแบงยอย ๆ ลงไปอก เชน ถาเรากาหนดใหตวแปรตวใดตวหนงเกบขอมลชนดทเปนตวเลขในแบบของ integer เรากไมสามารถทจะนาเอาขอมลทเปนตวเลขในรปแบบอน เชน double หรอ float มาเกบไวในตวแปรนได เนองจากวาขอมลทตวแปรเกบไดนนมขนาดตายตว ตามการออกแบบของภาษา ดงนน การนาเอาขอมลชนดอนมาใสไวในตวแปรนจะถกตรวจสอบโดย compiler และ compiler จะฟองไปยงผเขยนโปรแกรมทนท การประกาศตวแปรนน ผเขยนโปรแกรมจะใชสญลกษณใด ๆ กไดท Java ยอมใหใช ซงตองอยในกฎเกณฑ ตอไปน 1. ตองขนตนดวยตวอกษร (letter) หรอ เครองหมาย _ (underscore) หรอ เครองหมาย $ (dollar

sign) 2. เครองหมายอน ๆ ทตามมาเปนไดทง ตวอกษร ตวเลข และ สญลกษณอน ๆ ทไมไดถกใชโดย Java

(เชน operator ตาง ๆ ท Java ใชดงตวอยางของการ + (บวก) – (ลบ) * (คณ) / (หาร) เปนตน) ตวอยางของตวแปรทถกตอง taxRate pricePerUnit

Page 19: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 14 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

_timeInSecond $systemClock unit897 เนองจากวา Java ไดออกแบบใหผใชสามารถทจะกาหนดตวแปรใหเปน Unicode1 เพอเปดโอกาสใหการออกแบบตวแปรเปนไปไดในภาษานน ๆ ของ ผเขยนโปรแกรม เราจงสามารถทจะใชตวแปรทเปนภาษาไทยได สงทเราตองคานงถงกคอ text editor ทเราใชในการเขยน code ตองยอมใหเราใชภาษาไทยดวย ในบทนและบทอน ๆ ของตารานจะใชตวแปรทเปนภาษาองกฤษเทานน เพอใหงายตอการเขยน และการทาความเขาใจในเนอหาไดรวดเรวขน โดยทวไปเราจะเรยกตวแปรทไดกาหนดใหเกบขอมลชนดใด ชนดหนงวา variable หรอ identifier และ identifier ทวาน มความยาวเทาไรกได (จานวนของตวอกษร) แตกตองอยภายใตขอกาหนดทไดกลาวมาแลว พรอมกนน ตวแปรทสรางขนจะตองไมใช keyword หรอ reserved word ท Java ไดสรางขนไวใชงาน ดงทแสดงในตาราง 2.1 ตารางท 2.1 keyword abstract const finally int public this boolean continue float interface return throws break default for long short throws byte do goto native static transient case double if new strictfp try catch else implements package super void char extends import private switch volatile class final instanceof protected synchronized while

ชนดของขอมล (datatype) ในการประกาศตวแปรทกครงเราจะตองบอกชนดของขอมลใหกบ ตวแปรนนดวย ซงการประกาศตวแปรนน ตองเรมตนดวย ชนดของขอมล และตามดวย ชอของตวแปร ตามรปแบบทกาหนดดงน datatype identifier โดยท datatype คอชนดของขอมลท ตวแปรสามารถเกบได และในภาษา Java datatype เปนไดทง ขอมลทเรยกวา primitive datatype และขอมลทเปน reference (เราจะพดถง reference ในบทอน) Java กาหนดใหม primitive datatype จานวนทงสน 8 ชนด ดงทแสดงใหเหนในตารางท 2.2 ตาราง 2.2 primitive datatype datatype คาอธบาย ขนาด (bit) boolean คาทางตรรกะ 8 มคาเปน true หรอ false byte ตวเลขทไมมจดทศนยม 8 short ตวเลขทไมมจดทศนยม 16 int ตวเลขทไมมจดทศนยม 32 long ตวเลขทไมมจดทศนยม 64 float ตวเลขทมจดทศนยม 32 double ตวเลขทมจดทศนยม 64 char ตวอกษร 16

ขนาดของ datatype จะเปนตวกาหนดคาทเราสามารถเกบไดในตวแปรทไดประกาศในโปรแกรม ยงจานวนของ bit มากเทาไรเรากสามารถเกบคาสง ๆ ได ตารางท 2.3 แสดงคาตาง ๆ ทสามารถเกบไดใน datatype ชนดตาง ๆ

1 มความจ 2 byte เพอรองรบภาษาทใชกนในประเทศตาง ๆ (เดมใช ASCII ซงมความจเพยง 1 byte)

Page 20: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 15 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ตาราง 2.3 คาทเกบไดใน primitive datatype ตาง ๆ datatype คาตาสด คาสงสด byte -128 127 short -32768 32767 int -2147483648 2147483647 long -9223372036854775808 9223372036854775807 float -3.4 x 1038 3.4 x 1038 double -1.7 x 10308 1.7 x 10308

ตวอยางการประกาศตวแปร int numberOfBikes; float taxRate; double interests, PI; boolean yesOrNo; char response; โดยทวไปนกพฒนาโปรแกรมมกจะใช ตวอกษรตวเลกเปนตวเรมตนของตวแปร และจะเปลยนเปนอกษรตวใหญเมอคานน ๆ สนสดลง เชนการประกาศตวแปรทเหนดานบนน อกวธหนงทหลาย ๆ คนชอบใช คอการใชเครองหมาย _ (underscore) เปนตวแบงคา เชน int number_of_bikes; float tax_rate; double cum_gpa; boolean yes_or_no; ทงนและทงนน การประกาศตวแปรทงสองวธทาใหการอานตวแปรทาไดงายขน แตสงสาคญทเราจาเปนจะตองคานงถงในการประกาศตวแปรกคอ การเลอกใชคาทสอถงความหมายของขอมลทตวแปรนน ๆ รองรบ หรอ เกบอย เชน ถาเราตองการเกบขอมลทเปนเกรดทเปนตวอกษร เรากควรใช ตวแปรทสอถงเกรดทเปนตวอกษร เชน คาวา letterGrade และถาเราตองการเกบเกรดทเปนคาเฉลยเรากควรใช ตวแปร เชน gpa หรอ cumulativeGPA เปนตน การกาหนดคาใหกบตวแปร (Assignment) การกาหนดคาใหกบตวแปรนนทาไดดวยการใชเครองหมาย = (เรยกกนวา assignment operator) ซงมความหมายวา "ใหนาคาทางขวามอ (rvalue) ของเครองหมาย = ไปเกบไวในตวแปรทอยทางดานซายมอ (lvalue) ของเครองหมาย =" rvalue สามารถเปนไดทง คาคงท ตวแปร หรอประโยคใด ๆ ทสามารถหาคาได สวน lvalue เปนไดเฉพาะตวแปรเทานน เพราะจะตองเปนททเกบขอมลได (physical memory) เชน numberOfBikes = 2; area = PI * r * r; taxReturned = calculateTaxReturned(income); แตไมใชแบบน 2 = numberOfBikes; PI * r * r = area; calculateTaxReturned(income) = taxReturned; ในการกาหนดคาใหกบตวแปรนน ถาเรามองในมมมองของทมาของคาทนามาใสใหกบตวแปร เรากสามารถทจะแบงการกาหนดคาไดเปนสองแบบ คอ (1) การกาหนดคาใหกบตวแปรภายในตวโปรแกรม และ (2) การกาหนดคาใหกบตวแปรผานทางสอการนาเขาขอมลมาตรฐาน (standard I/O channel) เราจะมาทาความเขาใจการกาหนดคาในแบบทหนงกนกอน เพราะเปนการกาหนดคาทงายทสด

Page 21: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 16 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การกาหนดคาใหกบตวแปรภายในโปรแกรม การกาหนดคาใหกบตวแปรนนสาคญมาก เพราะโดยทวไปตวแปรจะไมมคาใด ๆ เลยหลงจากการประกาศ ภาษาในการเขยนโปรแกรมหลาย ๆ ภาษาบงคบใหผเขยนโปรแกรมกาหนดคาเบองตน กอนทจะใชตวแปรนน ๆ ซงกเปนสงทด เพราะจะทาใหการเขยนโปรแกรมเปนไปไดงาย และสะดวกตอการตรวจสอบหากมขอผดพลาดเกดขน โปรแกรมตวอยางทเหนนแสดงถงวธการประกาศตวแปรพรอมกบการกาหนดคาเบองตนใหกบตวแปรเหลานน /* * Variables.java - Variable decalration and initialization */ class Variables { public static void main(String[] args) { boolean booleanVar = true; byte byteVar = 0; short shortVar = 0; int intVar = 0; long longVar = 0L; float floatVar = 0.0F; double doubleVar = 0.0D; char charVar = 'A'; System.out.println("boolean variable and its initial value is " + booleanVar); System.out.println("byte variable and its initial value is " + byteVar); System.out.println("short variable and its initial value is " + shortVar); System.out.println("int variable and its initial value is " + intVar); System.out.println("long variable and its initial value is " + longVar); System.out.println("float variable and its initial value is " + floatVar); System.out.println("double variable and its initial value is " + doubleVar); System.out.println("char variable and its initial value is " + charVar); } } เรากาหนดคาทเปนศนยใหกบตวแปรทกตว ยกเวนตวแปรทเปน boolean ซงเรากาหนดคาใหเปน true เราบอกให Java รวาคาทกาหนดใหกบตวแปรตาง ๆ มชนดเปนอะไรไดดวยการใสตวอกษรทบงบอกชนดนน ๆ ของตวแปร เชน 0L 0.0F และ 0.0D ซงหมายถง คาของศนยทเปน long คาของศนยทเปน float และ คาของศนยทเปน double ตามลาดบ ทงนเพอบอกให Java รวาเราตองการใชคาทเกบชนดนน ๆ จรง ซงเราจาเปนทจะตองทาเพยงคาของตวแปรทเปน float และ double เทานน เพราะวาตวแปรทมชนดเปน float ถามการกาหนดคา Java จะเหมาเอาวาเปน double เราจงตองกาหนดคาตามชนดของตวแปรจรง ๆ ทเราตองการ ผลลพธของโปรแกรม Variables.java boolean variable and its initial value is true byte variable and its initial value is 0 short variable and its initial value is 0 int variable and its initial value is 0 long variable and its initial value is 0

Page 22: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 17 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

float variable and its initial value is 0.0 double variable and its initial value is 0.0 char variable and its initial value is A เรามาดขนตอนท Java เกบขอมลในตวแปรกนดกวา (หากจะบอกวาภาษาอน ๆ กเกบแบบนกคงจะไมผดนก) เราจะใชตวแปรจากโปรแกรมตวอยางขางบน จากประโยคของการประกาศและกาหนดคา long longVar = 0L; ประโยคทเหนดานบนนสามารถทจะเขยนไดอกแบบหนงคอ long longVar; longVar = 0L; ประโยค long longVar; นนเปนการประกาศตวแปรชอ longVar ทมชนดเปน long สวนประโยค longVar = 0L; นนเปนการกาหนดคา 0 ใหกบตวแปร longVar (ภาพท 2.1 แสดงถงขนตอนในการสรางตวแปรและการกาหนดคาใหกบตวแปรของ Java) การประกาศพรอมกบกาหนดคาใหกบตวแปรในประโยคเดยวกน ชวยใหการเขยน code เมอมองดแลวสวยและกะทดรดขน ทงนกคงจะขนอยกบตวผอานเองวามความคดเหนอยางไร สาหรบตวผเขยนเองคดวาถาเปนการประกาศทมตวแปรไมกตวในบรรทดนนกคงมองดแลวสวยด แตถามมากเกนไปกคงจะไมเขาทาเทาไรนก ตวอยางเชน double price = 0.0D, tax = 0.7D, returned = 0.0D, interests = 0.0D, principal = 10000.0D; โปรแกรมเมอรควรจะแยกการประกาศทเหนดานบนนใหอยคนละบรรทดเพอใหงายตอการอาน และเปลยนแปลง หากมการเปลยนแปลงเกดขนในโปรแกรม

ภาพท 2.1 การกาหนดคาใหกบตวแปร ในการกาหนดคาใหกบตวแปรนน เราไมจาเปนทจะตองกาหนดคาของตวแปรตาง ๆ ใหเปนศนย เราสามารถทจะกาหนดคาอะไร กไดใหกบตวแปรเหลาน ทงนขนอยกบการใชงานของตวแปรนน ๆ หลาย ๆ ครงทเราตองตดสนใจวาควรจะใชตวแปรชนดใดด ในกรณทขอมลเปนชนดทอยในหมวดเดยวกน เชน ขอมลเปนเลขทไมมจดทศนยม หรอ ขอมลเปนเลขทมจดทศนยม ซงถาเหตการณเหลานเกดขน เรากจาเปนทจะตองคดถงคาความเปนไปไดของขอมลวาอยใน range เทาใด เชน ถาเราตองการใชตวแปรรองรบขอมลทเปนเลขทไมมจดทศนยมทมขนาดไมเกน 127 เรากควรทจะประกาศตวแปรดวยการใช byte แทนการใช int เปนตน เราสามารถทจะประกาศตวแปรพรอมกบการกาหนดคาใหกบตวแปร หลาย ๆ ตวในหนงประโยค เชน int length = 2, height = 8, width = 4; double angles = 30.5, distance = 24.50;

long longVar;

??? 0

longVar = 0L;

ประกาศตวแปรชนด long ชอวา longVar ซง Java จะจองหนวยความจาใหแตไมมคาใด ๆ ณ หนวยความจานน

หลงจากกาหนดคา 0 ใหกบ longVar แลวหนวยความจา ณ ตาแหนงนนกจะมคาตามทกาหนดให คอ 0

Page 23: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 18 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การประกาศตวแปรในรปแบบนตองใชเครองหมาย , (comma) เปนตวแบงตวแปรออกจากกน และตวแปรเหลานนจะมชนดเปนชนดเดยวกนตลอด เราไมสามารถประกาศตวแปรตางชนดกนไดดวยวธการประกาศแบบน เชน int cats = 90, float tax = 0.50; // ERROR – mixed-type declaration // and initialization การประกาศตวแปรไมจาเปนตองกาหนดคาใหทนท แตสามารถทจะกาหนดไดภายหลง เชน double radius; radius = 2.54; ลองมาดการประกาศและกาหนดคาในรปแบบอกรปแบบหนง int one = 1, two = 2, three = one + two; Java ยอมใหมการประกาศและกาหนดคาแบบนได เนองจากวา ตวแปร one และ two มการกาหนดคาเรยบรอยแลว ดงนน การประกาศและกาหนดคาใหกบตวแปร three จงทาไดโดยไมมปญหาใด ๆ จาก compiler เลย ประโยค three = one + two; เปนประโยคทมการประมวลผลของ one + two กอนแลวจงนาคาทไดมาเกบไวทตวแปร three เราจะพดถง ประโยค และ การประมวลผลทเกดขนในประโยคในโอกาสตอไป การใช final ในการกาหนดคาใหกบตวแปร หลาย ๆ ครงทเราตองการใชคาบางคาตลอดอายการทางานของโปรแกรม เชน คาของ PI หรอ คาคงททจะไมมการเปลยนแปลงใด ๆ ในขณะใชงานในโปรแกรม Java มคาสงท user ไมสามารถทนามาใชในการประกาศตวแปรได (reserved word) แตเอาไวใชในงานนโดยเฉพาะ คอ คาวา final ถาเราขนตนการประกาศตวแปรดวยคาวา final ตวแปรนน ๆ จะไมสามารถมคาอน ๆ ไดอก ไมวาจะเปนการเปลยนคาภายในโปรแกรม หรอ การเปลยนแปลงทเกดจากการใสขอมลใหมผานทาง keyboard ดงโปรแกรมตวอยางทแสดงใหเหนน /* * Final.java - Use of final keyword */ class Final { public static void main(String[] args) { final double PI = 3.14; int radius = 2; double area = radius * radius * PI; System.out.println("Area of a circle is " + area); } } หลงจากท compile และ run โปรแกรม ผลลพธทไดคอ Area of a circle is 12.56 ถาเราเปลยนแปลงโปรแกรม Final.java ดวยการกาหนดคาใหกบตวแปร PI ใหม ดงทเหนในโปรแกรม FinalWithError.java น compiler จะฟองดวยขอมลดงทเหน /* * FinalWithError.java - Changing the value of final keyword */

Page 24: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 19 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class FinalWithError { public static void main(String[] args) { final double PI = 3.14; int radius = 2; double area = radius * radius * PI; System.out.println("Area of a circle is " + area); PI = 3.142; area = radius * radius * PI; System.out.println("Area of a circle is " + area); } } ผลของการ compile FinalWithError.java:14: cannot assign a value to final variable PI PI = 3.142; ^ 1 error ขออธบายถงขอความ error ท Java ฟองสกนดหนอย ถาผอานสงเกต error ทเกดขนจะเหนเลข 14 ถดจากชอของโปรแกรมทไดรบการ compile ซงบงบอกถงเลขทบรรทดท error นเกดขน รวมไปถงตาแหนงท error เกดขนซงเปนตวชวยใหเรากลบเขาไปแกไขโปรแกรมของเราไดงายยงขน (ไมตองเสยเวลาคนหาบรรทดทเกด error) การใช final ทาใหโปรแกรมมความแมนยาและมนคงมากยงขน ความพยายามทจะเปลยนคาเหลานกไมสามารถทาได ทาใหการออกแบบและพฒนาโปรแกรมเปนไปไดดวยด ลดขอผดพลาดทอาจเกดขนจากตวโปรแกรมเมอรเอง ในบางครงการประกาศตวแปรตองการใชคาทสงมาก ๆ หรอ คาทเลกมาก ๆ เชน ระยะทางจากโลกไปยงดวงอาทตย ซงมคาโดยประมาณเทากบ 149, 600,000 กโลเมตร (1.496 x 108) หรอ การกาหนดคาของมวลของอเลคตรอน (electron mass) ซงมคาเลกมาก ขนาดของมวลโดยประมาณมคาเทากบ 0.0000000000000000000000000009 กรม (9.0 x 10-28) เรากสามารถทาไดดวยการใชการประกาศในรปแบบของการกาหนดคาทางวทยาศาสตร (scientific notation) เชน final double sunDistance = 1.496E8; // 1.496 x 108 final float electronMass = 9.0E-28F; // 9.0 x 10-28 การประกาศและกาหนดคาในรปแบบนทาใหการมองเหน และ การเขยนหรอการอานทาไดงายยงขน ลองนกถงการทเราตองเขยนประโยคในการกาหนดคาใหกบ มวลของอเลคตรอน ทไดกลาวถงขางตนซงมศนยถง 27 ตววานาราคาญขนาดไหน (โปรแกรมเมอรสวนใหญรเรองนด) ยงถาเราเขยน code เยอะ ๆ การกาหนดคาใหกบตวแปรเหลานดวยการเขยนทสนทสดยอมเปนการดเสมอ (เขยนโปรแกรมไดไวขน?) อาย และ ขอบเขตการใชงาน (life-time and scope) ของตวแปร หลงจากทมการประกาศใชตวแปรใด ๆ ในโปรแกรม ตวแปรเหลานจะมขอบเขต หรออายการใชงานตามลกษณะการประกาศตวแปรของผเขยนโปรแกรมเอง โดยทวไปตวแปรจะมอายการใชงานตามเนอท (block) ทตวแปรเหลานนปรากฏอย ซงจะอยในเครองหมาย {} เชนโปรแกรมตวอยางตอไปน /* Scope.java - Showing scope of variables */ class Scope { public static void main(String[] args) { int x = 5, y = 8;

Page 25: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 20 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.print("Value of x is "); System.out.println(" Value of y is " + y); { int x = 45; //error x is already defined int w = 89; System.out.println("Value of x in brackets is " + x); System.out.println("Value of y in brackets is " + y); } //error w is out of scope System.out.println("Value of w is " + w); } } เปนทแนนอนอยแลววาโปรแกรม Scope.java จะ compile ไมผาน เนองจากเหตผลสองอยางดงท compiler ฟอง คอ (1) ตวแปร int x ไดมการประกาศใน main() แลว และ (2) ตวแปร int w ไมไดอยใน scope ของมนเอง ซงในทนคอ block ทมการประการ int x และ int w Scope.java:13 x is already defined in main(java.lang.String[]) int x = 45; ^ Scope.java:19: cannot resolve symbol symbol : variable w location: class Scope System.out.println("Value of w is " + w); ^ 2 errors ในภาษาอน เชน C++ การประกาศตวแปรใน block ใหมดวยตวแปรทมชอซากนสามารถทาไดโดยไมมเงอนไขใด ๆ (ดงทเหนในโปรแกรม Scope.java) แตตว Java เองไมยอมใหมการประกาศตวแปรซาถงแมวาจะอยใน block ใหมทซอนกนอยกตาม ลองมาดโปรแกรมตวอยางอกตวหนง /* Scope2.java - Showing scope of variables */ class Scope2 { static int x = 8, y; public static void main(String[] args) { { int x; x = 5; y = x; System.out.println("Value of y is " + y); } y = x; System.out.println("Value of y is " + y); } }

โปรแกรม Scope2.java หลงจากท compile ผานแลวจะไดผลลพธดงน Value of y is 5 Value of y is 8 จะเหนวา compiler ยอมใหผานทงนเพราะตวแปร x ใน block ดานในมการประกาศและกาหนดคาอยางสมบรณ และ ตวแปร x ใน scope ดานนอกมการกาหนดใหเปน static ซงเปนตวแปรท Java เรยกวา class variable ดงนนตวแปรทงสองจงไมใชตวแปรเดยวกน เพราะฉะนนการกาหนดคาใหกบตวแปร y ใน

Page 26: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 21 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

block ดานในจะไดคาของตวแปร x ทอยดานใน และการกาหนดคาใหกบ y อกครงดานนอกจงไดคาของ class variable ทชอวา x เรามาลองดโปรแกรมตวอยางอกโปรแกรมหนง /* Scope2v1.java - Showing scope of variables */ class Scope2v1 { static int x = 8, y; public static void main(String[] args) { { //int x; x = 5; y = x; System.out.println("Value of y is " + y); } y = x; System.out.println("Value of y is " + y); } } โปรแกรม Scope2v1.java แสดงการใชตวแปร x ตวเดยวทไดประกาศกอน method main() ซงมคาเปน 8 ดงนนการเปลยนคาของ x ใน block ดานในทาใหคาของตวแปร x เปนคาลาสดคอ 5 ผลลพธของการ run โปรแกรมนจงไดอยางทคาดหวงไว คอ Value of y is 5 Value of y is 5 ลองมาดอกตวอยางหนง /* Scope3.java - Showing scope of variables */ class Scope3 { static int x; public static void main(String[] args) { int x = (x = 12) + 8; System.out.println("Value of local x is " + x); } } ในโปรแกรม Scope3.java นเราประกาศตวแปรสองตวทมชอเหมอนกนคอ x โดยทตวหนงม scope อยใน class Scope3 และอกตวหนงม scope อยใน method main() และเมอ compile ผานแลวผลลพธทได คอ Value of local x is 20 คาถามทเกดขนคอ ตวแปร x ตวใดท Java นามาใชในการกาหนดคาของประโยค int x = (x = 12) + 8; เพอใหเหนวา Java ใชตวแปร x ตวไหนเราจงดดแปลง code ใหมโดยกาหนดคาใหกบตวแปร x ทอยดานนอกใหเปน 4 ดงโปรแกรม Scope3v1.java ทเหนน /* Scope3v1.java - Showing scope of variables */ class Scope3v1 { static int x = 4; public static void main(String[] args) { int x = x + 8;

Page 27: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 22 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.println("Value of local x is " + x); } } และเมอ compile เราจงรวา Java ใชตวแปร x ทอยใน block ดานในเพราะวา compiler ฟองดวย error Scope3v1.java:8 variable x might not have been initialized int x = x + 8; ^ 1 error เพอใหการ compile ผานเราจงแกไข code ใหมดงทแสดงใหเหนในโปรแกรม Scope4.java /* Scope4.java - Showing scope of variables */ class Scope4 { public static void main(String[] args) { int x = (x = 12) + 8; System.out.println("Value of local x is " + x); } } โปรแกรม Scope4.java เปนโปรแกรมเดยวกนกบโปรแกรม Scope3.java เพยงแตเราลบการประกาศตวแปรทอยดานนอกออก และเมอ compile และ run ผลลพธทไดกคอผลลพธเดมทไดจากโปรแกรม Scope3.java แตถาอยากจะใหแนใจวา Java ใชตวแปรตวไหนจรง ๆ กลองเปลยน code ใหเปนดงทเหนในโปรแกรม Scope5.java (ถงตอนนผอานคงสามารถทายไดวาอะไรจะเกดขนถามการ compile) /* Scope5.java - Showing scope of variables */ class Scope5 { public static void main(String[] args) { int x = x + 8; System.out.println("Value of local x is " + x); } } compiler กจะฟองดวย error Scope5.java:7: variable x might not have been initialized int x = x + 8; ^ 1 error ซงเปน error ทเหมอนกนกบ error ทเกดขนจากการ compile โปรแกรม Scope3v1.java (เพราะวาตวแปร x ยงไมมคากาหนดใด ๆ เลย) ลองมาดอกตวอยางหนง /* Scope6.java - Showing scope of variables */ class Scope6 { public static void main(String[] args) { int x = 12, y = x + 8; System.out.println("Value of local y is " + y); } } ซงไดผลลพธหลงจากการ compile และ run ดงน

Page 28: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 23 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Value of local y is 20 การประกาศและกาหนดคาแบบนสามารถทาไดเพราะ x ไดรบการกาหนดคากอนทจะถกนามาใชในการประกาศและกาหนดคาใหกบตวแปร y การประกาศและกาหนดคาใหกบตวแปรใด ๆ นนจะตองคานงถงการใช และขอบเขตของการใชเสมอ ทงนในการกาหนดคาใด ๆ ใหกบตวแปรนนสงทนามากาหนดคานนในตวของมนเองจะตองมคาอยแลว หรอสามารถทจะทาการประมวลคาไดกอนทจะนามาใชในการกาหนดคาใหกบตวแปรอน ดงเชนตวอยางทเหนกอนหนาน เราจะมาดเรองของ scope ในสถานะอน ๆ เชน scope ของ ตวแปรทเกยวของกบ method, class และตวแปรในสถานะอน ๆ ทอยในเนอหาทเราจะไดพดถงในบทตอ ๆ ไปเมอเราไดพดถงเรองนน ๆ แตจะขอบอกในทนวาตวแปรถกแบงออกเปน 7 แบบคอ 1. class variable 2. instance variable 3. array component 4. method parameter 5. constructor parameter 6. exception-handler parameter 7. local variable แตเราไดพดไปเพยงสองแบบคอ แบบท 1 (class variable) และแบบท 7 (local variable) การสรางประโยค (statement and expression) ในภาษา Java ประโยค (statement) จะตองจบดวยเครองหมาย ; (semicolon) เสมอดงตวอยางทแสดงใหเหนน int priceOfBook = 125; float taxReturn; เราไมจาเปนจะตองเขยนประโยคใหจบภายในบรรทดเดยว แตทสาคญตองมเครองหมาย ; ปดทายเสมอ เชน int priceOfBook = 125 ; Java จะมองหาเครองหมาย ; เสมอโดยไมแยแสวาประโยคนน ๆ จะกนเนอทกบรรทด แตทสาคญกคอการเขยนททาใหอานไดงาย ยอมจะทาใหทงเรา และผอนสามารถทจะด code ไดรวดเรวยงขน ถาไมเชอลองด code จากโปรแกรมนดส /* Scope2v1.java - Showing scope of variables* @author faa xumsai*/class Scope2v1{static int x = 8, y;public static void main(String[] args) { {int x;x = 5;y = x;System.out.println("Value of y is " + y);}y = x; System.out.println("Value of y is " + y);}} การเขยน code ใหมรปแบบทเหมาะสม อานไดงาย จะทาใหการพฒนาโปรแกรมเปนไปไดดวยความรวดเรวและเปนทยอมรบตามระบบสากล รปแบบทเหมาะสมนนคอมการยอหนา (indentation) เพอใหการอานทาไดงาย และมองดแลวสวยงาม ดงโปรแกรมตวอยางหลาย ๆ ตวทแสดงใหเหนกอนหนาน Expression หมายถงประโยคในภาษา Java ทไดรบการยอมรบวาอยในรปแบบทไดกาหนดไว เชน ประโยคในเรองของการกาหนดคาใหกบตวแปร ประโยคทตองมการประมวลผลในรปแบบตาง ๆ เชน การ

Page 29: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 24 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ประมวลผลทางดานคณตศาสตร (mathematical evaluation) การประมวลผลทางดานตรรกะ (relational evaluation) เปนตน การประมวลผลทางดานคณตศาสตรนน ม operator ทใชอยดงน คอ + (บวก), – (ลบ), * (คณ), / (หาร) และ % (การหาเศษทเหลอจากการหารตวเลขทเปน integer) โปรแกรมตวอยางตอไปนแสดงถงการประมวลผลของขอมลดวย operator ชนดตาง ๆ ทไดกลาวถง /* Operators.java - Shows mathematical operators */ class Operators { public static void main(String[] args) { int i, j, k; //generate random number between 1 and 10 j = 1 + (int)(Math.random() * 10); k = 1 + (int)(Math.random() * 10); System.out.println("j = " + j + " and k = " + k); //evaluate and display results of math operators i = j + k; System.out.println("j + k = " + i); i = j - k; System.out.println("j - k = " + i); i = j * k; System.out.println("j * k = " + i); i = j / k; System.out.println("j / k = " + i); i = j % k; System.out.println("j % k = " + i); } } เนองจากวาเราตองการทจะแสดงถงการสรางประโยคและการประมวลผลดวยคาทมาจาก ขางในโปรแกรมเอง และเราไดใชเครองมอในการสรางคาเหลานใหเราแบบอตโนมต ซงเครองมอทวานกคอ method random() ทมาจาก class Math (มอยใน Java แลว) method random() จะสรางคาระหวาง 0 – 0.9+ พดงาย ๆกคอ คาตาสดคอ 0 และคาสงสดคอ คาทใกล 1 แตไมเทากบ 1 (คา n ใด ๆ ทอยในเงอนไขน

0.0 <= n < 1.0) เมอไดคานแลวเราคณคานดวย 10 แลวบวก 1 เรากจะไดคาระหวาง 1 – 10 หลงจากนนเรากคานวณหาคา i ดวยการใช operator ตาง ๆ พรอมทงแสดงคาทหาไดไปยงหนาจอ และเมอ run โปรแกรมผลลพธทไดคอ j = 5 and k = 2 j + k = 7 j - k = 3 j * k = 10 j / k = 2 j % k = 1 และเนองจากวาเราใช method random() เปนตวหาคา ดงนนการ run ในแตละครงกจะไดผลลพธทอาจซากน หรอแตกตางกน Operator ตวอน ๆ กเหมอนกบการคานวณ ทางดานคณตศาสตรทเราคนเคยโดยทวไป ยกเวน % ซงเปนการหาเศษจากการหาร integer ประโยค i = j % k; จะนาเอาคาของตวแปร k คอ 2 ไปหารคาของตวแปร j ซงมคาเปน 5 แลวเกบเศษทไดจากการหารไว (ซงกคอ 1) เมอไดแลวกนาคานไปเกบไวในตวแปร i ตอไป โปรแกรมตวอยางตอไปนแสดงถงการกาหนดคาดวยขอมลชนด int และ double

Page 30: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 25 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

/* Operators.java - Shows mathematical operators */ import java.util.Random; class Operators { public static void main(String[] args) { //do the ints int i, j, k; //generate random number between 1 and 10 Random rand = new Random(); j = 1 + rand.nextInt(10); k = 1 + rand.nextInt(10); System.out.println("j = " + j + " and k = " + k); //evaluate and display results of math operators i = j + k; System.out.println("j + k = " + i); i = j - k; System.out.println("j - k = " + i); i = j * k; System.out.println("j * k = " + i); i = j / k; System.out.println("j / k = " + i); i = j % k; System.out.println("j % k = " + i); //do the doubles double v1, v2, v3; //generate random double between 1.0 and 10.0 (exclusive) v1 = 1.0 + rand.nextDouble() * 9; v2 = 1.0 + rand.nextDouble() * 9; System.out.println("v1 = " + v1 + " v2 = " + v2); v3 = v1 + v2; System.out.println("v1 + v2 = " + v3); v3 = v1 - v2; System.out.println("v1 - v2 = " + v3); v3 = v1 * v2; System.out.println("v1 * v2 = " + v3); v3 = v1 / v2; System.out.println("v1 / v2 = " + v3); } } โปรแกรม Operators.java แสดงตวอยางของการกาหนดคา และ การคานวณดวย operator อยาง งาย ๆ ทางดานคณตศาสตร โดยเรมตนดวยการกาหนดคาใหกบตวแปร i และ j ดวยการสรางคาแบบสม (random) จาก method nextInt(max value) ซง method นจะกาหนดคาทอยระหวาง 0 ถง คาทกาหนดใน max value แตไมรวมตว max value ดวยซงถาเราตองการทจะสรางคาทอยระหวาง 1 ถง 10 เรากตองบวก 1 เขากบคาทเกดจากการเรยกใช method นดวย ดงทไดกาหนดไวในโปรแกรม เราสามารถทจะเขยนประโยคทมการประมวลผลในรปของประโยคทมหลายตวแปรในประโยคเดยวกนได ดงตวอยางน /* Operators1.java - Shows mathematical operators */ class Operators1 { public static void main(String[] args) { int a, b, c, d, e; b = 1 + (int)(Math.random() * 10); c = 1 + (int)(Math.random() * 10); d = 1 + (int)(Math.random() * 10); e = 1 + (int)(Math.random() * 10); System.out.print("b = " + b + " c = " + c); System.out.println(" d = " + d + " e = " + e); a = b + c - d; System.out.println("Value of a is " + a); a = b * c - d; System.out.println("Value of a is " + a);

Page 31: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 26 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

a = b / c * d; System.out.println("Value of a is " + a); } } ผลลพธทไดจากการ run คอ b = 8 c = 2 d = 6 e = 5 Value of a is 4 Value of a is 10 Value of a is 24 การประมวลผล เมอมตวแปรหลายตวในการประมวลผลของประโยค ลาดบขน (precedence) ของการประมวลผลมความสาคญทนท ทงนกเนองมาจากรปแบบของการประมวลผลตามชนของ operator ตาง ๆ มลาดบการประมวลผลทไมเทากน (กอน หรอ หลง) ซงเปนไปตามลาดบขนของการประมวลผลตามกฎของการประมวลผลทางดานคณตศาสตร ดงตารางท 2.4 ตาราง 2.4 Operator Precedence Operator ตามกลม การประมวลผล (), [], ., postfix ++, postfix -- ซายไปขวา unary +, unary –, prefix ++, prefix -- ขวาไปซาย (datatype), new ซายไปขวา *, /, % ซายไปขวา +, - ซายไปขวา <<, >>, >>> ซายไปขวา <, <=, >, >=, instance of ซายไปขวา ==, != ซายไปขวา & ซายไปขวา ^ ซายไปขวา | ซายไปขวา && ซายไปขวา || ซายไปขวา ?: ซายไปขวา =, +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, |=, ^= ขวาไปซาย

การประมวลผลขอมลทเปน integer การประมวลผลขอมลทเปน integer ทงหมดไมมความสลบซบซอนอะไรเลย เปนการประมวลผลเหมอนกบทเราเคยเรยนมา ในวชาคณตศาสตรซงลาดบขนของการประมวลผลกขนอยกบชนดของ operator ทใชในการประมวลผลนน ๆ เชน การคณและการหาร ทากอน การบวกและการลบ statement 50 * 2 – 45 / 5 จะไดผลลพธคอ 91 ซงไดมาจากการนาเอา 2 ไปคณ 50 กอนหลงจากนนกเอา 5 ไปหาร 45 เมอไดแลวกนาเอาผลลพธทไดไปลบออกจากผลลพธของการคณ 50 กบ 2 ซงมคาเทากบ 100 – 9 แตถาเราตองการทจะใหการประมวลผลอยในรปแบบอน ทเราตองการเรากใชวงเลบเปนตวกาหนด เชน ถาเราตองการทจะใหการลบเกดกอน ในประโยคทเหนกอนหนานเรากเขยนใหมเปน 50 * (2 – 45) / 5 ซงมคาเทาเทยมกบประโยค 50 * -43 / 5

Page 32: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 27 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

และมคาเทากบ -430 เนองจากวาการประมวลผลขอมลทเปน integer โดยเฉพาะการหารนน เราจะไมมเศษเหลอใหทาการหารตอไปเหมอนทเราเคยหารกนมา เชน ถาเราเอา 4 ไปหาร 9 เรากจะได 2.25 แตถาเปนการหารดวย integer ใน Java แลวผลลพธทเราไดจากการหารนจะเปน 2 เทานน เราจะไมไดเศษ เราจะไดแตสวน ลองดตวอยางตอไปน 5 / 2 = 2 125 / 4 = 31 3 / 9 = 0 15 / 15 = 1 แตเรากหาเศษไดดวยการใช operator % ดงทไดแสดงในโปรแกรมตวอยางกอนหนาน หรอดงตวอยางการหาเศษตอไปน 5 % 2 = 1 125 % 4 = 1 3 % 9 = 3 15 % 15 = 0 โดยทวไปเทาทพบเหนและประสพมา ผอานทใหมตอการเขยนโปรแกรม มกจะสบสนในเรองของการหาเศษ หรอการหาสวนของขอมลทเปน integer อยางไรกตามเรองเหลานมกจะหายไปถาไดทดลองทาอยางสมาเสมอ สาหรบ Java นนการหาเศษสามารถทจะทาไดกบขอมลทเปน double หรอ float ดวย แตในทนจะทงไวใหผอานไดทดลองทาการตรวจสอบดเอง (เนองจากวาผเขยนเองยงมองไมเหนประโยชนของการหาเศษจากขอมลทเปน double หรอ float เลย) ในการเขยนโปรแกรมนนเราเกบขอมลไวในตวแปร ดงนนการประมวลผลกตองทากบตวแปรเหลานน เชน เราสามารถทจะคานวณหาคาของภาษมลคาเพม (vat) จากตวแปร price และ rate ถาตวแปรทงสองไดรบการกาหนดคาเรยบรอยแลว เชน double price = 120.0, rate = 7.5; double vat = price * rate; ลองมาดโปรแกรมตวอยางการประมวลผลดวยขอมลทเปน integer /* * Integer.java - Integers calculation */ class Integer { public static void main(String[] args) { //declares and initialize three variables int studentNumber = 40; int teacherNumber = 30; int totalNumber = 0; totalNumber = studentNumber + teacherNumber; //display result System.out.print(studentNumber + " students + " + teacherNumber); System.out.println(" teachers = " + totalNumber + " people"); } }

Page 33: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 28 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

โปรแกรม Integer.java เปนการแสดงถงการคานวณหาคาของผลรวมของจานวนนกศกษา (studentNumber)และคร (teacherNumber) จากประโยค totalNumber = studentNumber + teacherNumber; ซงขนตอนของการประมวลผล อาจพดไดคราว ๆ คอ Java นาเอาคาทเกบไวในตวแปร studentNumber และคาทเกบไวในตวแปร teacherNumber มารวมกนและนาเอาผลลพธทไดไปเกบไวในตวแปร totalNumber ผานทางเครองหมาย = (assignment operator) ลองดภาพท 2.2

ภาพท 2.2 การบวก integer สองตว ในการแสดงผลลพธทไดจากการประมวลผลไปยงหนาจอนน เราสงผานทาง System.out.print() และ System.out.println() ประโยค System.out.print(studentNumber + " students + " + teacherNumber); จะใหผลลพธคอ คาทเกบไวในตวแปร studentNumber ตามดวย string ทมคาเปน "student +" ตามดวยคาทเกบไวในตวแปร teacherNumber ในบรรทดเดยวกน หลงจากนนประโยค System.out.println(" teachers = " + totalNumber + " people"); กจะใหผลลพธ คอ string ทมคาเปน " teachers = " ตามดวยคาทเกบไวในตวแปร totalNumber ตามดวย string ทมคาเปน " people" ซงเมอรวมแลวทงหมดกจะไดผลลพธทแสดงไปยงหนาจอดงน 40 students + 30 teachers = 70 people คาวา "ตามดวย" จากคาอธบายดานบนนเกดจากการประมวลผลของ Java กบเครองหมาย + ในการใชประโยคของการแสดงผล (System.out) ขอมลใด ๆ ทอยในเครองหมาย " " จะถกสงไปยงหนาจอ แตถาเปนตวแปรหรอประโยคทตองมการประมวลผลอก Java จะทาการประมวลผลกอนเพอใหไดคาสดทายทสามารถจะสงออกไปหนาจอได เชน System.out.println("30 + 45 = " + (30 + 45)); สงทถกสงออกไปกอนคอ "30 + 45 = " ตามดวยคาของการประมวลผลของประโยค (30 + 45) ซงกคอ 75 ดงนนผลลพธทสงไปยงหนาจอคอ 30 + 45 = 75 วงเลบในประโยคของการบวก 30 กบ 45 กมสวนสาคญเพราะถาไมม Java กจะแสดงผลเปน

teacherNumber

studentNumber

totalNumber

40 30

70

+

Page 34: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 29 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

30 + 45 = 3045 การใสวงเลบเปนการบอก Java ใหทาการคานวณหาคาของประโยคนน ๆ ทงนเฉพาะในประโยคทใช System.out เทานน สวนการประมวลผลทอน ๆ กทาตามเดม เหตทเปนเชนนกเพราะวา System.out จะนาคานน ๆ ทเปนอยไปแสดงถาไมมการคานวณใด ๆ สมมตวาเราตองทาการบวกคาใดคาหนงใหกบตวแปร เรากสามารถทจะสรางประโยคไดเหมอนกบทเราเคยทามากอนหนาน เชน total = total + value; ถาเราลองเขยนภาพแทนประโยคดงกลาว เรากอาจเขยนไดดงน

ภาพท 2.3 การเพมคาใหกบตวแปรตวเดม ประโยคทเหนดานบนนสามารถทจะเขยนอกแบบได ดงนคอ total += value; เราใชเครองหมาย += ในการสรางประโยคของเรา แตไดผลลพธเชนเดยวกนกบประโยคกอนหนาน และลดเวลาในการเขยนลง (ถงแมวาจะไมมากกตาม) เชนเดยวกบการประมวลผลดวย operator ตวอน ๆ เรากสามารถจะใชวธเดยวกนนได ดงทไดสรปไวใน ตาราง 2.5 ตาราง 2.5 การใช operator ตาง ๆ รวมกบการกาหนดคา ประโยคตวอยาง ประโยคทไดผลลพธเหมอนกน sum = sum + count; sum += count; sum = sum - count; sum -= count; sum = sum * count; sum *= count; sum = sum / count; sum /= count; sum = sum % count; sum %= count;

การกาหนดคาแบบนไมจาเปนทจะตองทากบตวแปรเทานน เราสามารถทจะทากบคาคงทอน ๆ ได เชน total += 4; sum += 1; ยงม operator ทเราสามารถใชไดโดยไมตองเสยเวลาในการเขยนมากมายนก เชน การเพม หรอ ลดทละหนงคา ดงประโยคตวอยาง count = count + 1; value -= 1;

value

total

total value+

Page 35: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 30 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ทงสองประโยคทเหนดานบนทาการเพมคาและลดคาทละหนงคา ตามลาดบ เราสามารถทจะเขยนใหมดวยการใช operator ++ และ operator -- ไดดงน คอ count++; value--; จะเหนวาถาเราตองการเพมคาเพยงแคหนงคาเรากใชเครองหมาย ++ ตามหลงตวแปรนน เชนเดยวกนถาเราตองการลดคาลงหนงคา เรากใชเครองหมาย –- ตามหลงตวแปรนน เราเรยกการเขยนแบบนวา การเขยนแบบ postfix (postfix notation) ซงเปนการใช operator ตามหลงตวแปร และ Java ยอมใหมการเพมหรอลดคาไดเพยงแคหนงคาเทานน ถาเราตองการเพมหรอลดคามากกวาหนงคา เราตองใชวธสองวธทไดแสดงการใชกอนหนาน เชน ถาตองการเพมทละสอง เรากเขยนเปน total += 2; และถาเราตองการลดทละสาม เรากเขยนเปน total -= 3; Java ยงม Operator อกตวหนงทเราสามารถเลอกใช ในการประมวลผลถาเราคานงถงขนตอนของการประมวลผล วาควรจะทาอะไรกอน อะไรหลง ดงประโยคตวอยางตอไปน int count = 8, value = 5; count = count + value++; ถามองดเผน ๆ เรากอาจบอกวาประโยคนเปนการบวกคาของตวแปร value เขากบตวแปร count พรอมกบการเพมคาใหกบตวแปร value อกหนงคา แตเรารหรอไมวาอะไรไดรบการประมวลผลกอน count + value กอน หรอ value++ กอน และผลลพธทไดจากการบวกคออะไร จากประโยคดานบน Java จะนาเอาคาของ value มาบวกเขากบคาของ count กอน หลงจากนนจงเพมคาใหกบตวแปร value อหนงคา ดงนนถาเรา execute ประโยค count = count + value++ เรากจะไดผลลพธเปน 13 และคาของ value หลงจากการบวกจะเปน 6 แตถาเราเปลยนประโยคใหเปนดงน count = count + ++value; เราจะไดผลลพธจากการบวกเปน 14 (ทาไม) เนองจากวาเราใชเครองหมาย ++ นาหนาตวแปร ดงนน Java จงทาการเพมคาใหกบตวแปร value กอน หลงจากนนจงนาคาทไดนไปบวกเขากบคาของตวแปร count ผลลพธทไดจงเปน 14 ดงทเหน เราเรยกการเขยนแบบนวาการเขยนแบบ prefix (prefix notation) ขนอยกบตาแหนงทใช prefix หรอ postfix ในประโยค บางครงการประมวลผลจาก Java อาจไดผลลพธทเหมอนกน เราจะกลบมาพดถงกรณดงกลาวในเรองของการทางานแบบวน หรอ loop (repetition) ลองมาดตวอยางการใช prefix และ postfix กนอกสกหนอย int count = 10, value = 5; count--; value++; value = ++count + ++value; ถาเรา execute ประโยค value = ++count + --value; เรากจะไดผลลพธ คอ value มคาเปน 17 เพราะกอนหนานน count มคาเปน 9 และ value มคาเปน 6 (จาก count—และ value++) แตไดรบการเพมใหอกหนงคากอนการบวกในประโยคสดทาย

Page 36: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 31 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ถาหากวาเราตองการให code ทเขยนนนอานไดงายขนเรากอาจใชวงเลบเปนตวชวยกได เชน value = (++count) + (++value); หรออาจเขยนใหดแลวเวยนหวแบบน value = (count += 1) + (value += 1); หรอแบบน value = (count = count + 1) + (value = value + 1); สวนประโยคตอไปนจะใหผลลพธตางจากตวอยางดานบน (ทาไม?) value = (count++) + (value++); ถาเราลองวเคราะหประโยคดานบนน ดวยคาของ count = 10 และคาของ value = 5 และตามขอกาหนดการใชงานของ postfix ++ เรากตองสรปวา Java จะนาเอาคาของ count ซงมคาเทากบ 10 บวกเขากบคาของ value ซงมคาเทากบ 5 เมอไดแลวกนาผลลพธทไดไปเกบไวในตวแปร value ดงนน value จงมคาเทากบ 15 หลงจากนนกจะเพมคาใหกบ count และ value อกหนงคา ซงทาให count มคาเทากบ 11 และ value มคาเทากบ 16 แตเมอทดลอง run ดแลวผลลพธทไดกลบเปน value = 15 และ count = 11 ทาไม? เพอใหเกดความกระจางเรากทดลองเขยนประโยคตรวจสอบใหม คอ value = 5; value = value++; และเมอ run ดเรากไดผลลพธเปน value = 5 ทาใหเราคอนขางจะมนใจวา Java ไมยอมให postfix operator ++ เพมคาใหกบตวแปรเดมทไดรบการกาหนดคาในประโยคเดยวกน แตเพอใหแนใจขนอกเรากทดลอง run ดวยประโยค int sum = value++; เราไดผลลพธเปน sum มคาเทากบ 5 และ value มคาเทากบ 6 ดงนนเราจงมนใจวา postfix operator ++ ไมยอมใหมการเพมคาใหกบตวแปรตวเดยวกนกบทใชในการกาหนดคาในประโยคเดยวกน (ดงทไดกลาวไว) การเขยนโปรแกรมทดนนไมควรเขยนใหอานยาก เชนตวอยางของการใช ++ ทไดกลาวถงกอนหนาน ถาการเขยนนนไดผลลพธดงทเราตองการ ถงแมวาจะเขยนดวยประโยคหลาย ๆ ประโยค กยงดกวาทเขยนดวยจานวนประโยคทสน แตอานไดยากกวา ตวอยางตอไปนเปนการใช operator ++ และ operator – ในรปแบบตาง ๆ /* Increments.java - Shows increment operators */ class Increments { public static void main(String[] args) { int value = 25, number = 25; System.out.println("value is " + value); System.out.println("number is " + number); --value; number++; System.out.println("value is " + value); System.out.println("number is " + number); value = value + --number; System.out.println("value is " + value);

Page 37: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 32 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.println("number is " + number); number = number - value++; System.out.println("value is " + value); System.out.println("number is " + number); number--; value++; System.out.println("value is " + value); System.out.println("number is " + number); value = --value; number = number++; System.out.println("value is " + value); System.out.println("number is " + number); } } ผลลพธทไดจากการ run value is 25 number is 25 value is 24 number is 26 value is 49 number is 25 value is 50 number is -24 value is 51 number is -25 value is 50 number is -25 ผอานควรทดสอบการใช operator increment ทงสอง (++ และ --) ในประโยคสมมตตาง ๆ เพอใหเกดความเขาใจในการใช operator ทงสองไดดยงขน การประมวลผลดวย integer ขนาดเลก (short และ byte) ในการประมวลผลดวยขอมลทเปน byte หรอ short นน Java จะทาการประมวลผลเชนเดยวกนกบการประมวลผลดวยขอมลทเปน int และผลลพธของการประมวลผลขอมลทเปน short หรอ byte นนจะถกเกบอยในรปแบบของขอมลทเปน int ดงตวอยางตอไปน /* ByteShort.java - Shows byte and short integer calculation */ class ByteShort { public static void main(String[] args) { short numScooters = 10; short numChoppers = 5; short total = 0; total = numScooters + numChoppers; System.out.println("Number of scooters is " + numScooters); System.out.println("Number of choppers is " + numChoppers); System.out.println("Total number of bikes is " + total); } } เมอได compile แลว Java จะฟองวาม error เกดขน ByteShort.java:10: possible loss of precision

Page 38: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 33 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

found : int required: short total = numScooters + numChoppers; ^ 1 error เนองจากวาผลลพธของการบวกจะตองเกบเปน integer ทมขนาดเทากบ 64 bit แตตวแปร total สามารถเกบขอมลไดสงสดเทากบ 16 bit ดงนน compiler จงฟองทนท วธการแกไขกอาจจะตองเปลยนตวแปรทงสามใหเปน int หรอไมกใชวธการเปลยนชนดของขอมลทเรยกวา casting การเปลยนแปลงชนดของขอมลดวยการ cast ในการ cast นนเราจาเปนทจะตองคานงถงการจดเกบขอมลวาเราจะตองใชขอมลชนดไหน ในการจดเกบ การประกาศตวแปรกตองทาดวยความระมดระวง เนองจากวาการ cast นนถาเรา cast ขอมลทมขนาดใหญไปสขอมลทมขนาดเลก เราจะสญเสยคาความเปนจรงของขอมลนน เรามาทาการแกไขโปรแกรม ByteShort.java เพอให Java ยอมใหการ compile เปนไปไดดวยดกนดกวา วธการกไมยากเพยงแตเปลยนประโยค total = numScooters + numChoppers; ใหเปน total = (short)(numScooters + numChoppers); เทาน Java กยอมใหเรา compile และเมอเราทดลอง run ดกไดผลลพธดงทคาดไว คอ Number of scooters is 10 Number of choppers is 5 Total number of bikes is 15 ทนเราลองมาดกนวาถาเราเปลยนคาของ numScooters ใหเปน 32767 ดงทเหนดานลาง ผลลพธทไดในการ compile และ run โปรแกรมของเราจะเปนอยางไร short numScooters = 32767; //คาสงสดทเปนไปได short numChoppers = 5; ผลลพธทได คอ Number of scooters is 32767 Number of choppers is 5 Total number of bikes is -32764 จะเหนวาคาของ total เปน -32764 ซงเปนคาทไมถกตอง ซงถาบวกกนแลวคาทไดตองเปน 32772 ทาไม? เนองจากวาตวแปรทงสามตวมชนดเปน short และสามารถเกบขอมลไดสงสดเพยงแค 32767 ดงนนการนาเอาผลรวมทมคาเกนกวาคาสงสดทเปนไปไดมาเกบไวในตวแปร total จงไมสามารถทาไดแต Java กจะนาเอาคาอนทไดจากการประมวลผล (ทถกตองตามหลกการแตมคาความคลาดเคลอนของการประมวลผล – จานวน bit ทใชในการคานวณหายไปครงหนง จาก 64 bit เหลอเพยง 32 bit) มาใสไวให ผเขยนโปรแกรมจะตองทาความเขาใจเกยวกบชนดของของมล และการประมวลผลตามชนดนน ๆ ของขอมล ถาหากวาหลกเลยงได ผเขยนโปรแกรมกควรหลกเลยงการใช cast นอกเสยจากวาจาเปนตองใชจรง ๆ เทานน เรามาดการ cast อน ๆ จากโปรแกรม Casting.java /* Casting.java - Changing type of data */ class Casting { public static void main(String[] args) { byte byteVar = 127;

Page 39: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 34 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

short shortVar = 32767; long longVar = 100000; int intVar = 300000; System.out.println("byteVar is " + byteVar); System.out.println("shortVar is " + shortVar); System.out.println("longVar is " + longVar); System.out.println("intVar is " + intVar); byteVar = (byte)shortVar; shortVar = (short)longVar; longVar = (int)intVar * (int)longVar; intVar = (short)intVar * (short)intVar; System.out.println("byteVar is " + byteVar); System.out.println("shortVar is " + shortVar); System.out.println("longVar is " + longVar); System.out.println("intVar is " + intVar); } } ผลลพธทไดจากการ run คอ byteVar is 127 shortVar is 32767 longVar is 100000 intVar is 300000 byteVar is -1 shortVar is -31072 longVar is -64771072 intVar is 766182400 ในการประมวลผลดวยการใชขอมลทมชนดเปน long นน (บงคบใหเปน long ดวยการใส L ดานหลงคาทกาหนดใหกบตวแปรนน ๆ) ขอมลชนดอนจะถกเปลยนใหเปน long กอนการประมวลผล เชน long value = 125; long price = 200L; int total = 0; total = value * price; กอนการประมวลผลคาของตวแปร value จะถกเปลยนใหเปน long แลวจงนามาคณกบตวแปร price เพราะฉะนนในการประมวลผลขอมลทเปน integer นนขอควรคานงถงกคอ

o การประมวลผลกบตวแปรทประกาศเปน long ทมการกาหนดคาดวยตว L จะเปนการประมวลผลดวยการใชจานวน bit เทากบ 64 bit

o การประมวลผลกบตวแปรทประกาศเปน int จะเปนการประมวลผลดวยการใชจานวน bit เทากบ 32 bit

ปญหาของการประมวลผลดวยขอมลทมชนดเปน integer

o ถาเราหารตวแปรทมชนดเปน int ดวย 0 เราไมสามารถหาคาตอบได เพราะฉะนน Java จะทาการฟองดวย error แตเรากสามารถทจะตรวจสอบและแกไขไดดวยการใช exception ซงเปนวธดกจบ error ท Java เอออานวยใหผเขยนโปรแกรมไดทาการเอง เราจะพดถง exception ในโอกาสตอไป

o การประมวลผลดวยคาทเกนขดจากดของตวแปรจะทาใหไดผลลพธทคลาดเคลอน

Page 40: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 35 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

o การประมวลผลดวย % ทมคาของ 0 อยทางขวากทาใหเกด error เหมอนกบการหารดวย 0 การประมวลผลดวยตวแปรทมจดทศนยม (Floating Point Calculations) การประมวลผลของขอมลทเปนเลขทศนยมนนกคลายกนกบการประมวลผลดวยขอมลทเปน integer การใช operator ตาง ๆ กเหมอนกน คอ + - * / ลองมาดตวอยางกน /* FloatingPoint.java - Calculating income */ class FloatingPoint { public static void main(String[] args) { double weeklyPay = 1075 * 5; //1075 per day double extras = 1580; final double TAX_RATE = 8.5; //tax rate in percent //calculate tax and income double tax = (weeklyPay + extras) * TAX_RATE / 100; double totalIncome = (weeklyPay + extras) - tax; System.out.println("Tax = " + tax); System.out.println("Total income = " + totalIncome); } } โปรแกรม FloatingPoint.java เปนการคานวณหาภาษ และรายไดตอหนงอาทตย โดยเราสมมตใหรายไดตอวนเทากบ 1075 บาท และรายไดพเศษเทากบ 1580 บาท อดตราภาษเทากบ 8.5% เมอเรา execute โปรแกรมเรากจะไดผลลพธดงน Tax = 591.175 Total income = 6363.825 ในการคานวณหาภาษนนเราจาเปนทจะตองใชวงเลบในประโยค double tax = (weeklyPay + extras) * TAX_RATE / 100; เนองจากวาเราตองการใหการบวกทากอนการคณและการหาร ถาไมเชนนนแลวเราจะไมไดคารายไดโดยรวมทเปนจรง ถาเราสงเกตใหดผลลพธทไดจะมเลขหลงจดทศนยมอยสามตว เราทาใหเปนสองตวดงทใชกนอยทวไปไดมย? คาตอบกคอ ได ดวยการเพม code เขาไปในโปรแกรมดงน /* FloatingPoint2.java - Calculating income with formatted output */ import java.text.*; //for NumberFormat class FloatingPoint2 { public static void main(String[] args) { double weeklyPay = 1075 * 5; //1075 per day double extras = 1580; final double TAX_RATE = 8.5; //tax rate in percent //set format output NumberFormat form = NumberFormat.getNumberInstance(); form.setMaximumFractionDigits(2); //calculate tax and income double tax = (weeklyPay + extras) * TAX_RATE / 100; double totalIncome = (weeklyPay + extras) - tax; System.out.println("Tax = " + form.format(tax)); System.out.println("Total income = " + form.format(totalIncome));

Page 41: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 36 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} } เราเพมประโยค NumberFormat form = NumberFormat.getNumberInstance(); form.setMaximumFractionDigits(2); และเปลยนการแสดงผลลพธดวยการใช form.format(tax) และ form.format(totalIncome) เพอใหผลลพธทออกมาเปน Tax = 591.18 Total income = 6,363.82 จะเหนวา 591.175 จะถกปดใหเปน 591.18 และ 6363.825 ถกปดใหเปน 6363.82 โดยทคาของ totalIncome ม , (comma) เปนตวบอกถงจานวนของหลกรอยดวย ในการใช method ทง getNumbereInstance() และ setMaximumFractionDigits() นนเราจาเปนทจะตอง import class NumberFormat เขาสโปรแกรมของเรา ถาไมแลวเราจะไมสามารถใช method เหลานได ยงม method อนใน class DecimalFormat ทเราสามารถเรยกใชในการ format ผลลพธทเปนจดทศนยมได เชนถาเราไมตองการ , (comma) เปนตวแบงหลกเราจะทาอยางไร? ลองดตวอยางนด /* FloatingPoint3.java - Calculating income with formatted output */ import java.text.*; //for DecimalFormat class FloatingPoint3 { public static void main(String[] args) { double weeklyPay = 1075 * 5; //1075 per day double extras = 1580; final double TAX_RATE = 8.5; //tax rate in percent //set format output DecimalFormat form = new DecimalFormat("#.00"); //calculate tax and income double tax = (weeklyPay + extras) * TAX_RATE / 100; double totalIncome = (weeklyPay + extras) - tax; System.out.println("Tax = " + form.format(tax)); System.out.println("Total income = " + form.format(totalIncome)); } } ผลลพธทไดคอ Tax = 591.18 Total income = 6363.82 เราเพยงแตเรยกใช class DecimalFormat แทน NumberFormat และเปลยนการกาหนด format ใหเปน DecimalFormat form = new DecimalFormat("#.00); เรากจะไดผลลพธทมเลขหลงจดทศนยมอยสองตว และไมม , (comma) เปนตวแบงหลก ยงมวธการกาหนดรปแบบของการแสดงผลลพธอกมากมายแตเรากคงจะพดเพยงเทานกอน

Page 42: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 37 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การประมวลผลขอมลตางชนดกน (Mixed Type Calculations) ในการประมวลผลขอมลทมความหลากหลายของชนดในประโยคใด ๆ นน โดยทวไป Java จะทาการเปลยนชนดของขอมลทมขนาดเลกกวาใหเปนขนาดทใหญทสดในกลมของขอมลนน ๆ แตผเขยนโปรแกรมจะตองใชความระมดระวงในเรองของการจดเกบขอมลทมขนาดใหญไปไวในตวแปรทมขนาดเลก เชนเดยวกบทไดทามากอนหนานในเรองของการประมวลผลขอมลทเปน integer ลองมาดตวอยางกน /* FloatingPoint4.java - Mixed-type calculations */ import java.text.*; //for NumberFormat class FloatingPoint4 { public static void main(String[] args) { double hourlyPay = 85.50; //85.50 per hour int hoursPerDay = 8; //8 hours per day int numberOfDays = 5; //total days worked int extraHoursWorked = 15; //overtime hours final double TAX_RATE = 8.5;//tax rate in percent //set format output NumberFormat form = NumberFormat.getNumberInstance(); form.setMaximumFractionDigits(2); //calculate weekly pay double weeklyPay = hourlyPay * hoursPerDay * numberOfDays; //calculate extra pay: one and a half time of //regular hourly pay double extras = extraHoursWorked * (hourlyPay + (hourlyPay / 2.0)); //calculate tax double tax = (weeklyPay + extras) * TAX_RATE / 100; //calculate total income double totalIncome = (weeklyPay + extras) - tax; System.out.println("Income before tax = " + form.format((weeklyPay + extras))); System.out.println("Tax = " + form.format(tax)); System.out.println("Income after tax = " + form.format(totalIncome)); } } โปรแกรม FloatingPoint4.java ใชตวแปรทมชนดเปนทง double และ integer ปนกนในการคานวณหารายไดตอหนงอาทตย โดยกาหนดใหตวแปร hoursPerDay numberOfDays และ extraHoursWorked เปน integer สวนตวแปร hourlyPay weeklyPay extras tax และ totalIncome เรากาหนดใหเปน double การประมวลผลกไมยงยากอะไร Java จะเปลยนตวแปรทเปน int ใหเปน double กอนการประมวลผล เพราะฉะนนการจดเกบผลลพธกไมมคาความคลาดเคลอนใด ๆ เกดขน ดงผลลพธทแสดงน Income before tax = 5,343.75 Tax = 454.22 Income after tax = 4,889.53 ขอควรจาในการประมวลผลขอมลตางชนดกน (ในประโยคเดยวกน)

o ถามตวแปรใดเปน double ตวแปรทนามาประมวลผลดวยจะถกเปลยนใหเปน double กอนการประมวลผล

Page 43: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 38 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

o ถามตวแปรใดเปน float ตวแปรทนามาประมวลผลดวยจะถกเปลยนใหเปน float กอนการประมวลผล

o ถามตวแปรใดเปน long ตวแปรทนามาประมวลผลดวยจะถกเปลยนใหเปน long กอนการประมวลผล

สงทสาคญกคอขอมลทเลกกวาในประโยคจะถกเปลยนใหเปนชนดทใหญทสดในประโยคนน ๆ ซงบางครงกไมใชการประมวลผลทเราตองการ เชน ตวอยางของโปรแกรมตอไปน /* MixedTypes.java - Mixed-type calculations */ import java.text.*; class MixedTypes { public static void main(String[] args) { double result = 0.0; int one = 1, two = 2; result = 1.5 + one / two; //formatting output DecimalFormat f = new DecimalFormat("#.00"); System.out.println("Result is " + f.format(result)); } } ผลลพธทเราคาดหวงวาจะได คอ 2.0 แต Java กลบให 1.5 ซงเปนผลลพธทเราไมตองการ ถาสงเกตใหดจะเหนวาประโยค result = 1.5 + one / two; นน การหารจะเกดกอน และเนองจากวาทง one และ two เปน int ดงนนผลลพธของการหารจงมคาเปน int และมคาเปน 0 หลงจากนน Java กจะเปลยน 0 ทไดใหเปน double แลวจงทาการบวกเขากบ 1.5 เพอใหผลลพธเปนทเราตองการ ดงนนเราจงตองทาการ cast ใหตวแปร one เปน double เสยกอน ดงน /* MixedTypes.java - Mixed-type calculations */ import java.text.*; class MixedTypes { public static void main(String[] args) { double result = 0.0; int one = 1, two = 2; result = 1.5 + (double)one / two; //formatting output DecimalFormat f = new DecimalFormat("#.00); System.out.println("Result is " + f.format(result)); } } เรากจะไดผลลพธเปน 2.0 ดงทเราตองการ อยางไรกตามการ cast นนตองใชความระมดระวงเปนพเศษ หากเราทาการ cast ขอมลทใหญกวาไปเกบไวในตวแปรทเลกกวากจะทาใหเกดความคลาดเคลอนของขอมลได ดงทไดพดไวกอนหนาน เรามาลองดตวอยางอกตวอยางหนง /* FloatingPoint5.java - Mixed-type calculations */ import java.text.*; //for NumberFormat

Page 44: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 39 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class FloatingPoint5 { public static void main(String[] args) { double hourlyPay = 85.50D; //85.50 per hour int hoursPerDay = 8; //8 hours per day float numberOfDays = 5F; //total days worked int extraHoursWorked = 15; //overtime hours final double TAX_RATE = 8.5D;//tax rate in percent //set format output NumberFormat form = NumberFormat.getNumberInstance(); form.setMaximumFractionDigits(2); //calculate weekly pay double weeklyPay = hourlyPay * hoursPerDay * numberOfDays; //calculate extra pay: one and a half time of regular hourly pay double extras = extraHoursWorked * (hourlyPay + (hourlyPay / 2.0)); //calculate tax double tax = (weeklyPay + extras) * TAX_RATE / 100; //calculate total income double totalIncome = (weeklyPay + extras) - tax; System.out.println("Income before tax = " + form.format((weeklyPay + extras))); System.out.println("Tax = " + form.format(tax)); System.out.println("Income after tax = " + form.format(totalIncome)); } } เราไดเปลยนประโยค int numberOfDays = 5; ใหเปน float numberOfDays = 5F; และผลลพธทไดกยงคงถกตองเหมอนเดมทงนเพราะ Java จะเปลยน float ใหเปน double เชนเดยวกนกบทเปลยน int ใหเปน double จากตวอยางกอนหนาน การใช Mathematical Functions ตาง ๆ ท Java มให หลาย ๆ ครงทการเขยนโปรแกรมตองการใช function ทเกยวของกบการหาคาทางคณตศาสตร เชน การหาคาของ sine cosine tangent หรอ คาอน ๆ ทเกยวของกบการคานวณทางคณตศาสตร Java กไดทาการออกแบบและจดสรร function เหลานไวใหผใชไดเรยกใชอยางเตมท เราจะมาทดลองเรยกใช function ตาง ๆ เหลานด ตวอยางตอไปนจะเปนการคานวณหาคาของสมการ ทเรยกวา Quadratic Equation ax2 + bx + c = 0 ซงหาไดจากการใชสตร

aacbbx

242

1−+−

=

aacbbx

242

2−−−

=

ซง mathematical function ทเราตองใชกคอ การหา square root และ Java ไดจดเตรยม method ตวนไวใหเราแลวกคอ Math.sqrt() เรามาลองดโปรแกรมทหาคาของสมการตวนกนด /* Quadratic.java - Calculating roots of function */

Page 45: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 40 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class Quadratic { public static void main(String[] args) { double a, b, c; //4x2 + 20x + 16 = 0 a = 4; b = 20; c = 16; //calculate determimant double det = Math.sqrt(b * b - 4 * a * c); //calculate roots double x1 = (-b + det) / (2 * a); double x2 = (-b - det) / (2 * a); System.out.println("Root 1 = " + x1); System.out.println("Root 2 = " + x2); } } ผลลพธทไดคอ Root 1 = -1.0 Root 2 = -4.0 ในการเขยนโปรแกรม Quadratic.java ในครงนนนเราจะยงไมสนใจในเรองทคาของ determinant จะเปน 0 เนองจากวาเราไมสามารถหาคาของ square root ของ 0 ได เราจะใชตวเลขททาใหคาของ b2 – 4ac เปนบวกเทานนเพอหลกเลยงเหตการณดงกลาว อกอยางหนงกคอ เรายงไมไดเรยนเรองการใช ชดคาสงในการตรวจสอบ (if –else) เราจะกลบมาดตวอยางนอกครงหนงเมอเราไดเรยนเรองของการใช ชดคาสงในการตรวจสอบ ในทนเราสนใจแตเรองของการใช Math.sqrt() เทานนเอง เรามาลองใช Mathematical function อน ๆ ดกนดกวา /* MaxMin.java - Finding max and min */ class MaxMin { public static void main(String[] args) { int num1 = 58, num2 = 97, num3 = 15; //finding maximum between num1, num2, and num3 int maxOfTwo = Math.max(num1, num2); int maxOfAll = Math.max(maxOfTwo, num3); //finding minimum between num1, num2, and num3 int minOfTwo = Math.min(num1, num2); int minOfAll = Math.min(minOfTwo, num3); System.out.println("Maximum number is " + maxOfAll); System.out.println("Minimum number is " + minOfAll); } } โปรแกรม MaxMin.java แสดงการเรยกใช method max() และ min() ในการเปรยบเทยบและหาคาทมากทสด และคาทนอยทสดของ integer 3 ตว ตามลาดบ และเนองจากวา method ทงสองยอมรบ parameter เพยงแคสองตวเทานน เราจงตองทาการหาคาสองครง ครงแรกระหวาง integer 2 ตวแรก และครงทสองระหวางคาทหาได กบ integer ทเหลอ และเมอ execute โปรแกรมเรากจะไดผลลพธดงทเหนน Maximum number is 97

Page 46: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 41 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Minimum number is 15 โปรแกรมทแสดงใหดตอไปนเปนโปรแกรมทเรยกใช method ตาง ๆ ทมอยใน class Math /* Maths.java - Other math functions */ class Maths { public static void main(String[] args) { double angle = 0.7853982; //45 degrees angle in radians System.out.println("sin(45) is " + Math.sin(angle)); System.out.println("cos(45) is " + Math.cos(angle)); System.out.println("tan(45) is " + Math.tan(angle)); //absolute value of -456 System.out.println("Absolute value of -456 is " + Math.abs(-456)); //two to the fourth power System.out.println("2 to the 4th power is " + Math.pow(2D, 4D)); //round to the nearest integer System.out.println("2.345267 rounded to " + Math.round(2.345267)); //round to the nearest integer System.out.println("2.859 rounded to " + Math.round(2.859)); //the remainder of 3.25 / 2.25 System.out.println("The remainder of 3.25 / 2.25 is " + Math.IEEEremainder(3.25, 2.25)); //nearest integer of PI System.out.println("The nearest integer of PI is " + Math.rint(Math.PI)); } } โปรแกรม Maths.java ใช method จาก class Math ทาการหาคาของ sine cosine และ tangent ของมม 45 ซงมคาเทากบ 0.7853982 radians สาเหตทตองใชมมทเปน radians กเพราะวา method เหลานบงคบใหมมทรบเขาเปน parameter มชนดเปน radians หลงจากนนกทาการหาคา absolute ของ -456 คา 24 และคาการปดเศษในรปแบบตาง ๆ ผลลพธทไดจากการ run คอ sin(45) is 0.7071068070684596 cos(45) is 0.7071067553046345 tan(45) is 1.0000000732051062 Absolute value of -456 is 456 2 to the 4th power is 16.0 2.345267 rounded to 2 2.859 rounded to 3 The remainder of 3.25 / 2.25 is 1.0 The nearest integer of PI is 3.0 โปรแกรมตวอยางการใช method toRadians() สาหรบการเปลยนมมทเปน degrees ใหเปน radians ถาเราไมรวามมทเราเคยชนอยดวยการวดแบบ degrees มคาเปนเทาไรในการวดแบบ radians /* Maths1.java - Other math functions */ import java.text.DecimalFormat; class Maths1 {

Page 47: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 42 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public static void main(String[] args) { double angle = 45; //45 degrees angle double sin, cos, tan; //set format output DecimalFormat f = new DecimalFormat("0.00000"); //calculate sin, cos, and tan sin = Math.sin(Math.toRadians(angle)); cos = Math.cos(Math.toRadians(angle)); tan = Math.tan(Math.toRadians(angle)); System.out.println("sin(" + angle + ") = " + f.format(sin)); System.out.println("cos(" + angle + ") = " + f.format(cos)); System.out.println("tan(" + angle + ") = " + f.format(tan)); } } โปรแกรมตวอยางอกตวหนงทใช math function ในการคานวณหาคาของรศมของวงกลม จากพนทของวงกลมทกาหนดให /* Radius.java - Other math functions */ import java.text.DecimalFormat; class Radius { public static void main(String[] args) { double radius; double area = 850.0; int meters, centimeters; //calculate radius radius = Math.sqrt(area / Math.PI); //convert to meters and centimeters meters = (int)Math.floor(radius); centimeters = (int)Math.round(100.0 * (radius - meters)); System.out.print("Circle with area of " + area + " square meters "); System.out.print("has a radius of " + meters + " meters and "); System.out.println(centimeters + " centimeters"); } } เราใช floor() ในการหาคาของรศมทเปนจานวนเตม และใช round() ในการคานวณหาคาของ centimeters ทเหลอจากการนาเอา meters ไปลบออกจาก radius ซงเมอ run กจะไดผลลพธดงน Circle with area of 850.0 square meters has a radius of 16 meters and 45 centimeters ยงม method อกหลายตวทผเขยนโปรแกรมอาจตองใช ซงไดสรปไวในตารางท 2.6 ตาราง 2.6 Mathematical Functions สาหรบการหาคาทางตรโกณ Method Function Argument Result Type sin(arg) หาคา sine double (radians) double cos(arg) หาคา cosine double (radians) double tan(arg) หาคา tangent double (radians) double

Page 48: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 43 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

asin(arg) หาคา arc sine double double (radians ระหวาง –π /2 และ π /2)

acos(arg) หาคา arc cosine double double (radians ระหวาง 0.0 และ π )

atan(arg) หาคา arc tangent double double (radians ระหวาง –π /2 และ π /2 )

atan2(arg1, arg2) หาคา arc tangent of arg1 และ arg2

double double (radians ระหวาง –π และ π )

abs(arg) หาคา absolute ของ arg int long float double

เหมอนกนกบ Argument

max(arg1, arg2) หาคาสงสดระหวาง arg1 และ arg2

int long float double

เหมอนกนกบ Argument

min(arg1, arg2) หาคาตาสดระหวาง arg1 และ arg2

int long float double

เหมอนกนกบ Argument

ceil(arg) หาคาทเลกทสดทใหญกวาหรอเทากบ arg

double double

floor(arg) หาคาทใหญทสดทนอยกวาหรอเทากบ arg

double double

round(arg) หาคา integer ทใกลเคยงกบ arg ทสด

float double ได int ถา argument เปน float และ long ถาเปน double

rint(arg) หาคา integer ทใกลเคยงกบ arg ทสด

double double

IEEEremainder(arg1, arg2)

หาคาเศษทเหลอจากการหาร arg1 ดวย arg2

double double

sqrt(arg) หาคา root ทสองของ arg double double pow(arg1, arg2) หาคาของ arg1 ยกกาลง

arg2 double double

exp(arg) หาคา e ยกกาลง arg double double log(arg) หาคา log ของ arg double double random() หาคาสมทมากกวา 0.0 แต

นอยกวา 1.0 ไมม double

การใชขอมลทเปน Character เราไดดการประกาศตวแปรทเปน character มากอนหนานเพยงตวอยางเดยว เพอใหเกดความเขาใจถงการใชขอมลทเปน character ใน Java เรามาลองดตวอยางการใช character ในรปแบบตาง ๆ กนอกสกหนอย /* Characters.java - Using character data */ class Characters { public static void main(String[] args) { char H, e, l, o; H = 72; //ASCII for 'H' e = 101; //ASCII for 'e' l = 108; //ASCII for 'l' o = 111; //ASCII for 'o'

Page 49: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 44 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.print(H); System.out.print(e); System.out.print(l); System.out.print(l); System.out.print(o); System.out.println(" World"); } } ผลลพธจากการ run โปรแกรม Characters.java กคอ Hello World ซงตวโปรแกรมเองใชรหส ASCII ในการกาหนดคาใหกบตวแปร H e l และ o ซงเมอนาไปแสดงผลกจะไดคาทตวแปรเหลานนเปนอย เรามาลองดการประมวลผลดวยการใช character ดวย operator งาย ๆ ทมอย /* Characters1.java - Using character data */ class Characters1 { public static void main(String[] args) { char ch1 = 88, ch2 = 77; System.out.println("ch1 = " + ch1); System.out.println("ch2 = " + ch2); ch1 -= 23; //ASCII for 'A' ch2 += 6; //ASCII for 'S' System.out.println("ch1 = " + ch1); System.out.println("ch2 = " + ch2); } } โปรแกรมเรมตนดวยการกาหนดคาให ch1 และ ch2 มคาเปนตวอกษร X และ M ตามลาดบ และเมอแสดงผลของทงสองตวแปรแลว โปรแกรมกเปลยนคาใหกบตวแปร ch1 และ ch2 ดวยการลดคาของ ch1 ลงเปนจานวนเทากบ 23 และเพมคาใหกบตวแปร ch2 อก 6 เพอใหไดตวอกษร A และ X และเมอ execute โปรแกรมเรากจะไดผลลพธทงหมดเปน ch1 = X ch2 = M ch1 = A ch2 = S ทนเรามาลองดการใช Unicode ในการแสดงผลตวอกษรตาง ๆ /* Characters2.java - Using character data */ class Characters2 { public static void main(String[] args) { char ch1 = '\u0058'; //unicode for 'X' char ch2 = '\u004D'; //unicode for 'M' char ch3 = '\u0041'; //unicode for 'A' char ch4 = '\u0053'; //unicode for 'S' System.out.println("ch1 = " + ch1); System.out.println("ch2 = " + ch2); System.out.println("ch3 = " + ch3); System.out.println("ch4 = " + ch4); }

Page 50: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 45 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} ซงเมอ run แลวกจะไดผลลพธเหมอนกนกบผลลพธของโปรแกรม Characters1.java เราสามารถทจะใช Unicode ในการแสดงตวอกษรในภาษาไทยได เชนเดยวกนกบทเราใช Unicode ในการแสดงตวอกษรในภาษาองกฤษ แตวาระบบของเราจะตองเออตอการแสดงผลทเปนตวอกษรไทยดวย ไมเชนนนแลวผลลพธทไดกจะเปนตวอกษรทอานไมรเรอง หรอไมกแสดงผลเปนเครองหมาย '?' ทกตว แตถาเราใช Unicode เพอการแสดงผลใน applet เรากจะไมเจอปญหาใด ๆ เลยเพราะ Unicode ไดถกออกแบบมาเพอแสดงผลบน applet อยแลว ตารางท 2.7 แสดงถงตวอกษรทใชในการแสดงผลลพธทไมใชตวอกษรธรรมดา หรอทภาษาองกฤษเรยกวา Character Escape Sequences ซงเราสามารถนามาใชในการจดวางรปแบบของผลลพธทเราตองการใหดแลวสวยงามขน (อยางหยาบ ๆ และ งาย ๆ) ตาราง 2.7 Character Escape Sequence Escape Sequence ความหมาย \ddd แสดงผลลพธเปนเลขฐานแปด (Octal) \uxxxx แสดงตวอกษร Unicode (Hexadecimal) \' ตว ' (Single quote) \" ตว " (Double quote) \\ ตว \ เอง \r กลบไปยงจดเรมตนของบรรทด (Carriage return) \n ขนบรรทดใหม (New line หรอ Linefeed) \f เลอนไปหนาถดไป (Form feed) \t เลอนไปยงตาแหนงถดไป (Tab) \b เลอนไปทางซายหนงตวอกษร

การใชตวแปรชนด boolean เราไดเหนการประกาศตวแปรทเปน boolean มาเพยงนอยนดกอนหนาน ตอไปเราจะมาทาความเขาใจกบขอมลทเปน boolean และการประมวลตวแปรหรอประโยคทมคาของการประมวลผลเปน boolean อกสกเลกนอยกอนทเราจะใชมนในโอกาสตอไป ผเขยนหลายทานเรยก operator เหลานวา Logical Operator โดยทวไปเราสามารถประมวลผลขอมลทเปน boolean ดวย operator ตาง ๆ ทเหนน && หรอทเรยกวา Conditional AND || หรอทเรยกวา Conditional OR & หรอทเรยกวา Logical AND | หรอทเรยกวา Logical OR ! หรอทเรยกวา Logical NOT && และ || มการประมวลผลในรปแบบทหนงสอหลาย ๆ เลมใหชอวา Lazy หรอ Short Circuit ซงมรปแบบการประมวลผลทแตกตางจาก & และ | operator && ตางจาก & โดยท && นนจะไมประมวลผล ประโยคหรอตวแปรทตามหลงตวมนเอง ถาประโยคหรอตวแปรทอยกอนหนามคาเปน false เพราะวาคาทเปน false เมอนามาประมวลผลกบคาอน ๆ แลวจะได false เสมอ operator || กเชนเดยวกนกบ && แตจะประมวลผลประโยคหรอตวแปรทตามมาเมอประโยคแรกหรอตวแปรตวแรกมคาเปน true เพราะวาประโยคหรอตวแปรทมคาเปน true เมอนามาประมวลกบคาใด ๆ กตามจะไดคา true เสมอ สวน operator & และ | จะประมวลผลประโยคและตวแปรทงสองเสมอ

Page 51: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 46 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

และ operator ! นนเมอไปอยหนาตวแปรหรอประโยคทมคาทาง boolean คาใดคาหนงกจะเปลยนคานนใหเปนตรงกนขามทนท Operator ตวอน ๆ ทใชกบตวแปรหรอประโยคทมคาเปน boolean มดงน < ใชในการเปรยบเทยบวา คาทางดานซายของเครองหมาย นอยกวา คาทางดานขวาหรอไม > ใชในการเปรยบเทยบวา คาทางดานซายของเครองหมาย มากกวา คาทางดานขวาหรอไม <= ใชในการเปรยบเทยบวา คาทางดานซายของเครองหมาย นอยกวาหรอเทากบ คาทางดานขวา หรอไม >= ใชในการเปรยบเทยบวา คาทางดานซายของเครองหมาย มากกวาหรอเทากบ คาทางดานขวา หรอไม == ใชในการเปรยบเทยบวา คาทางดานซายของเครองหมาย เทากบ คาทางดานขวาหรอไม != ใชในการเปรยบเทยบวา คาทางดานซายของเครองหมาย ไมเทากบ คาทางดานขวาหรอไม เราเรยก operator เหลานวา Relational operator ซงเอาไวใชในการตรวจสอบความสมพนธของตวแปรหรอประโยความคาแตกตางกนอยางไรเมอนามาเปรยบเทยบกน เราจะลองเขยนโปรแกรมตรวจสอบ operator ตาง ๆ เหลานด /* BooleanOp.java - Testing boolean operations */ class BooleanOp { public static void main(String[] args) { boolean A = true, B = false; System.out.println("Conditional AND"); System.out.println("F && F is " + (B && B)); System.out.println("F && T is " + (B && A)); System.out.println("T && F is " + (A && B)); System.out.println("T && T is " + (A && A)); System.out.println("Conditional OR"); System.out.println("F || F is " + (B || B)); System.out.println("F || T is " + (B || A)); System.out.println("T || F is " + (A || B)); System.out.println("T || T is " + (A || A)); System.out.println("Logical AND"); System.out.println("F & F is " + (B & B)); System.out.println("F & T is " + (B & A)); System.out.println("T & F is " + (A & B)); System.out.println("T & T is " + (A & A)); System.out.println("Logical OR"); System.out.println("F | F is " + (B | B)); System.out.println("F | T is " + (B | A)); System.out.println("T | F is " + (A | B)); System.out.println("T | T is " + (A | A)); System.out.println("Logical NOT"); System.out.println("!F is " + (!B)); System.out.println("!T is " + (!A)); } } โปรแกรมประกาศตวแปรสองตว A และ B ดวยคา true และ false ตามลาดบ และทาการแสดงผลลพธของการประมวลผลดวย operator ผานทาง System.out.println() ผลลพธทแสดงออกทางหนาจอ คอ

Page 52: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 47 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Conditional AND F && F is false F && T is false T && F is false T && T is true Conditional OR F || F is false F || T is true T || F is true T || T is true Logical AND F & F is false F & T is false T & F is false T & T is true Logical OR F | F is false F | T is true T | F is true T | T is true Logical NOT !F is true !T is false ทนลองมาดโปรแกรมการใช Relational operator /* BooleanOp2.java - Using relational operators */ class BooleanOp2 { public static void main(String[] args) { int i = 5, j = 10; System.out.println("i = " + i); System.out.println("j = " + j); System.out.println("i > j is " + (i > j)); System.out.println("i < j is " + (i < j)); System.out.println("i >= j is " + (i >= j)); System.out.println("i <= j is " + (i <= j)); System.out.println("i == j is " + (i == j)); System.out.println("i != j is " + (i != j)); System.out.println("(i < 10) && (j < 10) is " + ((i < 10) && (j < 10))); System.out.println("(i < 10) || (j < 10) is " + ((i < 10) || (j < 10))); } } โปรแกรม BooleanOp2.java ทาการหาคาของประโยคตาง ๆ ในรปแบบงาย ๆ เพอใหผอานไดเหนถงผลลพธของการใช operator ตาง ๆ ไดอยางชดเจน เราประกาศตวแปรทเปน int สองตว คอ i และ j ซงกาหนดใหมคาเปน 5 และ 10 ตามลาดบ หลงจากนนโปรแกรมกใช operator ตาง ๆ กบตวแปรสองตวน และเมอ run โปรแกรมนแลวผลลพธทได คอ

Page 53: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 48 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

i = 5 j = 10 i > j is false i < j is true i >= j is false i <= j is true i == j is false i != j is true (i < 10) && (j < 10) is false (i < 10) || (j < 10) is true เพอใหเหนภาพของการประมวลของ operator && และ operator || ไดชดเจนยงขน ผอานควรตรวจสอบจากแผนภาพของการประมวลผลน โดยเราไดกาหนดใหตวแปร p และ q มคาเปน 5 และ 10 ตามลาดบในการประมวลผลทางดานซาย และใหมคาเปน 10 และ 5 ในการประมวลผลทางดานขวา

ภาพท 2.4 การประมวลผลดวย &&

ภาพท 2.5 การประมวลผลดวย || ตาราง 2.8 ไดสรปคาของการประมวลผลดวย operator && || & | ดงทไดกลาวมาแลว

p = 10, q = 5

(q <= 10)

T

F T

p = 5, q = 10

(p < q) || (q <= 10) (p < q) ||

T ไมตองประมวลผลตอเพราะ T || กบอะไรกได T

p = 10, q = 5

(q <= 10)

T

p = 5, q = 10

(p < q) && (q <= 10) (p < q) &&

T T Fไมตองประมวลตอเพราะ F

&& กบอะไรกได F

Page 54: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 49 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ตาราง 2.8 การใช operator && || & และ |

P Q P && Q P || Q P & Q P | Q true true true true true true false true false true false true true false false true false true false false false false false false

เราคงมองไมเหนถงประโยชนของการใชตวแปรทเปน boolean และการใช operator ตาง ๆ ทไดพดถงในตอนนอยางมากมายนก การประมวลผลของตวแปรทเปน boolean สวนใหญจะเอาไวชวยการตรวจสอบถงเหตการณ (condition) ตาง ๆ ทอาจเกดขนในโปรแกรม เชน ถาประโยคทหนง เมอนามาประมวลผลกบ ประโยคทสองแลว ผลลพธทไดเปน true หรอ false ซงถาเปน true เราจะทาการอยางอน และกจะทาการอนหากเปน false เปนตน เราจะพดถง boolean operator ตาง ๆ เมอเราพดถงเรองของ logic และเรองของการประมวลผลในรปแบบของการวนซา (logic and loop) การประมวลผลในระดบ bit ดวยการใช operator Shift และ Bitwise ในการทางานในระดบ bit นนม operator ไมกตวทเราสามารถเรยกใชได ซงการใชงานโดยทวไปกไมงายนก เพราะตองทาในระดบ bit และผใชตองมความเขาใจในเรองของเลขฐานสองอยางดพอสมควร เราจะยกตวอยางเพยงไมกตวอยางเพอใหเหนถงการใชงานของ operator shift ตาง ๆ ท Java มให คอ << >> และ >>> ตาราง 2.9 การใช operator shift << >> และ >>> Operator วธใช ความหมาย

<< operand1 << operand2 โยก bit ของ operand1 ไปทางซายจานวนเทากบคาของ operand2 เตม 0 ทก ๆ bit ทางขวา

>> operand1 >> operand2 โยก bit ของ operand1 ไปทางขวาจานวนเทากบคาของ operand2 เตมดวยคา bit (sign bit)สงสดทางซาย

>>> operand1 >>> operand2 โยก bit ของ operand1 ไปทางขวาจานวนเทากบคาของ operand2 เตม 0 ทก ๆ bit ทางซาย

ตวอยาง 13 >> 1 13 = 000011012 เมอ shift ไปทางขวา 1 bit ผลลพธทไดคอ 000001102 (เทากบ 6 ในเลขฐาน 10) 13 << 1 shift ไปทางซาย 1 bit ผลลพธทไดคอ 000110102 (เทากบ 26 ในเลขฐาน 10) 13 >>> 1 shift ไปทางขวา 1 bit ผลลพธทไดคอ 000001102 (เทากบ 6 ในเลขฐาน 10) การโยก bit ไปทางซายครงละหนง bit นนทจรงแลวกคอการคณดวยสอง เรามาดตวอยางโปรแกรมการโยก bit ไปทางซายกน จากโปรแกรม ShiftLeftOp.java ทเหนดานลางน /* ShiftLeftOp.java - Using shift operators */ class ShiftLeftOp { public static void main(String[] args) { byte bits = 1; System.out.println("Value of bits is " + bits); bits = (byte) (bits << 1); System.out.println("Value of bits is " + bits); bits = (byte) (bits << 1);

Page 55: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 50 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.println("Value of bits is " + bits); bits = (byte) (bits << 1); System.out.println("Value of bits is " + bits); bits = (byte) (bits << 1); System.out.println("Value of bits is " + bits); bits = (byte) (bits << 1); System.out.println("Value of bits is " + bits); } } เราเรมดวยการกาหนดใหตวแปร bits มชนดเปน byte และมคาเทากบหนง โปรแกรมทาการโยก bit ไปทางซายจานวนเทากบหาครง ซงในการโยกแตละครงเรากจะไดคาใหมทมคาเทากบคาเดมคณดวยสอง ดงทเหนจากผลลพธของการ run โปรแกรมน Value of bits is 1 Value of bits is 2 Value of bits is 4 Value of bits is 8 Value of bits is 16 Value of bits is 32 เราเลอกใชขอมลชนดทเปน byte กเพอใหเหนวาถาเราโยก bit อกครงดวยจานวน bit ทตองการโยกเทากบสอง bit (ครงทหก) เราจะไดคาทตวแปร bits ไมสามารถเกบได ลองด code ทเพม และ ผลลพธของการ run bits = (byte) (bits << 2); System.out.println("Value of bits is " + bits); ผลลพธเมอ run อกครงดวย code ทเพมขนจะเหนวาคาของ bits ทไดมคาเปน -128 ซงเปนคาท Java เปนผกาหนดให แตไมใชคาทถกตอง เพราะขอมลทเปน byte นนเกบคาสงสดทเปนบวกไดเพยงแค 127 เทานน Value of bits is 1 Value of bits is 2 Value of bits is 4 Value of bits is 8 Value of bits is 16 Value of bits is 32 Value of bits is -128 สงสาคญอกสงหนงกคอ การ cast เราจาเปนตองเปลยนขอมลใหถกตองตามชนดของตวแปร เนองจากวา Java ไดทาการเปลยนตวแปร bits ของเราใหเปน int กอนทจะทาการ shift ดงนนเราตองเปลยนขอมลใหกลบมาเปนชนดเดมกอนการจดเกบ (หลงจากการ shift สนสดลง) เราไดพดถงการประกาศตวแปร การกาหนดคาใหกบตวแปรทอยภายในตวโปรแกรม ดวยขอมลทงทมชนดเปน integer และ floating-point ซงการกาหนดคาใหกบตวแปรภายในโปรแกรมนน ไมมความยดหยนของขอมลทถกเกบอยในตวแปรนน หากผใช หรอ ผเขยนโปรแกรมตองการทจะเปลยนคาทตวแปรนนเกบอย ผเขยนจะตองเปนผแกไขแตเพยงฝายเดยว ผใชโปรแกรมไมสามารถทจะเปลยนคาเหลานนได ดงนนการเขยนโปรแกรม จะตองใหโอกาสผใชโปรแกรมในการเปลยนแปลงคาเหลานน Java ม method อยหลายตวทรองรบการใสขอมลผานทาง keyboard เราจะมาทาความรจก และเขาใจถงวธการ ซงคอนขางจะซบซอนพอสมควรสาหรบผเรมหดเขยนโปรแกรมใหม อยางไรกตามหลงจากทไดทาความเขาใจแลว กจะเหนวาการรบคาตาง ๆ ผานทาง keyboard นนเปนเรองท (จรง ๆ แลว) ไมยงยากเลย

Page 56: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 51 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การกาหนดคาใหกบตวแปรผานทางสอการนาเขาขอมลมาตรฐาน Java ไมม method ใด ๆ ทรบคาขอมลตามชนดนน ๆ ของขอมลทเขามาเลย เชน ถาผใชโปรแกรมตองการทจะใสคาทเปน int float double หรอ char ผเขยนโปรแกรมกไมสามารถทจะรบคาตาง ๆ เหลานไดโดยตรง เหมอนกบการเขยนโปรแกรมดวยภาษาอน ๆ เชน C หรอ C++ แตตวผเขยนเองจะตองเขยน code ขนมารองรบคาเหลานผานทางการอานเขาแบบทเรยกวา การรบขอมลทเปน String ซงเมออาน String ไดแลวกตองแปลง String ใหเปนชนดของขอมลทผเขยนโปรแกรมตองการใหเปน ผอานอาจสงสยวา String คออะไร ในทนจะอธบายอยางคราว ๆ เนองจากวาเราจะพดถง String ในบทอนตอไป ใน Java นน String เปน object (อกแลว object? เชนเดยวกนเราจะพดถง object อยางละเอยดในบทอน) ซงสามารถเกบตวอกษรไดคราวละมาก ๆ ขอยกตวอยางงาย ๆ ใหดกแลวกน People of Thailand สวสด price_of_coffee 1234567890 23+popOfRock ตวอยางทเหนดานบนนลวนแลวแตเปน String ทงนน ทนเรามาลองดวธการอาน String เขามาจาก keyboard แลวกเปลยน String ใหเปนขอมลชนดตาง ๆ ทเราตองการ เรมดวยการเปลยนแปลง code ของโปรแกรม Radius.java ใหรบคาของ area จาก keyboard แทนการกาหนดภายในโปรแกรม /* Radius2.java - Reading data from keyboard */ import java.io.*; class Radius2 { public static void main(String[] args) throws IOException { double radius, area; int meters, centimeters; //prompt user for area of a circle System.out.print("Please enter area of a circle: "); //get string from keyboard InputStreamReader in = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(in); String inputString = buffer.readLine(); //convert string to double area = Double.parseDouble(inputString); //calculate radius radius = Math.sqrt(area / Math.PI); //convert to meters and centimeters meters = (int)Math.floor(radius); centimeters = (int)Math.round(100.0 * (radius - meters)); System.out.print("Circle with area of " + area + " square meters "); System.out.print("has a radius of " + meters + " meters and "); System.out.println(centimeters + " centimeters"); } } โปรแกรม Raadius2.java เพม code ใหอาน String จาก keyboard ดวยประโยค System.out.print("Please enter area of a circle: ");

Page 57: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 52 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

InputStreamReader in = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(in); String inputString = buffer.readLine(); ประโยคแรกสดเปนการสงขอความไปยง user ใหรวาตองใสขอมลอะไรเขาสโปรแกรม ประโยคถดมาอานขอมลในรปแบบของ byte จากระบบ (System.in) เปลยนขอมลเหลานนใหเปน character แลวจงนามาเกบไวในตวแปร in ประโยคทสามทาการจองเนอทใหกบตวแปร buffer พรอมกบนาคา character ทอยในตวแปร in มาเกบไวในรปแบบของ String เมอได String (ซงตอนนอยในตวแปร buffer) เรากทาการอาน String ทวานดวย method readLine() ผานทางตวแปร buffer แลวจงนาไปเกบไวในตวแปรชนด String ทมชอวา inputString ฟงดแลวรสกวามขนตอนมากมายในการอาน String แตตอนนขอเพยงแตจาวาถาจะอาน String จาก keyboard ตองทาดวยวธน (ณ เวลาน เพราะมอกหลายวธ) เมอเราได String แลวขนตอนตอไปกคอการเปลยน String ใหเปนขอมลชนดทเราตองการใชในโปรแกรม ซงโปรแกรม Radius.java ของเราตองการใชขอมลชนดทเปน double เราจงตองทาการเปลยน String นใหเปน double ดวยการเรยกใช method parseDouble() จาก class Double พรอมทงสงตวแปรทเกบขอมลจาก keyboard ไปใหแก method นดวย area = Double.parseDouble(inputString); หลงจากนน code ของโปรแกรมทเหลอกเหมอนกบทเราไดเขยนกอนหนาน และเมอ run โปรแกรมด สองครง ดวยคา 850 ในครงแรกและคา 54 ในครงทสอง เรากไดผลลพธ ดงทแสดงใหเหนน Please enter area of a circle: 850 Circle with area of 850.0 square meters has a radius of 16 meters and 45 centimeters Please enter area of a circle: 54 Circle with area of 54.0 square meters has a radius of 4 meters and 15 centimeters ถาสงเกตใหดจะเหนวาโปรแกรม Radius2.java นนมขอความเพมตอทายของ main(..) คอ throws IOException เหตผลทเราตองเพม throws IOException ใหกบ main(…) กเพราะวา การอานขอมลเขาสโปรแกรมนน บางครงกอาจเจอกบปญหาในการอาน เชน อานไมได และเหตผลอกอนหนง คอ Java บงคบใหเราตองตรวจสอบการทางานกบ I/O เอง ซงถาหากมปญหาเกดขน เราจะไดแกไขไดถกตอง มวธการตรวจสอบและปองกนไมใหการอานมปญหาหลากหลาย ซงเราจะไดดกนในโอกาสตอไป (บทท 7) ลองมาดวาถาเราไมใสขอความทวาลงไปในโปรแกรม Radius2.java เราจะได error อะไร Radius2.java:16: unreported exception java.io.IOException; must be caught or declared to be thrown String inputString = buffer.readLine(); ^ 1 error จะเหนวา Java จะบอกใหเรารวาเราไมสามารถทจะอานขอมลเขาสโปรแกรมได ถาเราไมทาการตรวจสอบดวยวธทไดกลาวไว ประโยคทวา must be caught or declared to be thrown กลาวถงวธ สองวธ ทเราสามารถใชไดในการอานขอมลเขาสโปรแกรม คอ (1) ตรวจจบ – catch และ (2) เรยกใช throws ของ Java

Page 58: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 53 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ตอไปจะไดแสดงการใชวธทหนง ซงเปนการตรวจจบ error ในการอานขอมล แตจะพดเพยงเพอใหการอานขอมลทาไดสมบรณเทานน คงจะไมกลาวถงอยางละเอยดมากมายนก เรามาเรมตนดวยการเขยน code เพมขนใหม ดงทแสดงใหเหนน /* Radius2.java - Reading data from keyboard */ import java.io.*; class Radius2 { public static void main(String[] args) throws IOException { double radius, area; int meters, centimeters; String inputString = null; try { //prompt user for area of a circle System.out.print("Please enter area of a circle: "); //get string from keyboard InputStreamReader in = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(in); inputString = buffer.readLine(); } catch(IOException ioe) {} //convert string to double area = Double.parseDouble(inputString); //calculate radius radius = Math.sqrt(area / Math.PI); //convert to meters and centimeters meters = (int)Math.floor(radius); centimeters = (int)Math.round(100.0 * (radius - meters)); System.out.print("Circle with area of " + area + " square meters "); System.out.print("has a radius of " + meters + " meters and "); System.out.println(centimeters + " centimeters"); } } สงทเราไดปรบปรงคอประโยค ตอไปน String inputString = null; //prompt user for area of a circle System.out.print("Please enter area of a circle: "); try { //get string from keyboard InputStreamReader in = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(in); inputString = buffer.readLine(); } catch(IOException ioe) {} เรายายการประกาศตวแปร inputString ไปอยกอนประโยคทอานขอมลเขาพรอมกบเพมประโยค try { …

Page 59: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 54 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

… … } catch(IOException ioe) {} เขาสโปรแกรมดวยการนาเอาประโยคการอานขอมลเขาส string ทงสามประโยคไวใน block ของ try {} สวนคาวา catch(IOException ioe) {} นนเรากเพมเขาหลงจาก block ของ try {} เราไมจาเปนตองใส code อะไรเขาไปใน code ของ catch(IOExcpetion ioe) {} เพราะเราเพยงแตตองการใหการอานเปนไปไดดวยดเทานน เรายงจะไมกงวลถง error ทเกดขน ซงถาม error เกดขน Java กจะเปนผฟองใหเราทนท เพอใหเกดความเขาใจอกสกหนอย เราจะมาตรวจสอบการใสขอมลของผใชดวา ไดมการใสขอมลเขาสโปรแกรม หรอเพยงแตกดปม Enter เฉย ๆ เราทาการตรวจสอบดวยการเพม try {..} และ catch() {} ใหกบโปรแกรม Radius2.java ดงน /* Radius2.java - Reading data from keyboard */ import java.io.*; class Radius2 { public static void main(String[] args) { double radius, area; int meters, centimeters; String inputString = null; //prompt user for area of a circle System.out.print("Please enter area of a circle: "); try { //get string from keyboard InputStreamReader in = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(in); inputString = buffer.readLine(); try { //convert string to double area = Double.parseDouble(inputString); //calculate radius radius = Math.sqrt(area / Math.PI); //convert to meters and centimeters meters = (int)Math.floor(radius); centimeters = (int)Math.round(100.0 * (radius - meters)); System.out.print("Circle with area of " + area + " square meters "); System.out.print("has a radius of " + meters + " meters and "); System.out.println(centimeters + " centimeters"); } //catch empty string (user hits Enter) catch(Exception e) { System.out.println("Error! you must supply input"); e.printStackTrace(); System.exit(1); } } //catch other I/O error - do nothing catch(IOException ioe) { /* leave it to Java! */ } }

Page 60: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 55 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} โปรแกรม Radius2.java ทเราเขยนขนใหมม try {…} และ cath() {} อยสองตว ตวแรกใชตรวจสอบเรองของการอานทวไปทไดกลาวไปแลว สวนตวทสองเปนการตรวจสอบวาผใชมการใสขอมลหรอไม ซงถาไมใส เรากจะ 1. สงขอความไปยงหนาจอดวยคาสง System.out.println("Error! you must supply input"); 2. สงขอความ error ท Java ไดฟองไว ดวยคาสง e.printStackTrace(); 3. ออกจากโปรแกรมโดยไมมการประมวลผลใด ๆ ทงสน ดวยคาสง System.exit(1); และเมอ execute ดเรากจะไดขอความดงน Please enter area of a circle: < ผใชกดปม Enter > Error! you must supply input java.lang.NumberFormatException: empty String at java.lang.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:986) at java.lang.Double.parseDouble(Double.java:202) at Radius2.main(Radius2.java:22) โดยทวไปการออกจากโปรแกรมทไมมปญหาใด ๆ ในการเขยนดวยภาษา Java นนเราจะใชการออกดวยเลข 1 ในประโยค System.exit(1) หรอเลขอน ๆ ทไมใช 0 สวนการออกแบบปกตนนเราใชเลข 0 แทนเลข 1 เราคงจะพกการตรวจสอบ หรอ ตรวจจบ error ไวเพยงแคนกอนเราจะกลบมาพดถงการเขยน code รองรบ error ในบทอนตอไป สรป เราไดเรยนรถงขอมลชนดตาง ๆ ทเปนขอมลแบบพนฐาน หรอทเรยกวา primitive datatype ท Java มให รวมไปถงการประกาศตวแปร การกาหนดคาใหกบตวแปร การประมวลตวแปรชนดเดยวกน และ ตางชนดกน การเปลยนชนดของขอมล (casting) การใช method ทเกยวของกบตวเลข การแสดงผลตวเลขทมจดทศนยม การอานขอมลเขาสโปรแกรม และการตรวจสอบ และตรวจจบ error ทอาจเกดขนในการอานขอมล แบบฝกหด 1. จงอธบายถงความหมายของคาวา final พรอมทงยกตวอยางประกอบ 2. จงอธบายถงความแตกตางระหวาง 5, 5.0, '5', "5", และ "5.0" 3. จงหาผลลพธของการประมวลผลประโยคตอไปน ถากาหนดให

double x = 4.5; double y = -45.25; int p = 12; int q = 2; 3.1. x + p * y / (p – y) * x 3.2. p % (p – q) 3.3. (int) y 3.4. (int) p 3.5. Math.round(x) 3.6. (int) Math.round(y)

Page 61: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 56 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

3.7. -2 * y + (int) x 3.8. q / p 3.9. p % q 3.10. y * y – y + (x * (int) x)

4. จงเขยนโปรแกรมทรบตวเลขชนด int จาก keyboard จานวน 2 ตว และขอมลชนด double อก 2 ตว

หลงจากนนใหโปรแกรมคานวณหาผลรวมของเลขทง 4 ตว ใหเกบผลลพธทหาไดไวในตวแปรตวใหม สงผลลพธทไดไปยงหนาจอ

5. จงเขยนประโยคดวยภาษา Java จากสมการทใหน

5.1. a + bc / 2 5.2. a(a – c) + b(b – c) – (c(c – a) / d) 5.3. b2 – 4ac 5.4. (4/3)2 / 2

5.5. 21 TkD

xMTq +

−=

6. จงเขยนโปรแกรมททาการเปลยน องศา Celsius ใหเปนองศา Fahrenheit โดยกาหนดใหขอมลท

ตองการเปลยน นาเขาจาก keyboard โดยกาหนดใหสตรการเปลยน คอ

Celsius = 95

(Fahrenheit – 32)

7. จงเขยนโปรแกรมททาการเปลยน องศา Fahrenheit ใหเปนองศา Celsius โดยกาหนดใหขอมลท

ตองการเปลยน นาเขาจาก keyboard 8. จงเขยนโปรแกรมทรบขอมลทเปนจานวนกโลกรมจาก keyboard เปลยนใหเปน mile สงผลลพธไป

ยงหนาจอ 9. จงเขยนโปรแกรมทอานขอมลจาก keyboard ทเปนอายของผใชในรปแบบของป ใหโปรแกรม

เปลยนเปนจานวนวน สงผลลพธออกทางหนาจอ (กาหนดให 1 ปเทากบ 365 วน) 10. จงเขยนโปรแกรมทรบ int จานวน 5 ตว หาคาเฉลยของตวเลขเหลาน เสรจแลวสงผลลพธไปยง

หนาจอ 11. จงเขยนโปรแกรมทคานวณหาเวลาทแสงเดนทางจากโลกไปยงดวงอาทตย ใหสงผลลพธของการ

คานวณในรปแบบของนาท สงผลลพธทหาไดไปยงหนาจอ 12. สมมตวาอาจารยทกคนในวทยาลยแหงหนงดม beer 1 ขวดตอวน และในการทา beer 1 ลง (24

ขวด) นนตองใชขาว barley จานวน 1 ถง ถาจานวนของอาจารยในวทยาลยทวานมทงสน 200 คน จงเขยนโปรแกรมในการคานวณหาจานวนของขาว barley ทตองใชในการทา beer ใหเพยงพอตอการบรโภคของอาจารยในวทยาลยนตลอดภาคการศกษา

13. จงเขยนโปรแกรมทรบขอมลชนด long ทมจานวนของตวเลข (digit) อยระหวาง 10 – 12 ตว ใหสง

ผลลพธในรปแบบของ ตวเลขทใชเครองหมาย , เปนตวแบงกลม โดยเรมตนจากทางขวามอ และใหมตวเลขกลมละ 3 ตวไปยงหนาจอ

14. จงเขยนโปรแกรมทรบคาความยาวของดานทกดานของสามเหลยม จากนนใหคานวณหาคาของเสน

รอบรป (perimeter) สงผลลพธไปยงหนาจอ 15. จงเขยนโปรแกรมทคานวณหาพนทของวงกลม จากรศมทรบเขามาจาก keyboard

Page 62: Beginning JAVA [Thai]

บทท 2 ขอมล ตวแปร และ การประมวลผล 57 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

16. จงเขยนโปรแกรมทรบขอมลชนด double จานวน 5 ตวจาก keyboard จากนนใหคานวณหา คาเฉลยของตวเลขเหลานน สงผลลพธทหาไดไปยงหนาจอ

17. กาหนดใหเสนผาศนยกลางของดวงอาทตยเทากบ 865,000 ไมล และเสนผาศนยกลางของโลก

เทากบ 7,600 ไมล จงเขยนโปรแกรมทคานวณหา

17.1. ปรมาตรของโลก (cubic mile หรอ mile3) 17.2. ปรมาตาของดวงอาทตย (cubic mile) 17.3. อตราสวนของปรมาตรของดวงอาทตยตอปรมาตรของโลก

18. จงเขยนโปรแกรมทรบขอมลชนด double ทอยในรปแบบ 123.4567 จาก keyboard จากนนใหดง

เอาสวนของขอมลทอยหนาจดทศนยมไปเกบไวในตวแปรทมชนดเปน long ตวหนง เสรจแลวใหเกบขอมลทอยหลงจดทศนยมไปเกบไวในตวทเปน long อกตวหนง สงผลลพธทอยในตวแปร long ทงสองไปยงหนาจอ

Page 63: Beginning JAVA [Thai]

ในบททสามนเราจะมาทาความรจกกบการทางานในรปแบบของการประมวลผลชดคาสงซา ๆ กนตามเงอนไขทกาหนดให หรอทเรยกวาการประมวลผลแบบวน (repetition หรอ loop) การใชชดคาสงในการตดสนใจ และ การใชประโยคในการเปรยบเทยบขอมลตาง ๆ หลงจากจบบทเรยนนแลวผอานจะไดทราบถง

o การเปรยบเทยบขอมล (comparison) o การกาหนดประโยคในการเปรยบเทยบ (logical expression) o การเปลยนแปลงขนตอนการประมวลผลในแบบตาง ๆ (control statement) o การทางานแบบวน (loop)

for loop while loop do … while loop

o การยตการทางานของ loop ดวยการใชคาสง break และ continue หลาย ๆ ครงการเขยนโปรแกรมตองมการเลอกทจะประมวลผล ไมวาจะเปนการเลอกตามขอมลทนาเขา หรอ การเลอกประมวลผลตามขนตอน กระบวนการทไดกาหนดไว เชน ถาขอมลนาเขามคานอยกวาศนย เราจะยตการทางานของโปรแกรม ถามากกวาเราจะมวลผลตอไป อะไรทานองน ในการตดสนใจทจะให code ทาอยางใด อยางหนงนน เราจะตองรจกวธการสรางประโยคทใชในการเปรยบเทยบ ขนตอนของการใชประโยคเปรยบเทยบในรปแบบตาง ๆ การตดสนใจ และ การเปรยบเทยบ การตดสนใจเปนสวนประกอบทสาคญมาก ๆ สวนหนงของการเขยนโปรแกรม โปรแกรมของเราตองมความสามารถในการตดสนใจเลอกวาจะทาอะไรตอไป เชน ถาจานวนของนกศกษาทมาสมครเรยนในภาควชาคอมพวเตอรธรกจมมากกวา หารอย เราจะมการสอบคดเลอก หรอ เชน ถาเงนเดอนเพมขนฉนจะซอบาน อะไรทานองน ซงในดานของการเขยน code นน การตดสนใจจะทาไดโปรแกรมกตองมความสามารถทจะเปรยบเทยบไดกอน เชน เปรยบเทยบถงความมากกวา นอยกวา หรอ เปรยบเทยบถงความเทากน และความไมเทากน ในบททสองเราไดพดถง relational operator เพยงเลกนอยในเรองของการทางานกบตวแปรทมชนดเปน boolean และ operator ทวานกคอ < <= > >= == และ != เราจะมาดถงการใช operator เหลานในประโยคทมการเลอกประมวลผลตามผลลพธของการเปรยบเทยบนน ๆ ประโยคทใช if if เปนคาสงทเรานามาใชในการเลอกวาเราจะประมวลผลอะไรตามผลลพธทเกดขน if มรปแบบดงน คอ if(expression) statement; โดยมขอกาหนดวา expression จะตองเปนประโยคทเมอมการประมวลผลแลวจะไดคาทเปน boolean ซงเปนไปไดเพยงแค true หรอ false เทานน เชน

Page 64: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 59 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

if(numberOfStudents >= 500) entranceExam = true; หรอ if(number < 0) number *= 10; number++; ถาคาของ expression เปนจรง ประโยคทตามหลง if จะถกประมวลผล แตถาเปนเทจกจะไมถกประมวลผล เชนตวอยางทเหนดานบนน ถาคาของ number < 0 เปนจรงประโยค number *= 10 กจะไดรบการประมวลผล ภาพท 3.1 แสดงถงขนตอนของการประมวลผลดวยการใช if กบประโยคในรปแบบทวไป และประโยคการเปรยบเทยบ number ทไดกลาวถงกอนหนาน if(expression) statement; other_statement;

ภาพท 3.1 การใชประโยค if ในบางครงเรากอาจเขยนประโยค if ใหเปนรปแบบทอยในบรรทดเดยวกน เชน ถาเราเปลยนประโยคตวอยางกอนหนานใหอยในบรรทดเดยวกนเรากจะได if(number < 0) number *= 10; number++; ซงถกตองตามหลกไวยากรณของ Java แตโดยทวไปแลวการขนบรรทดใหมสาหรบประโยคทตามมาหลงจากการเปรยบเทยบสนสดลง จะทาใหด code ไดงายขน ลองดโปรแกรมตวอยางการตรวจสอบวา ตวเลขท user ใสเขาสโปรแกรมเปนเลขคหรอไม /* IfStatement.java - Using if statement to find out whether a number * is odd or even */ import java.io.*; import java.lang.Integer; class IfStatement { public static void main(String[] args) throws IOException {

no

yes

number *= 10;

number++;

number < 0

no

yes

statement

other_statement

เปนจรง?

Page 65: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 60 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

int number; //set up buffer stream InputStreamReader isr = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(isr); //get input string System.out.print("Enter a number (int): "); String input = buffer.readLine(); //convert string to int number = Integer.parseInt(input); //check if number is even or not if(number % 2 == 0) System.out.println(number + " is an even number."); } } โปรแกรม IfStatement.java บอก user ใหใสตวเลขหนงตว ซงโปรแกรมไดจดเกบไวในตวแปรชอ number หลงจากนนกทาการตรวจสอบวาตวเลขทอานมาเปนเลขคหรอไมดวยประโยค if(number % 2 == 0) System.out.println(number + " is an even number."); ซงถานาสองไปหาร number แลวไมมเศษ (หารลงตว) แสดงวาตวเลขทวานเปนเลขค ซงโปรแกรมกจะแสดงขอความไปยงหนาจอบอกผใชวา ตวเลขทใสเขามาเปนเลขค ดงเชนผลลพธของการ run น Enter a number (int): 45 Enter a number (int): 20 20 is an even number. โปรแกรมของเรายงไมใชโปรแกรมทสมบรณ ดงจะเหนไดจากผลลพธทได ถาเราใส 45 โปรแกรมกจะไมแสดงอะไรเลย จะแสดงกตอเมอตวเลขทใสเปนเลขคเทานน เราจะกลบมาดวาเราตองทาอยางไร ถงจะสามารถทจะแสดงขอความไปยงหนาจอโดยแบงแยกวาตวเลขนนเปน เลขคหรอเลขค การใช if ในประโยคทมมากกวาหนงประโยค (if – block) การเขยน code ทมมากกวาหนงประโยคนน ทาไดดวยการใชเครองหมาย {} ลอมรอบประโยคเหลานน (compound statement) ดงตวอยางทเหนน if(expression) { statement 1; statement 2; statement 3; … statement n; } เชน if(number % 2 == 0) { System.out.println(number + " is an even number."); number++; System.out.println("But " + number + " is not!"); }

Page 66: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 61 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ทนเราจะกลบไปยงประเดนทเราพดถงกอนหนาน เกยวกบเรองของการแสดงผลทงทเปนจรง และไมเปนจรง ในการตรวจสอบดวยการใช if นนเราสามารถทจะบงคบการประมวลผลใหเกดขนทงทเปนจรง และเปนเทจ อยางใด อยางหนงดวยการใช else ตามหลงประโยคทตาม if มาอกทหนง รปแบบโครงสรางของประโยค if – else นมดงน if(expression) statement; else other_statement; another_statement; ภาพท 3.2 แสดงถงโครงสรางของ if – else

ภาพท 3.2 การใช if - else จากโปรแกรม IfStatement.java ถาเราตองการทจะแสดงผลถาตวเลขท user ใสเขาสโปรแกรมเปนเลขค เรากตองเปลยน code ของเราใหเปนดงน /* IfElse.java - Using if - else statement to find out whether a * number is odd or even */ import java.io.*; import java.lang.Integer; class IfElse { public static void main(String[] args) throws IOException { int number; //set up buffer stream InputStreamReader isr = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(isr); //get input string System.out.print("Enter a number (int): "); String input = buffer.readLine();

noyes

statement

another_statement

เปนจรง?

other_statement

Page 67: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 62 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//convert string to int number = Integer.parseInt(input); //check if number is even or not if(number % 2 == 0) System.out.println(number + " is an even number."); else System.out.println(number + " is an odd number."); System.out.println("Good Bye."); } } ประโยคทเราไดเขยนเพมเขาสโปรแกรมของเรา คอ else System.out.println(number + " is an odd number."); System.out.println("Good Bye."); ซงจะทาใหโปรแกรมของเราทาการประมวลผลประโยคทอยถดมาจาก else ถา number % 2 == 0 เปนเทจ และตวเลขทจะทาใหประโยคนถกประมวลผลกคอ ตวเลขทเปนเลขค (นา 2 ไปหารแลวเหลอเศษ) ลองดผลลพธของการ run น Enter a number (int): 45 45 is an odd number. Good Bye. Enter a number (int): 80 80 is an even number. Good Bye. จะเหนวาการนาเอา if – else มาใชทาใหโปรแกรมของเราสนองตอบความตองการในการแสดงผล เมอการตรวจสอบไดผลทเปนจรงทางหนง และเมอผลของการตรวจสอบเปนเทจ อกทางหนง เนองจาก if – else กเปน statement ตวหนงดงนนเรากสามารถทจะนาเอา if – else ไปใสไวในประโยคทเปน if – else อกประโยคหนงได หรอแมแตกระทงหลาย ๆ ประโยค เราเรยกประโยคทใช if – else แบบนวา Nested – if ซงมรปแบบโครงสราง ทมลกษณะคลาย ๆ กบทเหนน (อาจมประโยค if – else มากกวา หรอนอยกวา) if(expression 1) { statement 1; statement 2; } else if(expression 2) statement 3; else { statement 4; statement 5; } จากโครงสรางตวอยางดานบนนประโยคทจะไดรบการประมวลผลถา expression 1 เปนจรงคอ statement 1 และ statement 2 สวน statement 3 จะไดรบการประมวลผล ถา expression 2 เปนจรง และ statement 4 และ statement 5 จะไดรบการประมวลผลกตอเมอ expression 1 และ expression 2 เปนเทจ

if(expression 1) { statement 1; statement 2; } else if(expression 2) statement 3; else { statement 4; statement 5; }

หรอ

Page 68: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 63 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ลองมาดโปรแกรมตวอยางการใช Nested – if ในโปรแกรม Grades.java /* Grades.java - Using Nested - if finding letter grade * from a given score */ import java.io.*; import java.lang.Integer; class Grades { public static void main(String[] args) throws IOException { int score; char grade; //set up buffer stream InputStreamReader isr = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(isr); //get input string System.out.print("Enter your score: "); String input = buffer.readLine(); //convert string to int score = Integer.parseInt(input); //determine grade by given score if(score >= 90) grade = 'A'; else if(score >= 80) grade = 'B'; else if(score >= 70) grade = 'C'; else if(score >= 60) grade = 'D'; else grade = 'F'; System.out.println("Your grade is " + grade); } } โปรแกรม Grades.java ใชเกณฑการใหเกรดคอ ถา score มคา มากกวาหรอเทากบ 90 ได A มากกวาหรอเทากบ 80 ได B (อยระหวาง 80 ถง 89) มากกวาหรอเทากบ 70 ได C (อยระหวาง 70 ถง 79) มากกวาหรอเทากบ 60 ได D (อยระหวาง 60 ถง 69) ตากวา 60 ได F เราไดออกแบบใหการตรวจสอบเปนไปไดทกกรณดวยการใชการเปรยบเทยบจาก 90 ลงไปถง 60 ตามขนตอน คอ ถา user ใส score ทมคาเทากบ 75 การเปรยบใน if แรก และ if ทสองจะเปนเทจ แตจะมาเปนจรงใน if ทสามคอ score >= 70 ประโยคทตามมา grade = 'C' กจะไดรบการประมวลผล สวนในกรณสดทายนน ประโยค grade = 'F' จะไดรบการประมวลผลกตอเมอ ทก ๆ กรณของการตรวจสอบกอนหนานเปนเทจทงหมด ผอานควรตรวจสอบประโยค if – else จากตวอยางดวยคา score ทแตกตางกนเพอใหเกดความเขาใจมากยงขน ผลลพธของการ run ดวยขอมลบางสวน

Page 69: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 64 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Enter your score: 87 Your grade is B Enter your score: 45 Your grade is F Enter your score: 92 Your grade is A เราสามารถทจะเขยนโปรแกรม Grades.java ขนใหมดวยการใช operator && หรอ || ชวยในการตรวจสอบถงสถานะภาพของ score วาอยในกลมใด ลองมาดกน /* Grades2.java - Using Nested - if finding letter grade * from a given score */ import java.io.*; import java.lang.Integer; class Grades2 { public static void main(String[] args) throws IOException { int score; char grade; //set up buffer stream InputStreamReader isr = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(isr); //get input string System.out.print("Enter your score: "); String input = buffer.readLine(); //convert string to int score = Integer.parseInt(input); //determine grade by given score if(score >= 90) grade = 'A'; else if(score >= 80 && score <= 89) grade = 'B'; else if(score >= 70 && score <= 79) grade = 'C'; else if(score >= 60 && score <= 69) grade = 'D'; else grade = 'F'; System.out.println("Your grade is " + grade); } } เราเปลยน code ในการตรวจสอบใหมใหเปน if(score >= 90) grade = 'A'; else if(score >= 80 && score <= 89) grade = 'B'; else if(score >= 70 && score <= 79)

Page 70: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 65 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

grade = 'C'; else if(score >= 60 && score <= 69) grade = 'D'; else grade = 'F'; ซงเมอไดลอง run ดแลวกไดผลลพธเหมอนกนกบทไดจากโปรแกรม Grades.java แตขนตอนของการตรวจสอบไมเหมอนกน เราไดพดกอนหนานวา ถามการใช && และคาของประโยคทอยทางดานหนาของ && มคาเปนจรง ประโยคทอยทางดานหลงกจะไดรบการประมวลผลดวย เชน สมมตวา score มคาเปน 85 การประมวลผลใน if แรกจะเปนเทจ Java กจะประมวลผล if ทสอง คอ else if(score >= 80 && score <= 89) ซงทนเองท Java จะประมวลผลประโยคทอยหลง && ดวยเพราะประโยคทอยทางดานหนา คอ score >= 80 นนเปนจรง กรณอน ๆ ทมลกษณะคลายกนกจะถกประมวลผลในแบบเดยวกนน ซงเปนการประมวลผลทซาซอน ทง ๆ ทไมมความจาเปนทตองทาเลย แตนเปนเพยงตวอยางเดยวเทานน มกรณอกหลายกรณท ตองใช && หรอ || เขามาชวยในการตรวจสอบจรง ๆ เชนในกรณของโปรแกรมตอไปน ซงเปนโปรแกรมตรวจสอบวา ตวอกษรทกาหนดใหอยในกลมนน ๆ หรอไม /* UpperLower.java - Using && in if - else statement */ import java.io.*; class UpperLower { public static void main(String[] args) throws IOException { char ch = 'F'; if(ch >= 'A' && ch <= 'Z') System.out.println(ch + " is an uppercase letter."); else if(ch >= 'a' && ch <= 'z') System.out.println(ch + " is a lowercase letter."); } } โปรแกรมกาหนดใหตวแปร ch มคาเปนอกษร F ตวใหญ และใชประโยค if – else ทาการตรวจสอบวาตวอกษรทวานเปนอกษรตวใหญหรอตวเลก ซงกแนนอนวาผลลพธทไดจะตองเปนตวใหญ แตเราตองการทจะแสดงใหเหนถงการใช && เขามาชวยในการตรวจสอบคาของ ch ทเราไดกาหนดขน ในการเปรยบเทยบนน Java จะใชคา ASCII (Unicode) ในการเปรยบเทยบตวอกษรทงสองตว โดยในตอนแรกจะเปรยบเทยบ F กบ A (70 กบ 65) ซงผลของการเปรยบเทยบเปนจรง จงตองเปรยบเทยบ F กบ Z (70 กบ 90) ซงกเปนจรง ดงนนประโยคทตามมา System.out.println(ch + " is an uppercase letter."); จงไดรบการประมวลผล เชนเดยวกนกบตวอกษรตวเลก ถา ch เกบอกษรทเปนตวเลกอยการเปรยบเทยบจะเกดขนในประโยค else – if ทตามมา โปรแกรมตอไปนแสดงการใช || ในการตรวจสอบวาเดอนทกาหนดใหอยในฤดอะไร /* Season.java - Using || in if - else statement */ import java.io.*; import java.lang.Integer; class Season { public static void main(String[] args) throws IOException { int month; String season, input; InputStreamReader in; BufferedReader buffer; System.out.print("Enter month (1 – 12): "); in = new InputStreamReader(System.in);

Page 71: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 66 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

buffer = new BufferedReader(in); input = buffer.readLine(); month = Integer.parseInt(input); if(month == 3 || month == 4 || month == 5 || month == 6) season = "Summer"; else if(month == 7 || month == 8 || month == 9 || month == 10) season = "Rainy"; else if(month == 11 || month == 12 || month == 1 || month == 2) season = "Winter"; else season = "Never heard of it!"; System.out.println(month + " is in " + season); } } โปรแกรม Season.java ใช || ในการตรวจสอบวา month ท user ใสเขาสโปรแกรมนนอยในฤดอะไร โดยเรากาหนดใหเดอน 3 – 6 เปนฤดรอน 7 – 10 เปนฤดฝน และ 11 – 2 เปนฤดหนาว (ซงเดยวนชกจะไมแนนอนเสยแลว) ลองมาดผลลพธจากการ run ดกวา Enter month (1 – 12): 4 4 is in Summer Enter month (1 – 12): 8 8 is in Rainy Enter month (1 – 12): 1 1 is in Winter Enter month (1 – 12): 20 20 is in Never heard of it! Operator || นนเปนการเปรยบเทยบขอมลทอาจเปนไดหลาย ๆ อยาง ดงทเหนในโปรแกรม ถาเราใหคาของ month เปน 3 4 5 หรอ 6 เรากกาหนดให season มคาเปน Summer สวนเดอนอน ๆ กเชนเดยวกน ในทางตรงกนขามถาเราใช && แทนโปรแกรมของเรากจะไมทางานตามทเราคาดหวงไว กลาวคอ คาของ month ไมสามารถเปนไปไดทงสคา โปรแกรมกจะประมวลผลประโยคทตาม else ตวสดทายตลอดไป ผอานควรตรวจสอบวาทกลาวมาน เปนจรงหรอไม ในการใช Nested if – else นนเราจะตองระวงวาทก ๆ if ทเราใชจะตองม else หรอไมเพราะ Java จะตรวจสอบวา else ทใชนนวาม if อยกอนหนาหรอไม สมมตวามเรากตองระวงในเรองของขนตอนการตรวจสอบ วาเปนไปอยางทเราตงใจหรอไม เชนตวอยางน /* DanglingElse.java */ import java.io.*; class DanglingElse { public static void main(String[] args) { int x = 7, y = 99; if(x > 5) if(y > 5) System.out.println("x and y is greater than 5"); else System.out.println("x is less than 5");

Page 72: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 67 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} } โปรแกรม DanglingElse.java ทเหนนเมอ run แลวผลลพธทไดคอ x and y is greater than 5 ซงเปนไปตามทเราคดไว แตถาเราเปลยนคาของ y ใหเปน 2 ผลลพธทไดกลบเปน x is less than 5 ซงไมใชสงทเราตองการ เพราะเรารวา x มคามากกวา 5 สงทเกดขนคอ Java จดให else นนคกบ if ตวทสอง ดงน if(x > 5) if(y > 5) System.out.println("x and y is greater than 5"); else System.out.println("x is less than 5"); เพราะฉะนนถาเราตองการใหการประมวลผลเปนไปตามทเราตองการ เราตองใช {} เปนตวชวย ดงน if(x > 5) { if(y > 5) System.out.println("x and y is greater than 5"): } else System.out.println("x is greater than 5"); ซงเมอ run ดแลวกจะไดผลลพธเปนไปตามทเราตองการ คอ ไมมผลลพธใด ๆ แสดงไปยงหนาจอถา y มนอยกวา หรอเทากบ 0 ถงเวลาทเราจะกลบไปปรบปรงโปรแกรม Quadratic.java ทเราไดพดถงในบททสอง เพอใหมการตรวจสอบคาของ determinant ทอาจเปน 0 ดวยการใช if ในประโยค //calculate determinant double d = b * b – 4 * a * c; if(d <= 0) { System.err.println("Error: cannot find square root"); System.exit(1); } double det = Math.sqrt(d); เราไดกาหนดใหมการตรวจสอบคาของ d กอนการเรยกใช Math.sqrt() ถาคาของ d นอยกวา หรอเทากบ 0 เราจะฟองไปยง user พรอมกบยตการทางานของโปรแกรมทนท ดวยการเรยกใช System.exit(1) /* Quadratic.java - Calculating roots of function */ class Quadratic { public static void main(String[] args) { double a, b, c; //4x2 + 20x + 16 = 0 a = 4; b = 20; c = 16; //calculate determimant double d = b * b – 4 * a * c;

Page 73: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 68 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

if(d <= 0) { System.err.println("Error: cannot find square root"); System.exit(1); } double det = Math.sqrt(d); //calculate roots double x1 = (-b + det) / (2 * a); double x2 = (-b - det) / (2 * a); System.out.println("Root 1 = " + x1); System.out.println("Root 2 = " + x2); } } การใช Conditional Operator (? :) Java ม operator อกตวหนงทเราสามารถนามาใชแทน if – else ได เราเรยก operator ตวนวา Conditional operator หรอ operator ทม expression (statement) อยสามตว ซงมโครงสรางดงน คอ (expression) ? (true statement) : (false statement); เชน (number % 2 == 0) ? System.out.println("Even number.") : System.out.println("Odd number."); ลองดโปรแกรมตวอยางกน /* OddEven.java */ import java.io.*; class OddEven { public static void main(String[] args) { int num; String result; num = (int)(Math.random() * 100; result = (num % 2 == 0) ? "Even" : "Odd"; System.out.println(num + " is an " + result + " number."); } } โปรแกรม OddEven.java ใช operator ? : ในการตรวจสอบวา num เปนเลขคหรอ เลขค ซงถาเปนอยางใดอยางหนงกจะเกบขอมลนน (Even หรอ Odd) ไวในตวแปร result แลวจงแสดงผลไปยงหนาจอหลงจากนน ดงน 65 is an Odd number. โปรแกรม Min.java ทเหนดานลางนใช operator ? : ในการหาคาตวเลขทนอยทสดระหวางเลขสองตวทกาหนดให /* Min.java */ import java.io.*; class Min {

Page 74: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 69 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public static void main(String[] args) { int num1 = 45, num2 = 89; int min = (num1 < num2) ? num1 : num2; System.out.println("Min number is " + min); } } ผลลพธทไดจากการ run คอ Min number is 45 การใช operator ? : กคอการใช if – else นนเองดงนนกเปนเรองของผเขยนโปรแกรมเองวาอยากทจะใช operator ตวไหน เพราะทงสองใหผลการประมวลผลในลกษณะเดยวกน การใช switch Java มคาสงอกตวหนงทเราสามารถนามาใชแทน if – else ได คาสงนกคอ switch ซงมโครงสรางดงน switch(expression) { case value1 : statement; break; case value2 : statement; break; … default : statement; break; } คาทไดจาก expression ของ switch นนจะตองเปนคาทมชนดเปน char byte short หรอ int เทานน ถาเปนคาชนดอน Java จะฟองดวย error ทนท ภาพท 3.3 แสดงถงขนตอนการทางานของ switch

Page 75: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 70 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ภาพท 3.3 ขนตอนการทางานของ switch คาสง break ใน switch นนสาคญมาก ๆ ถาเราไมใส การทางานของ switch กจะไมไดผลลพธดงทเราไดคาดการณไว เราลองมาดตวอยางโปรแกรมการใช switch ด /* Switch.java - Using switch * to differentiate input */ import java.io.*; import java.lang.Integer; class Switch { public static void main(String[] args) throws IOException { int month; String season, input; InputStreamReader in; BufferedReader buffer; System.out.print("Enter month (1 – 12): "); in = new InputStreamReader(System.in); buffer = new BufferedReader(in); input = buffer.readLine(); month = Integer.parseInt(input); switch(month) { case 3: case 4: case 5: case 6: season = "Summer"; break; case 7: case 8: case 9: case 10: season = "Rainy"; break; case 11: case 12: case 1: case 2: season = "Winter"; break; default : season = "Never heard of it!";

yes

yes

no

no

statement

default

เปนจรง?

statementเปนจรง?

ทาคาสงอน ๆ ในโปรแกรม

break

break

break

Page 76: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 71 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

break; } System.out.println(month + " is in " + season); } } เราไดทาการเปลยนแปลงโปรแกรม Season.java ทใช if – else ใหมาใช switch แทน โดยเราไดรวมเอาเดอนทอยในฤดเดยวกนเหมอนทเราทากบโปรแกรม Season.java มาอยในกลมของ case เดยวกน จะเหนวาเราเขยน case ตาง ๆ ทอยในกลมเดยวกนตามหลงกนไปโดยไมมการประมวลผลใด ๆ จนกวาจะจบ case สดทายในกลมนน เชน case 3: case 4: case 5: case 6: season = "Summer"; break; Java จะประมวลผล case 3 กอนแตเราไมมประโยคใด ๆ ใน case นดงนน Java จงประมวลผล case 4 case 5 และจนกระทงมาถง case 6 ซงเปน case สดทายในกลม Java จงประมวลผลประโยค season = "Summer" และ break การนาเอา case ตาง ๆ มาตอกนในลกษณะนมผลเหมอนการประมวลผลดวยการใช operator || ในประโยคทเรยกใช if ผอานควรสงเกตถงการใช switch ในลกษณะนใหด เพราะเปนวธการทชวยลดขนตอนการเขยนไดดพอสมควร ผลลพธทไดจากการ run โปรแกรม Switch.java กเหมอนกนกบการ run โปรแกรม Season.java เรามาลองดตวอยางการใช switch อกสกตวหนง /* Switch2.java */ import java.io.*; import java.lang.Integer; class Switch2 { public static void main(String[] args) throws IOException { int digit; BufferedReader buffer; InputStreamReader isr; String input; System.out.print("Enter a digit: "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); input = buffer.readLine(); digit = Integer.parseInt(input); switch(digit) { case 1: System.out.println("You entered ONE."); break; case 2: System.out.println("You entered TWO."); break; case 3: System.out.println("You entered THREE."); break; case 4: System.out.println("You entered FOUR."); break; case 5: System.out.println("You entered FIVE."); break; case 6: System.out.println("You entered SIX.");

Page 77: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 72 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

break; case 7: System.out.println("You entered SEVEN."); break; case 8: System.out.println("You entered EIGHT."); break; case 9: System.out.println("You entered NINE."); break; case 0: System.out.println("You entered ZERO."); break; default: System.out.println("Sorry - not a digit!"); break; } } } โปรแกรม Switch2.java บอก User ใหใสตวเลขระหวาง 0 – 9 และจะแสดงตวหนงสอแทนตวเลขเหลานนกลบไปยงหนาจอ ซงเมอ run แลวกจะไดผลลพธดงน Enter a digit: 9 You entered NINE. Enter a digit: 2 You entered TWO. Enter a digit: 36 Sorry - not a digit! เมอเราใส 36 โปรแกรมกลบบอกวาไมใชตวเลข ทงนเพราะโปรแกรมของเราตรวจสอบเฉพาะตวเลขเพยงตวเดยวเทานน เราตองปรบปรงโปรแกรมของเราใหมถาเราตองการทจะตรวจสอบตวเลขจรง ๆ ทงหมด การทางานแบบวน (Loop) หลาย ๆ ครงทโปรแกรมเมอรตองการทจะใหโปรแกรมทาการประมวลผลในรปแบบเดมซา ๆ กน เชน คณตวเลข 1 – 10 ดวย 2 หรอ อานขอมลจาก keyboard จนกวา user จะพอใจ เราสามารถนาเอาชดคาสงท Java มใหมาใชกบการทางานทวานไดอยางไมยากนก ลองดโปรแกรมททาการแสดงคาจาก 1 – 10 ไปยงหนาจอน /* ForLoop.java */ import java.io.*; class ForLoop { public static void main(String[] args) { int number = 1; System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); number++;

Page 78: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 73 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); number++; System.out.println("Number now is " + number); } } แนนอนผลลพธทไดกตองเปน Number now is 1 Number now is 2 Number now is 3 Number now is 4 Number now is 5 Number now is 6 Number now is 7 Number now is 8 Number now is 9 Number now is 10 การแสดงคาจาก 1 – 10 นนยงไมมปญหาอะไรมากมายนก ถาเราตองการทจะแสดงคาจาก 1 – 100 หรอ จาก 1 – 1000 หละ เราคงตองพมพจนมอเมอยแนเลย ลองมาดวาเราจะใช loop ชวยในการทางานในลกษณะนไดอยางไร Java มโครงสรางหลายตวทเราสามารถนามาใชในการทางานแบบวนได คาสงทวาน คอ while, do..while และ for ชดคาสงแรกทเราจะดกน คอ for loop การใช for loop กอนทเราจะไปดโครงสรางของ for loop กนเรามาดกนวาโปรแกรมกอนหนาน ถาใช for loop แลวจะมหนาตาเปนอยางไร /* ForLoop2.java */ import java.io.*; class ForLoop2 { public static void main(String[] args) { int number; for(number = 1; number <= 10; number++) System.out.println("Number now is " + number); } } จะเหนวาโปรแกรมของเราสนลงมาก คาสงใน for loop บอกให Java รวาการประมวลผลตองทาทงหมด 10 ครงโดยเรมตนการประมวลผล เมอ number มคาเทากบ 1 ไปจนกวา number จะมคาเปน 10 ซงเมอ number มคาเปน 10 Java กจะยตการประมวลผลทงหมด และผลลพธทไดกเหมอนกนกบโปรแกรม ForLoop.java ทเราเขยนขนมากอนหนาน โครงสรางของ for loop มดงนคอ for(expression1 ; expression2 ; expression3) statement;

Page 79: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 74 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

โดยท expression ทงสามตวมการทางานทตางกน expression1 จะถกประมวลผลเปนตวแรกสด ซงโดยทวไป expression นมกจะถกเรยกวา initialization expression คอทาหนาทในการกาหนดคาเบองตนใหกบตวแปรทจะนามาใชใน for loop หลงจากนน expression2 กจะถกประมวลผล ซงถาการประมวลผลเปนจรงตามเงอนไข statement ทอยใน for loop กจะถกประมวลผล และ for loop จะยตการทางานทนททการประมวลของ expression2 เปนเทจ เมอ statement ทอยใน for loop สนสดการประมวลผลแลว expression3 กจะไดรบการประมวลผล และ for loop จะกลบไปประมวลผล expression2 อกครง ซงถาเปนจรง statement กจะถกประมวลผลอกครง ทาอยางนไปจนกวา expression2 จะเปนเทจ เราเรยก expression2 วา loop condition และ expression3 วา increment expression ภาพท 3.4 แสดงแผนผงการทางานของ for loop

ภาพท 3.4 ขนตอนการทางานของ for loop เรากลบมาดโปรแกรม ForLoop2.java ทเราเขยนกอนหนานวามการทางานอยางไร เราเรมตนดวยการเขยน for loop for(number = 1; number <= 10; number++) System.out.println("Number now is " + number); สงท Java ทากอนกคอ กาหนดคาตวแปร number ใหเปนหนง หลงจากนนกทาการตรวจสอบวาตวแปร number มคานอยกวา หรอเทากบสบหรอไม ซงกเปนจรง ดงนน Java จงประมวลผลประโยคทอยใน for loop เมอเสรจแลวจงไปประมวลผลประโยค number++ ซงเปนการเพมคาใหกบตวแปร number เสรจแลวจงกลบไปตรวจสอบวา number <= 10 อกครง ทาไปเรอย ๆ จนกวา number จะมคามากกวาสบจงจะยตการทางาน โดยสรปแลวขนตอนของ for loop มดงนคอ 1. กาหนดคาเบองตนใหกบ number 2. ตรวจสอบวา number <= 10 หรอไม ถาเปนจรง ประมวลผลประโยค System.out.println("Number now is " + number); ถาเปนเทจ ยตการทางานของ for loop 3. ประมวลผลประโยค number++ 4. กลบไปทาคาสงในขอสองใหม

yes

no

expression1

expression3

expression2(จรง ?)

statement อน ๆ ในโปรแกรม

statement

Page 80: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 75 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Expression ทสาคญทสดทจะทาให for loop ทางานตอ หรอยตการทางานกคอ expression ทสอง ดงนนในการใช for loop เราจงตองระมดระวงถงประโยคทใชในการตรวจสอบวาสามารถทจะทาไดทงสองกรณหรอไม เพราะถาเราตรวจสอบไมดการทางานของ for loop อาจทาไปโดยไมมการสนสด หรอทเรยกวา Infinite loop ตวอยางเชน ถาเราเปลยน for loop ของเราใหเปนดงน for(number = 1; number > 0; number++) System.out.println("Number now is " + number); For loop ใหมของเรากจะทางานโดยไมมทสนสด เพราะวาคาของ number จะมากกวาศนยอยตลอดเวลา ทาใหประโยคของการตรวจสอบเปนจรงเสมอ การเขยน for loop ใหทางานตลอดเวลานนสามารถเขยนไดหลายแบบ ตวอยางเชน int number = 1; for(;;) System.out.println("Number now is " + number); เราให for loop ทางานไปเรอย ๆ ดวยการยกเลก expression ทงสามตวทอยใน loop หรอยกเลก expression ทหนงและสาม ดงน int number = 1; for(;number > 0;) System.out.println("Number now is " + number); ถาเราตองการ infinite loop ทไมมประโยคใด ๆ เลยกทาได ดงน for( ; ;) ; เราลองมาดการใช for loop ในการบวกเลขจาก 1 ถง 100 /* Add1To100.java */ import java.io.*; class Add1To100 { public static void main(String[] args) { int total = 0; for(int i = 1; i <= 100; i++) total += i; System.out.println("Sum of 1 - 100 is " + total); } } ผลลพธของการ run คอ Sum of 1 – 100 is 5050 ตวอยางโปรแกรมตอไปนทาการคานวณหาดอกเบยทบตนในแตละป เปนจานวนเทากบจานวนปท user เปนผกาหนดจากเงนฝากเรมตนทหนงพนบาท (หรอเทากบจานวนท user เปนผใสเขาสโปรแกรม) โดยใชสตรการในการคานวณ คอ amount = p(1 + r)n โดยท

Page 81: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 76 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

p คอ จานวนเงนเรมตน (principal) r คอ อตราดอกเบยประจาป n คอ จานวนของปทตองการหา amount คอ เงนตนทนาฝากของทกป /* Interests.java */ import java.io.*; import java.lang.Integer; class Interests { public static void main(String[] args) throws IOException { double amount; //amount at the end of year double principal; //first deposit double rate; //annual interests rate int years; //number of years BufferedReader buffer; InputStreamReader isr; String input; //get input from user (principal, rate, years) System.out.print("Enter amount to deposit: "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); input = buffer.readLine(); principal = Double.parseDouble(input); System.out.print("Enter interests rate: "); input = buffer.readLine(); rate = Double.parseDouble(input); System.out.print("Enter number of year: "); input = buffer.readLine(); years = Integer.parseInt(input); //calculate and display amount System.out.println("\nYear\tAmount on deposit"); for(int y = 1 y <= years; y++) { amount = principal * Math.pow(1.0 + rate, y); System.out.println(y + "\t" + amount); } System.out.print("\nTotal interests after " + years); System.out.println(" years is " + (amount - principal)); } } ผลลพธของการ run ดวย principal = 10000 rate = 0.25 และ years = 5 Enter amount to deposit: 10000 Enter interests rate: .25 Enter number of year: 5 Year Amount on deposit 1 12500.0 2 15625.0 3 19531.25 4 24414.0625 5 30517.578125

Page 82: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 77 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Total interests after 5 years is 20517.578125 สวนประกอบทสาคญคอ for loop ททาหนาทคานวณหาจานวนเงนทไดรบในแตละป (พรอมทงดอกเบย) เราใช method Math.pow() ในการหาคาของดอกเบยในแตละป ซงเมอหาไดแลวเรากแสดงผลลพธไปยงหนาจอทนท for loop ของเรายตการประมวลผลเมอคาของตวแปร y มคามากกวาตวแปร years หลงจากแสดงจานวนของเงนในแตละปแลว เมอออกจาก for loop เรากแสดงจานวนของดอกเบยทงหมดทไดจากการฝากในชวงนน ถาหากเราไมตองการใชสตรในการคานวณหาดอกเบย เรากสามารถทาไดดวยการคานวณหาดอกเบยกอนแลวจงนาเอาดอกเบยทหาไดไปบวกกบเงนตน หลงจากนนกคานวณหาดอกเบยจากเงนตนใหมน ทาการคานวณจนกวาจะครบตามจานวนปทไดกาหนดไว ดงทแสดงดวย code น amount = principal; System.out.println("\nYear\tAmount on deposit"); for(int y = 1; y <= years; y++) { double interests = amount * rate; //calculate interests amount += interests; //calculate new principal System.out.println(y + "\t" + amount); } เราลองมาดโปรแกรมตวอยางอกตวหนงทใช for loop ในการควบคมการทางานของโปรแกรม พรอมทงยอมให user ใสขอมลหลาย ๆ ตวในบรรทดเดยวกนได /* AddNumbers.java - reading numbers from input line * user must specify space between those numbers and * hit <enter> when done. */ import java.io.*; import java.text.DecimalFormat; class AddNumbers { public static void main(String[] args) throws IOException { double number, sum = 0; //a number read and sum of numbers int count = 0; //total numbers read BufferedReader buffer; //input buffer InputStreamReader isr; //input stream StreamTokenizer token; //token from input stream DecimalFormat f = new DecimalFormat("0.00"); System.out.print("Enter numbers (space between – enter when done): "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); //get tokens from input buffer token = new StreamTokenizer(buffer); //set priority to EOL so that we can break out of the loop token.eolIsSignificant(true); //get each number from tokens //calculate the sum until EOL is reached for(; token.nextToken() != token.TT_EOL ;) { switch(token.ttype) { //token is a number case StreamTokenizer.TT_NUMBER: number = token.nval; //save token in number count++; //number of tokens read

Page 83: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 78 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

sum += number; //calculate sum break; default: System.out.println("Token is not a number! " + token.toString()); break; } } //calculate average and display result double average = sum / count; System.out.println("Sum of numbers = " + sum); System.out.println("Average of numbers = " + f.format(average)); } } โปรแกรม AddNumbers.java ใช method จาก class StreamTokenizer และ for loop เปนตวชวยในการดงเอาขอมลแตละตวท User ใสเขาสโปรแกรม เรากาหนดให user กดปม <enter> เมอสนสดการใสขอมล ดงนนเราจงจาเปนทจะตองบอกให Java รวาปม <enter> มความสาคญในการยตการทางานของ loop ซงเราทาไดดวยการเรยกใช method eolIsSignificant() ดวยคาทเปนจรงดงน eolIsSignificant(true); ถาเราไมเรยก method นมาใชการกดปม <enter> ของ user กจะไมมผลใด ๆ ตอโปรแกรม (โปรแกรมจะไมยตการทางาน และเราตองกดปม <ctrl> + c เพอใหโปรแกรมหยดการทางาน) เมอเรากาหนดความสาคญของปม <enter> แลวเรากเรมอาน token แตละตวทเราไดดงมาจาก keyboard จนกวา token นนจะมคาเปน EOL (End Of Line) ซงเปนตวกาหนดการสนสดของขอมลในบรรทดนน เราอาน token ทมอยทงหมดใน buffer มาเกบไวในตวแปร token ดวยคาสง token = new StreamTokenizer(buffer); หลงจากนนเรากตรวจสอบดวา token ทอยถดไปใน buffer เปน EOL หรอไม ซงถาไมเปนเรากเรยกใช switch เพอตรวจสอบดวา token ทอานมานนเปนตวเลขหรอไม ถาเปนเรากจะทาการบวกตวเลขนเขากบตวแปร sum พรอมกบเพมคาใหกบตวแปร count for(; token.nextToken() != token.TT_EOL ;) { switch(token.ttype) { //token is a number case StreamTokenizer.TT_NUMBER: number = token.nval; //save token in number count++; //number of tokens read sum += number; //calculate sum break; default: System.out.println("Token is not a number! " + token.toString()); break; } } เราตรวจสอบความเปนตวเลขของ token ไดดวยการเปรยบเทยบ token.ttype กบ StreamTokenizer.TT_NUMBER และถาเปนจรง token ทเปนตวเลขจะถกเกบไวในตวแปร nval (และมชนดเปน double) ดงนนตวแปร number จงตองประกาศใหเปน double และการดงคามาเกบในตวแปร number ทาไดดวยการกาหนดคาจากประโยค number = token.nval;

Page 84: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 79 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เนองจากวาเราสนใจเฉพาะ token ทเปนตวเลขเทานนเราจงไมสนใจ token ทเปนชนดอน ดงนนเราจงเพยงแตสงคาของ token กลบคนไปยงหนาจอถา token นนเปนชนดอนทไมใชตวเลข for loop ของเราจะทางานไปเรอย ๆ จนกวา user จะกดปม <enter> ซงการกดปม <enter> นจะทาให expression ทมอยเพยงตวเดยวใน for loop เปนเทจ การทางานของ for loop จงสนสดลง ผอานจะสงเกตไดวาเราไมสนใจกบ expression ท 1 และ expression ท 3 ของ for loop เลยทงนกเพราะวาเราไมตองมการกาหนดคาเบองตน หรอเพมคาใด ๆ เลย การยตการทางานของ for loop เกดจากการกดปม <enter> ของ user เทานน ผลลพธของการ run ดวยคาสมมตตาง ๆ Enter numbers (space between - enter when done): 20 30 45 789 12 34 Sum of numbers = 930.0 Average of numbers = 155.0 Enter numbers (space between - enter when done): 45 68 95 Sum of numbers = 208.0 Average of numbers = 69.33 Class StreamTokenizer ยงม field อน ๆ ทเราสามารถเรยกใชได แตไมไดกลาวไวในทนเพราะวา โปรแกรม AddNumbers.java ของเราสนใจแตเฉพาะการอานตวเลขเทานน ผอานสามารถหาขอมลไดจาก javadoc ของ Sun เอง ในการใช for loop นนเราสามารถทจะใช , (comma) เปนตวแบงการประมวลในแตละ expression ได ดงตวอยางโปรแกรมการหาผลรวมและคาเฉลยนของเลขจากหนงถงสบน /* Sum.java */ import java.io.*; class Sum { public static void main(String[] args) { int i, sum; for(i = 1, sum = 0; i <= 10; sum += i, i++) ; System.out.println("Sum = " + sum); System.out.println("Average = " + (double)sum / (i-1)); } } เรากาหนดให expression1 ของเรามขอความอยสองขอความคอ i = 0 และ sum = 0 โดยเราใช , เปนตวแบงขอความทงสอง เชนเดยวกนกบ expression3 เรากาหนดใหมขอความ sum += i และ i++ อย และในตว for loop นนเราไมมการกาหนดประโยคใด ๆ เลย ทงนกเพราะวาเราไดกาหนดใหการหาผลรวมนนอยใน expression3 แลว แตเราจะตองใส ; (หรอเราอาจใส {})เพอให Java รวาเราไดจบ for loop ของเราแลว for(i = 1, sum = 0; i <= 10; sum += i, i++) ; หรอ for(i = 1, sum = 0; i <= 10; sum += i, i++) { } การทางานของ for loop ทวานกเหมอนกนกบการเขยน for loop แบบเดม ตางกนตรงทเราไดยายตาแหนงของประโยคสองประโยค เทานนเอง

Page 85: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 80 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

sum = 0; for(i = 1; i <= 10; i++)

sum += i; ตาแหนงของขอความการหาผลรวมกมความสาคญ เราตองกาหนดใหประโยค sum += i นนอยกอนประโยค i++ ทงนกเพราะวา Java จะประมวลผลประโยคทอยทางซายของเครองหมาย , กอน แลวจงจะประมวลผลประโยคทอยถดไปทางขวา ซงถาเรากาหนดให i++ อยกอน sum += i การประมวลผลของเรากจะผดพลาด คาของผลรวมทไดคลาดเคลอน สวนทสาคญอกสวนหนงกคอ คาของ i สาหรบการคานวณหาคาเฉลย เราตองหกคาของ i ออกหนงคากอนนาไปหาร sum กเนองจากวาในขณะท for loop ยตการทางานนนคาของ i มคาเปน 11 การหาผลรวมของ for loop ทกลาวมาแลวนน เราสามารถทจะเขยนไดอกหลายรปแบบ เชน i = ; sum = 0; for( ; i <= 10; i++) ;

sum += i; หรอ i = 1; sum = 0; for( ; i <= 10; ) {

sum += i; i++;

} หรอ sum = 0; for( i = 1; i <= 10; ) {

sum += i; i++;

} ผอานควรคานงถงการเขยน code ทดแลวอานไดงาย มโครงสรางทมองดเปนสากล ดงนนถงแมวา Java จะยอมใหเราเขยน code ไดอยางอสระและหลายรปแบบ เรากไมควรเขยน code ทยากตอการทาความเขาใจ ยกเวนวาการเขยน code นน ๆ มความจาเปนทตองใชรปแบบนน ๆ ในการเขยน (จาเปนจรงหรอ?) การใช while loop การใช while loop กคลาย ๆ กบการใช for loop ตางกนเฉพาะโครงสรางบางโครงสรางเทานนเอง (ตาแหนงของ expression) เรามาดโครงสรางของ while loop กน while(expression) statement; while loop จะตรวจสอบวาคาของ expression นนเปนจรงหรอเทจ ถาเปนจรงกจะประมวลผลประโยคตาง ๆ ทอยภายใน while loop และจะประมวลผลประโยคอน ๆ ทตามมา (ภายนอก while loop) หลงจากทหลดออกจาก while loop แลว ภาพท 3.5 แสดงขนตอนการทางานของ while loop

Page 86: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 81 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ภาพท 3.5 ขนตอนการทางานของ while loop เรามาลองใช while loop แทน for loop ทเราไดใชในโปรแกรมตวอยางบางตวกอนหนาน /* Sum.java */ import java.io.*; class Sum { public static void main(String[] args) { int i, sum; i = 0; sum = 0; while(i <= 10) { sum += i; i++; } System.out.println("Sum = " + sum); System.out.println("Average = " + (double)sum / (i-1)); } } สงแรกทเราตองทากคอการกาหนดคาเบองตนใหกบตวแปร i และ sum หลงจากนนเรากทาการตรวจสอบดวาประโยค i <= 10 เปนจรงหรอไม ซงถาเปนจรงเรากให while loop ของเราทาการบวกคาของ i เขากบตวแปร sum พรอมทงเพมคาใหกบ i เมอเสรจแลว ถาเราลองเปรยบเทยบการใช while loop กบ for loop เราจะเหนวา ประโยค i = 0; sum = 0; คอ expression ทหนงของ for loop และประโยค

yes

noExpression (จรง ?)

statement

Next statement

Page 87: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 82 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

i <= 10 กคอ expression ทสองใน for loop สวนประโยค i++ กคอ expression ทสามใน for loop นนเอง (ถงแมวาเราไดกาหนดคาของ i ใหเรมตนท 0 กไมทาใหการประมวลผลเปลยนไป เพยงแตวา loop ของเราทางานมากขนอกหนงครง เทานน) ทนเรามาลองใช while loop แทน for loop ในโปรแกรม AddNumbers.java กน /* AddNumbers2.java - reading numbers from input line user must specify space between those numbers and hit <enter> when done. (using while loop) */ import java.io.*; import java.text.DecimalFormat; class AddNumbers2 { public static void main(String[] args) throws IOException { double number, sum = 0; //a number read and sum of numbers int count = 0; //total numbers read BufferedReader buffer; //input buffer InputStreamReader isr; //input stream StreamTokenizer token; //token from input stream DecimalFormat f = new DecimalFormat("0.00"); System.out.print("Enter numbers (space between – enter when done): "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); //get tokens from input buffer token = new StreamTokenizer(buffer); //set priority to EOL so that we can break out of the loop token.eolIsSignificant(true); //get each number from tokens //calculate the sum until EOL is reached while(token.nextToken() != token.TT_EOL) { switch(token.ttype) { //token is a number case StreamTokenizer.TT_NUMBER: number = token.nval; //save token in number count++; //number of tokens read sum += number; //calculate sum break; default: System.out.println("Token is not a number! " + token.toString()); break; } } //calculate average and display result double average = sum / count; System.out.println("Sum of numbers = " + sum); System.out.println("Average of numbers = " + f.format(average)); } } เราแทบทจะไมตองเปลยนอะไรเลย เพยงแตเปลยนประโยค for(; token.nextToken() != token.TT_EOL ;)

Page 88: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 83 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ใหเปน while(token.nextToken() != token.TT_EOL) เทานนเอง สวน code อน ๆ กยงคงเหมอนเดม ทง for loop และ while loop เปนโครงสรางของการทางานแบบวนทตองมการตรวจสอบกอนวาประโยคในการควบคมของ loop ทงสองเปนจรงหรอเทจ ซงหมายถงวาการทางานของ loop ทงสองอาจไมเกดขนเลยถาการประมวลผลประโยคควบคมเปนเทจ แตถาเราตองการทจะประมวลผลกอนอยางนอยหนงครง เราจะทาอยางไร การใช do..while Java มโครงสรางการใช loop อกตวหนงทยอมใหมการทางานอยางนอยกอนหนงครง แลวจงจะทาการประมวลผลประโยคควบคม นนกคอ do … while ซงมโครงสรางดงน do { statement } while(expression); ภาพท 3.6 แสดงขนตอนการทางานของ do … while loop

ภาพท 3.6 ขนตอนการทางานของ do … while ถาเราตองการทจะทางานอยางนอยหนงครงกอนทจะมการตรวจสอบเพอยตการทางาน หรอทางานตอไป do … while loop จะเปนโครงสรางทเหมาะสมทสด โปรแกรมตวอยางตอไปนแสดงถงการใช do … while loop ในการตรวจสอบนน ๆ /* DoWhile.java - do .. while to repeat the program until user enter a letter other than 'y' */ import java.io.*;

yes

no

Expression (จรง ?)

statement

statement

Page 89: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 84 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

import java.lang.Integer; class DoWhile { public static void main(String[] args) throws IOException { int score; char grade, ch; //set up buffer stream InputStreamReader isr = new InputStreamReader(System.in); BufferedReader buffer = new BufferedReader(isr); do { //get input string System.out.print("Enter your score: "); String input = buffer.readLine(); //convert string to int score = Integer.parseInt(input); //determine grade by given score if(score > 90) grade = 'A'; else if(score > 80) grade = 'B'; else if(score > 70) grade = 'C'; else if(score > 60) grade = 'D'; else grade = 'F'; System.out.println("Your grade is " + grade); System.out.print("\nDO you want to continue? <y/n> : "); String response = buffer.readLine(); ch = (char)response.charAt(0); } while(ch == 'y'); } } เราเพยงแตดดแปลงโปรแกรมการหาเกรดของเรา ดวยการเพม do … while และประโยค System.out.print("\nDO you want to continue? <y/n> : "); String response = buffer.readLine(); ch = (char)response.charAt(0); ทใชสาหรบการถาม user วาตองการทางานตอหรอไม โดยเราทาการดงเอาตวอกษรตวแรกทอยในบรรทดนนออกมา ทาการเปรยบเทยบกบตวอกษร y ใน expression ของ do … while loop ซงถาการเปรยบเทยบนนเปนจรงเรากจะทางานไปเรอย ๆ วธการเดยวทจะทาให do … while loop ยตการทางานกคอ การใสตวอกษร n (หรอ อน ๆ ทไมใช y) เราใช method chatAt() ดวยคา parameter ทเปนศนยเพอดงเอาอกษรตวแรกสดใน buffer มาเกบไวในตวแปร ch สาหรบการเปรยบเทยบประโยคควบคมของ do … while loop ผลลพธการ run โปรแกรมดวยคาตาง ๆ Enter your score: 89 Your grade is B

Page 90: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 85 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

DO you want to continue? <y/n> : y Enter your score: 12 Your grade is F DO you want to continue? <y/n> : y Enter your score: 75 Your grade is C DO you want to continue? <y/n> : n เรามาลองดโปรแกรมตวอยางอกตวหนงทใช do … while loop ในการหาผลรวมของเลขระหวาง 1 – 100 /* Sum2.java */ import java.io.*; class Sum2 { public static void main(String[] args) { int i, sum; i = 0; sum = 0; do { sum += i; i++; } while(i <= 100); System.out.println("Sum = " + sum); System.out.println("Average = " + (double)sum / (i-1)); } } ซงเมอ run ดกไดผลลพธดงน Sum = 5050 Average = 50.5 เราไมไดเปลยนแปลงอะไรมากมายใน loop ของเราเพยงแตเปลยนมาใช do … while loop เทานนเอง เพอใหเกดความเขาใจในการทางานของ loop ดยงขน เราจงนาเอาตวอยางของ code ทใช loop ในรปแบบตาง ๆ มาใหดกน ผอานควรตรวจสอบถงผลลพธทควรจะไดจากการทางานของ loop เหลานดวยมอ กอนทจะเขยนโปรแกรมตรวจสอบ ตวอยางท 1 class Loops { public static void main(String[] args) { int index = 1; while(index != 9) { index += 2; System.out.println(index); index--; }

Page 91: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 86 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} } ตวอยางท 2 class Loops1 { public static void main(String[] args) { int index1, index2; index1 = 33; index2 = 1; while(index1 < index2) { index1 = index1 + 10; System.out.println(index1); index2 = index2 * 2; } } } ตวอยางท 3 class Loops2 { public static void main(String[] args) { int index = 1; while(index != 33) { index++; System.out.println(index); index++; } } } การใช break และ continue หลาย ๆ ครงทเราตองการยตการทางานของ loop โดยท loop ยงไมสนสดการทางานของมนเอง เชน กาหนดให loop หยดการทางานเมอคาของ loop index มคาตรงตามเงอนไขทไดกาหนดไว ดงแสดงใหเหนในโปรแกรมตวอยางน /* Sum3.java */ import java.io.*; class Sum3 { public static void main(String[] args) { int i, sum; i = 0; sum = 0; do { sum += i; i++; //break out of loop when i >= 50 if(i >= 50) break; }

Page 92: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 87 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

while(i <= 100); System.out.println("Sum = " + sum); System.out.println("Average = " + (double)sum / (i-1)); } } เราใชโปรแกรม Sum2.java เปนพนฐานของการเปลยนแปลง โดยเรากาหนดใหมการตรวจสอบคาของ i วามากกวาหรอเทากนกบ 50 หรอไมซงถาเปนจรงเรากจะ break ออกจาก loop ทนท if(i >= 50) break; เมอเราลอง run ดเราไดผลลพธดงน Sum = 1225 Average = 25.0 ลองมาดโปรแกรมทใช break ในการหยดการทางานของ loop ทใชหาคาของตวเลขทกาหนดใหวาเปนเลขคจานวนสบตว /* Break.java */ import java.io.*; class Break { public static void main(String[] args) { for(int number = 1; ; number++) if(number % 2 == 0) { System.out.println("Number is " + number); //break out of loop when number >= 10 if(number >= 10) break; } } } เราจะตรวจสอบวาตวเลขเปนเลขคกอนแลวจงทาการแสดงตวเลขนน ๆ ไปยงหนาจอ เมอครบสบตวแลวเรากจะหยดการทางานของ loop ดงทแสดงใหเหนจากผลลพธทไดน Number is 2 Number is 4 Number is 6 Number is 8 Number is 10 ทนเรามาลองใช continue ดบาง /* Continue.java */ import java.io.*; class Continue { public static void main(String[] args) { for(int number = 1; number <= 10; number++) {

Page 93: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 88 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//skip if number is 5 if(number == 5) continue; System.out.println("Number is " + number); } } } การประมวลของ code ทเหลออยในโปรแกรมจะถกประมวลผล ยกเวนเมอคาของ number มคาเทากบหา ดงแสดงใหเหนจากผลลพธน Number is 1 Number is 2 Number is 3 Number is 4 Number is 6 Number is 7 Number is 8 Number is 9 Number is 10 การใช continue นนโดยทวไปมกจะไมคอยมทใชเทาไรนก เพราะการเขยนโปรแกรมโดยทวไปมกจะทาการประมวลผลกลมของคาสงทงหมดจนเสรจ หรอไมกยตการทางานเมอเงอนไขบางอยางเปนจรง การกระโดดขามการประมวลผลชดคาสงไมคอยจะมใหเหนมากมายนก ดงนนกคงตองขนอยกบการออกแบบโปรแกรมของผอานเองวาเหมาะสมอยางไรตอการใชชดคาสงตาง ๆ การใช Nested Loop เราสามารถทจะนาเอา loop ตาง ๆ ทเราไดพดถงมาใสไวใน loop ได เชนเดยวกบทเราทากบ if – else เนองจากวาตว loop เองกเปนประโยคอยางหนง ดงนนการนาประโยคมาวางซอนกนในการเขยนโปรแกรมกยอมทจะทาได เรามาลองดตวอยางการใช nested loop กน /* NestedLoop.java */ import java.io.*; class NestedLoop { public static void main(String[] args) { for(int row = 1; row <= 10; row++) { for(int column = 1; column <= 10; column++) { if(column > row) continue; System.out.print("*"); } System.out.println(); } } } โปรแกรม NestedLoop.java ของเราใช for loop สองตวในการแสดงจานวนของ '*' ในแตละแถว ดงทแสดงใหเหนจากผลลพธน (หนาถดไป)

Page 94: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 89 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

* ** *** **** ***** ****** ******* ******** ********* ********** ใน for loop ตวแรกของเรา เราใชตวแปร row เปน loop index ซงจะประมวลผลเปนจานวนเทากบสบครง และในแตละครงท row มการประมวลผล for loop ตวทสองทม column เปน loop index จะประมวลผลเปนจานวนเทากบสบครง เพราะฉะนนการประมวลผลของ for loop ทงสองตวจงมคาเปนจานวนเทากบหนงรอยครง ทก ๆ การประมวลผลของ for loop ตวทสองเราจะตรวจสอบวาคาของ column มากกวาคาของ row หรอไม ซงถามากกวาเราจะหยดการแสดงคา '*' ไปยงหนาจอทนทดวยการเรยกใช continue ทเราไดพดถงกอนหนาน ในขณะท row และ column มคาเทากบหนงนนเรากสง '*' ไปยงหนาจอ หลงจากนน column กมคาเปนสอง ซงมคามากกวา row การกระโดดขามจงเกดขน ซงจะเปนไปจนกระทง column มคาเทากบสบเอดการประมวลผลของ for loop ดานในจงยตลง หลงจากนน row กมคาเปนสอง เหตการณเดมกเกดขนอก แตตอนนการแสดงผล '*' จะมเพมขนจนกวาคาของ column จะมากกวา row เปนเชนนไปเรอย ๆ จนกระทงคาของ row มคาเปนสบเอดการประมวลผลของ for loop ดานนอกจงยตลง โดยความเปนจรงแลวเราสามารถทจะใช break แทนการใช continue ได ซงกจะไดผลลพธเหมอนกน ทงนเพราะการใช break จะทาใหเราหลดออกจาก for loop ดานในทนท ซงเปนการประมวลผลทดกวาการใช continue เนองจากวาเราประมวลผล for loop ดานในดวยจานวนครงทเทากบคาของ row ทเปนอยขณะนน (ผอานควรตรวจสอบดวาการประมวลผลของ for loop ดานในมจานวนเทากบกครง ในทก ๆ การประมวลผลของ for loop ดานนอก - ทกคาของ row) ตวอยางการใช nested-loop ในรปแบบตาง ๆ (ผอานควรตรวจสอบผลลพธดวยมอกอนการเขยนโปรแกรมทดสอบ) ตวอยางท 1 class Loops3 { public static void main(String[] args) { int j, k = 0; while(k < 3) { j = 5; while(j > 0) { System.out.println(j); j -= 2; } System.out.println("k = " + k); k++; } } }

Page 95: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 90 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ตวอยางท 2 class Loops4 { public static void main(String[] args) { int j, k = 1; while(k < 7) { j = 5; while(j > 0) { System.out.println("j = " + j); System.out.println("k = " + k); j--; } k *= 2; } } } ตวอยางท 3 class Loops5 { public static void main(String[] args) { int j = 10, k = 1; while(k < 8) { while(j > 0) { System.out.println("j = " + j); System.out.println("k = " + k); j--; } k = k * 2; } } } การใช Labeled continue และ Labeled break ใน for loop Java ยอมใหมการใช label ในการหยดและเรมการประมวลผลใหม ซงโปรแกรมเมอรหลาย ๆ ทานไมคอยจะเหนดวยกบการใชการประมวลผลในลกษณะนเทาใดนก เรามาดตวอยางกน /* LabledContinue.java */ import java.io.*; class LabeledContinue { public static void main(String[] args) { label: for(int row = 1; row <= 10; row++) { System.out.println(); for(int column = 1; column <= 10; column++) { if(column > row) continue label; //goto label System.out.print("*"); } } } }

Page 96: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 91 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เราไดดดแปลงโปรแกรม Continue.java ของเราสาหรบการแสดงการใช labeled continue ในโปรแกรม LabeledContinue.java เรากาหนดใหม identifier ทมชอวา label อยกอนหนา for loop ดานนอกของเรา ซงตองมเครองหมาย ':' ตามหลงเสมอ และในการใช continue ใน for loop ดานในนนเราจะตองม identifier ทเราใชตามหลง continue เสมอ การประมวลดวย labeled continue กไมยากนกทจะทาความเขาใจ เมอคาของ column มากกวาคาของ row การทางานใน for loop ดานในกสนสดลงและไปเรมตนใหมท for loop ดานนอก เพราะนนเปนททม label อย การทางานแบบนกเหมอนกบการกระโดดไปยงตาแหนงทเราตองการจะไปนนเอง ทงนกตองขนอยกบเงอนไขทเราไดตงไว ถาเราเปลยน continue ใหเปน break เราจะไดผลลพธอะไร เรามาลองดโปรแกรมทใช labeled break กนด /* LabledContinue.java */ import java.io.*; class LabeledContinue { public static void main(String[] args) { System.out.println("Statement before first label."); first: for(int i = 1; i <= 10; i++) { for(int j = 1; j <= 10; j++) { if(j > i) break first; System.out.println('*'); } } System.out.println("Statement after first label."); } } เราไดเพมประโยคทงกอนและหลง label ทชอวา first ของเราเพอจะไดดวาการประมวลผลเกดขนทใดบาง กอนทเราจะประมวลผลของประโยคทตามหลง first เราสงขอความไปยงหนาจอวา Statement before first label. และ for loop ของเราทงสองตวสงตวอกษรเพยงตวเดยวไปยงหนาจอคอ * หลงจากนนกสงขอความ Statement after first label. ไปยงหนาจอ จะเหนวาการใช labeled break นนทาใหการประมวลผลของเรายตลง เพราะวาประโยคทมอยใน block ของ first นนมเพยงประโยคเดยวดงนน Java จะประมวลผลประโยคทอยถดไป หลงจาก block ของ first ซงกคอประโยค System.out.println("Statement after first label."); เราสามารถทจะม label block ก block กไดในโปรแกรมของเรา การใช labeled break ถาใชไดอยางเหมาะสมแลวจะทาใหการเขยน code เปนไปไดอยางสะดวกยงขน ทงนกเพราะวาเราสามารถทจะกระโดดไปยง block ตาง ๆ ไดอยางงาย ๆ ลองมาดโปรแกรมตวอยางอกตวหนงทใช labeled break ในการหาผลคณของเลขระหวาง 1 – 5

Page 97: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 92 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

/* LabledBreak.java */ import java.io.*; class LabeledBreak { public static void main(String[] args) { int prod = 1; int i = 1; outer: while(true) { prod *= i; i++; if(i > 5) break outer; } System.out.println("Product = " + prod); } } เราใช while loop ททางานอยตลอดเวลาโดยไมมการกาหนดใหหยด (ใช true ใน expression) แตเรากาหนดใหมการหยดจากการใช labeled break ใน while loop เอง ตวโปรแกรมจะคานวณหาผลคณไปจนกวาคาของ i จะเปนหากจะ break ออกจาก block ทชอ outer ทนท และจะไปประมวลผลประโยคทอยถดมาจาก block ซงกคอ System.out.println("Product = " + prod) Loop เปนโครงสรางทใชมากในการเขยนโปรแกรมตาง ๆ ทงนเพราะ loop เอออานวยใหผเขยนเรยกใชชดคาสงตาง ๆ ซากนได ทาใหการเขยนโปรแกรมลดขนตอนการทางานลง และการทางานของโปรแกรมกกระชบยงขน เราจะกลบมาพดถง loop อกหลาย ๆ ครงในบทตอ ๆ ไป โดยเฉพาะในเรองของ Array และ String สรป ในบทนเราไดพดถงการใชประโยคของการเปรยบเทยบ และการตดสนใจ การใชประโยคควบคมการทางาน การใช loop ในการประมวลผลตดตอกน โดยรวมแลวเราไดพดถง

การใช if และ if-else การใช nested-if การใช Tertiary operator - ? : การใช switch การใช loop ตาง ๆ เชน for-loop while-loop และ do-while-loop การใช break continue และการใชประโยคทใช label

แบบฝกหด 1. จงเขยนโปรแกรมทรบ int จาก keyboard จานวน 10 ตว หลงจากนนใหคานวณหาผลรวม และ

คาเฉลยของขอมลทง 10 ตว ใหสงผลลพธออกทางหนาจอ 2. จงเขยนโปรแกรมทสรางตวเลขแบบสมจานวน 100 ตว เสรจแลวใหแสดงผลลพธออกทางหนาจอ

เฉพาะตวเลขทเปนเลขคเทานน โดยกาหนดใหการแสดงผลเปน 10 ตวตอหนงบรรทด 3. จากโจทยในขอ 2 แทนทจะแสดงผลเปนเลขคใหแสดงผลเฉพาะทเปนเลขคเทานน โดยแสดงเฉพาะ

เลขคทมากกวา 20 เทานน 4. จงเขยนโปรแกรมทแสดงตวอกษรตงแต A ไปจนถง Z ดวยการใช while loop โดยไมมการรบคาใด

ๆ จาก keyboard

Page 98: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 93 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

5. จงเขยนโปรแกรมทคานวณหาคาทเลกทสดในกลมตวอกษรทอานเขามาจาก keyboard ทละตว

(ตวอกษรทนาเขาควรมจานวนไมนอยกวา 10 ตว) 6. จงเขยนโปรแกรมทอานขอมล 2 ตวจาก keyboard โดยทตวแรกเปน หมายเลขของสนคา (product

number) และตวทสองเปน จานวนทขายไปในแตละวน (quantity sold) กาหนดใหมสนคาอย 5 ชนดทมราคาตางกน ดงน

สนคาท 1 ราคา 500.0 บาท สนคาท 2 ราคา 750.0 บาท สนคาท 3 ราคา 850.0 บาท สนคาท 4 ราคา 950.0 บาท สนคาท 5 ราคา 1000.0 บาท โปรแกรมจะคานวณหายอดเงนทขายไดของสนคาทกตว ในอาทตยทผานมา โดยทจานวนของสนคาแตละชนดทขายไปจะนาเขามาจาก keyboard โปรแกรมทเขยนขนตองใช switch ในการแยกแยะราคาของสนคาแตละชนดทเขามา ใหแสดงผลลพธออกทางหนาจอ

7. จงเขยนโปรแกรมทคานวณหาดอกเบยทบตนจากเงนตนทอานเขามาจาก keyboard ดวยสตรท

กาหนดให ตอไปน (คลาย ๆ กบตวอยางในบทน)

a = p(1 + r)n p หมายถงเงนลงทนครงแรก r หมายถงอตราดอกเบยตอป n หมายถงจานวนปทตองการฝากเงน a จานวนเงนทฝากเขาทก ๆ สนป โปรแกรมควรแสดงรายการออกเปนสอง column โดยท column แรกเปนปทฝาก และ column ทสองเปนดอกเบยทไดในแตละป ใหทดลอง run โปรแกรมดวยอตราดอกเบย 5% ตอป และเงนตนท 1000 บาท เปนเวลา 10 ป

8. จงเขยนโปรแกรมทแสดงผลลพธ ดงทเหนน ดวยการใช loop เทานน

********** ********** ********* ********* ******** ******** ******* ******* ****** ****** ***** ***** **** **** *** *** ** ** * *

9. จงเขยนโปรแกรมทรบคา int หนงตว (n) ทมากกวาศนย หลงจากนนใหแสดงผล ดงน

1 2 3 … n-1 n 1 2 3 … n-1 … 1 2 3 1 2 1

Page 99: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 94 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

10. จงเขยนโปรแกรมทรบคาเปน วน เดอน ป จาก keyboard หลงจากนนใหแสดงตาแหนงของวนทนนในป เชน 12 29 2002 จะแสดงเปน 363

11. จงเขยนโปรแกรมทรบคาตาง ๆ จาก keyboard เฉพาะทเปน 0 มากกวาศนย และ นอยกวาศนย ให

นบจานวนของคาทงสามวามอยางละกตว โปรแกรมจะหยดทางานไดกตอเมอ user ใสขอมลทไมใชตวเลข

12. จงเขยนโปรแกรมทรบคาระหวาง 1 – 100 หลงจากนนใหแสดงคาทรบเขามาในรปแบบของ

ตวหนงสอ เชน ถาขอมลนาเขาเปน 11 ผลลพธทไดคอ สบเอด 13. จงเขยนโปรแกรมททาการเขารหสของขอมลทนาเขาจาก keyboard โดยนาเอาตวอกษรทอานเขา

บวกกบคาของตวอกษรทอยถดไป 2 ตวอกษร mod ดวยจานวนของตวอกษรทมอย (26 ในภาษาองกฤษ) เชน ถาคานาเขาเปน a ผลลพธทไดจากการเขารหสจะเปน a + c ซงจะมคาเทากบ 97 + 99 = 196 % 26 = 14 ใหใชคานเปนตวบอกตาแหนงของตวอกษรทจะแสดงไปยงหนาจอ ซงตวอกษร ณ ตาแหนงท 14 นคอ n

14. จงเขยนโปรแกรมทรบคาเปนประโยคทางคณตศาสตร เชน 9 + 5 – 2 * 4 + 2 / 3 หลงจากนนให

ทาการประมวลผลประโยคดงกลาว ตามลาดบของขอมลทนาเขา 15. จงเขยนโปรแกรมทรบคาเดอนทเปนตวเลขระหวาง 1 – 12 หลงจากนนใหแสดงผลเปนจานวนของ

วนทมอยในเดอนดงกลาว 16. จงหาผลลพธของตวแปร sum จาก code ทให

class Loops6 { public static void main(String[] args) { int j = 0, k, m, n, sum = 0; while(j != 20) { k = 0; while(k != 100) { m = 0; while(m != 50) { n = 0; while(n != 10) { sum++; n++; } m++; } k++; } j++; } } }

17. จงเขยนโปรแกรมทคานวณหา ตวหารรวมมาก (GCD – Greatest Common Divisor) ของตวเลข

สองตวทรบเขามาจาก keyboard เชน gcd ของ 24 และ 15 คอ 3

note: gcd ของ x และ y คอ integer ทใหญทสดทหาร x และ y ลงตว (เหลอเศษ 0) 18. จงเขยนโปรแกรมทคานวณหา ตวคณรวมนอย (LCD – Least Common Multiple) ของตวเลขสอง

ตวทรบเขามาจาก keyboard เชน lcd ของ 24 และ 15 คอ 120

note: lcd ของ x และ y คอ integer ทนอยทสดททง x และ y หารลงตว

Page 100: Beginning JAVA [Thai]

บทท 3 การประมวลผลแบบวน (Repetition) 95 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

19. จงเขยนโปรแกรมทหา factor ของตวเลขทรบเขามาจาก keyboard เชน ถาขอมลเทากบ 18 factor

ทไดคอ 2 3 และ 3 (8 = 2 * 3 * 3)

Page 101: Beginning JAVA [Thai]

ในบทนเราจะมาดการสรางและใช array ซงเปนโครงสรางอกตวหนงททาใหเราสามารถเกบขอมลทเปนชนดเดยวกนหลาย ๆ ตวไวในตวแปรตวเดยว รวมไปถงการสรางและใช string ซงจะเปนการแนะนาใหผอานไดรจกกบ object ในภาษา Java แบบคราว ๆ หลงจากจบบทเรยนนแลว ผอานจะไดทราบถง

o การประกาศและกาหนดคาให array o การเขาหาขอมลในตาแหนงตาง ๆ ทอยใน array o การสราง array ทใชเกบ array o การสราง object ทเปน string o การสรางและใช array ทเกบ object o การใชกระบวนการตาง ๆ กบ object ทเปน string

การใช array Array เปนโครงสรางชนดหนงทประกอบไปดวยขอมลชนดเดยวกนทอาจมมากกวาหนงตว การเขาหาขอมลแตละตวทอยใน array จะตองทาผานทาง ชอของ array และ index ทมคาเปน integer (int) ประกอบกน Java ไดกาหนดให index ตวแรกสดทเกบขอมลมคาเปน 0 และจะเพมขนทละหนงคาไปเรอย ๆ จนกวาจะหมดขอมลทมอยใน array นน ๆ การประกาศตวแปรทเปน array ทาไดดงน datatype[] nameOfArray; เชน int[] listOfNumbers; double[] prices; char[] vowels; ในการประกาศ array นนเราจะตองกาหนดจานวนของขอมลสงสดท array นนสามารถเกบได ชนดของขอมลทจะเกบไวใน array นน เครองหมาย [] เปนตวบอกให Java รวาตวแปรทถกสรางขนมานเปน array และเครองหมายนกจะเปนตวทใชในการเขาหาขอมลแตละตวใน array หนงสอหลาย ๆ เลมเลอกทจะประกาศ array ในรปแบบทเหนดานลางน ซงมความหมายเหมอนกนกบทเราไดประกาศกอนหนาน int listOfNumbers[]; double prices[]; char vowels[]; สาหรบหนงสอเลมนเราจะใชการประกาศในแบบทหนง หลงจากทเราไดประกาศใหตวแปรเปน array แลวเรากตองกาหนดความจใหกบ array นน ดงน listOfNumbers = new int[5];

Page 102: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 97 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ประโยคทเราไดเขยนขนนนบอกให Java รวาเราตองการให Java จองเนอทในการเกบ int เปนจานวนเทากบ 10 ตวใหกบตวแปร listOfNumbers ซงตวแปรนจะเปนตวอางอง (reference) ถงขอมลทงหมดทไดถกเกบไวใน array น ภาพท 4.1 แสดงถงสงตาง ๆ ทเกดขนเมอเราประกาศการใช array

ภาพท 4.1 การประกาศและกาหนดขนาดของ array เมอมการประกาศใช array เชน int [] num; นน array ทเราไดประกาศนนยงไมมเนอทในหนวยความจาเลย เราตองกาหนดขนาดเพอใหเกดการจองเนอทในหนวยความจาดวยการใช operator new รวมไปถงจานวนของเนอททตองการใช เชน int [] num = new int[5]; และทกครงของการจองเนอท Java จะกาหนดใหขอมลในทก ๆ ตาแหนงมคาเปน 0 เสมอ ในการเขาหาขอมลแตละตวนน เรากเพยงแตกาหนด index ของขอมลทเราตองการเขาหา เชน num[3] num[2] เราไมสามารถเขาหาขอมล ณ ตาแหนงทมคา index เกน 4 ไดทงนเพราะเรากาหนดให array num มความจสงสดเทากบ 5 ดงนนคาของ index ทเปนไปได คอ 0 1 2 3 และ 4 ถาหากวาเราเขาหาขอมลทไมอยในตาแหนงทกลาวน Java จะฟองดวย error ทนท (array index out of bound) การกาหนดคาเบองตนใหกบ array เรารวาหลงจากการประกาศและจองเนอทใหกบ array นนถาเปน array ทเกบ int ทก ๆ หนวยความจาของ array จะมคาเปน 0 แตถาเราตองการใหเปนคาอนเรากสามารถทาได ดงโปรแกรมตวอยางน /* Array1.java */ import java.io.*; class Array1 {

index ของ array num

ใช operator new ในการจองเนอท ชนด int จานวน 5 ตว

num[0] num[3] num[4] num[1] num[2]

int [] num = new int[5];

ประกาศ array ทเกบ int

ชอของ array

ชนดของขอมลท array num เกบได

num.length จะมคาเทากบ 5

Page 103: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 98 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public static void main(String[] args) { int[] list; //declare array of int list = new int[10]; //allocate space for 10 ints for(int i = 0; i < list.length; i++) System.out.println("list[" + i +"] = " + list[i]); } } โปรแกรม Array1.java ประกาศใหตวแปร list เปน array ทเกบ int เปนจานวนเทากบ 10 ตว เมอประกาศเสรจแลว เรากใช for loop ในการเขาหาขอมลในแตละตว array โดยแสดงถงคาท Java กาหนดใหกบ array ของเราไปยงหนาจอ ซงมคาดงน list[0] = 0 list[1] = 0 list[2] = 0 list[3] = 0 list[4] = 0 list[5] = 0 list[6] = 0 list[7] = 0 list[8] = 0 list[9] = 0 การใช loop เปนวธการทงายทสดในการเขาหาขอมลทกตวทอยใน array ยกเวนวาเรารตาแหนงทแนนอนของขอมลทเราตองการใน array นน เชน ตาแหนงท 5 หรอตาแหนงท 3 เรากเขาหาไดโดยตรง ดงน list[5] หรอ list[3] เปนตน Array ทสรางขนใน Java นนเราสามารถทจะดงเอาขนาดของ array ออกมาไดดวยการเรยกใชคาคงททไดถกสรางขนหลงจากการประกาศและจองเนอทใหกบ array ดงน list.length; ทก array ทไดถกสรางขนจะมขนาดของ array เกบไวในตวแปรชอ length และเราเรยกขนาดออกมาไดผานทางชอของ array ตามดวย . และตวแปร length เรามาลองกาหนดคาในตาแหนงตาง ๆ ใหกบ array ของเรา /* Array2.java */ import java.io.*; class Array2 { public static void main(String[] args) { int[] list; //declare array of int list = new int[10]; //allocate space for 10 ints list[5] = 8; list[3] = 2; list[9] = 4; for(int i = 0; i < list.length; i++) System.out.println("list[" + i +"] = " + list[i]); } } ผลลพธทไดจากการ run คอ

Page 104: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 99 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

list[0] = 0 list[1] = 0 list[2] = 0 list[3] = 2 list[4] = 0 list[5] = 8 list[6] = 0 list[7] = 0 list[8] = 0 list[9] = 4 เราสามารถทจะกาหนดคาใหกบ array โดยทไมตองกาหนดขนาดใหกบ array โดยตรง แตให Java จดการเกยวกบเรองเนอทใหเรา ดงโปรแกรมตวอยางตอไปน /* Array3.java */ import java.io.*; class Array3 { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90}; for(int i = 0; i < list.length; i++) System.out.println("list[" + i +"] = " + list[i]); } } เรากาหนดให list เปน array ทเกบ int และกาหนดคาเบองตนเปน 2 3 1 56 และ 90 ตามลาดบ เมอ Java เหนการประกาศในลกษณะนกจะทาการจองเนอทใหกบ array โดยอตโนมตพรอมทงนาคาตาง ๆ ทไดถกกาหนดจาก user ไปใสไวใน array list และเมอ run ดเรากไดผลลพธดงทเหนน list[0] = 2 list[1] = 3 list[2] = 1 list[3] = 56 list[4] = 90 โปรแกรมตวอยางตอไปนแสดงถงการเกบขอมลท user ใสเขามาจาก keyboard เขาส array /* ArrayOfNumbers.java */ import java.io.*; import java.text.DecimalFormat; import java.lang.Integer; class ArrayOfNumbers { public static void main(String[] args) throws IOException { double number, sum = 0; //a number read and sum of numbers double[] list; //array of double int count; //number of items in array String input; //input string BufferedReader buffer; //input buffer InputStreamReader isr; //input stream DecimalFormat f = new DecimalFormat("0.00"); System.out.print("How many numbers? : "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr);

Page 105: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 100 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

input = buffer.readLine(); count = Integer.parseInt(input); //total items in list list = new double[count]; //allocate space forlist //reading each double into list for(int i = 0; i < list.length; i++) { System.out.print("Enter number: "); input = buffer.readLine(); list[i] = Double.parseDouble(input); } //add all doubles in list int n = list.length - 1; //n is the last index of list while(n >= 0) { //looping until n equals to 0 sum += list[n--]; //add list[n] into sum and } //decrement n //calculate average and display result double average = sum / count; System.out.println("Sum of numbers = " + sum); System.out.println("Average of numbers = " + f.format(average)); } } โปรแกรม ArrayOfNumbers.java ถาม user ถงจานวนของขอมลสงสดท user จะใสเขาสโปรแกรม ซงเมอไดแลวโปรแกรมจะใชจานวนทอานไดเปนตวกาหนดขนาดใหกบ array list = new double[count]; หลงจากนนกจะอานขอมลทละตวจาก user นาไปเกบไวใน array list for(int i = 0; i < list.length; i++) { System.out.print("Enter number: "); input = buffer.readLine(); list[i] = Double.parseDouble(input); } ในขณะทอานขอมลเขาส array นนเราอาจหาผลรวมของเลขทกตวพรอม ๆ กนไปดวยกได แตทโปรแกรมนแยกการหาผลรวมกเพอทจะแสดงใหเหนถงการใช loop ในการเขาหา array อกครงหนง โดยเรากาหนดใหตวแปร n เปน index ตวสดทายของ array list ดวยประโยค int n = list.length - 1; เราตองไมลมวา list.length ใหจานวนของขอมลทงหมดทอยใน array ดงนน index ตวสดทายกคอ list.length – 1 หลงจากนนเราจะใช while loop เปนตวเขาหาขอมลใน array แตละตวจากขางหลง และบวกขอมลทก ๆ ตวเขากบตวแปร sum while(n >= 0) { sum += list[n--]; } ประโยค sum += list[n--] นนจะบวกขอมลในตาแหนง n เขากบตวแปร sum กอนทจะลดคาของ n ลงหนงคา และเมอคา n นอยกวา 0 เรากหลดออกจาก while loop ทนท

Page 106: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 101 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การอางถง array ดวยการ clone และการ copy array เมอเราสราง array ขนมาแลวเราสามารถทจะอางถงตวแปรตวนดวยตวแปรอนกได แตไมไดหมายความวาเราไดสราง array ตวใหมจากตวแปรตวใหมน เราเพยงแตใชตวแปรตวใหมในการอางถง array ตวเดม เพราะฉะนนการกระทาใด ๆ ผานตวแปรตวใหมกจะมผลกระทบกบขอมลใน array ตวเดมนน ดงโปรแกรมตวอยางน /* Array4.java */ import java.io.*; class Array4 { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90}; for(int i = 0; i < list.length; i++) System.out.println("list[" + i +"] = " + list[i]); int[] newList = list; //cloning newList[0] = 11; //changing data at list[0] for(int i = 0; i < list.length; i++) System.out.println("list[" + i +"] = " + list[i]); } } เราไดดดแปลงโปรแกรม Array3.java ใหมการอางถง (reference) array list ดวยตวแปรตวใหมทชอ newList int[] newList = list; และเรากไดทาการเปลยนขอมล ณ ตาแหนง 0 ใหเปน 11 ผานทาง newList เมอลอง run ดเรากจะไดผลลพธดงทคาดไว list[0] = 2 list[1] = 3 list[2] = 1 list[3] = 56 list[4] = 90 list[0] = 11 list[1] = 3 list[2] = 1 list[3] = 56 list[4] = 90 สวนวธการ copy ขอมลจาก array ตวหนงไปยง array อกตวหนงนนมวธการอยสามวธททาได วธทหนงนนเราตองสราง array ใหมขนมาแลวก copy ขอมลทกตวจาก array ตวเดมเขาส array ตวใหม ดงน /* Array5.java */ import java.io.*; class Array5 { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90}; //original array int[] newList = new int[list.length]; //new array

Page 107: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 102 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//copy each item from list into newList for(int i = 0; i < list.length; i++) newList[i] = list[i]; for(int i = 0; i < list.length; i++) System.out.println("newList[" + i +"] = " + newList[i]); } } โปรแกรม Array5.java สราง newList ดวยคาสง int[] newList = new int[list.length]; เรากาหนดขนาดของ newList ดวยขนาดทมาจาก list หลงจากนนเราก copy ขอมลทกตวดวยการใช for – loop for(int i = 0; i < list.length; i++) newList[i] = list[i]; และเมอ run ดเรากไดผลลพธดงทคาดไว คอ newList[0] = 2 newList[1] = 3 newList[2] = 1 newList[3] = 56 newList[4] = 90 ทนเรามาดวธทสองกน /* Array6.java */ import java.io.*; class Array6 { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90}; //original array int[] newList = new int[list.length]; //new array //copy each item from list into newList System.arraycopy(list, 0, newList, 0, list.length); for(int i = 0; i < newList.length; i++) System.out.println("newList[" + i +"] = " + newList[i]); } } ถงแมวาเรายงไมไดพดถงเรองของ class หรอ method แตเรากตองมาทาความเขาใจถงการเรยกใช method ท Java มให เพราะวาวธทสองนเราใช method arraycopy() ทาการสรางและ copy ขอมลให ตอนนเราคงตองจาวธการเรยกใชมากกวาการทาความเขาใจอยางละเอยด (ซงเราจะพดถงในบทตอ ๆ ไป) เรา copy ดวยการใชคาสง System.arraycopy(list, 0, newList, 0, list.length); โดยเราตองใสขอมล หรอ เงอนไข (parameter) ตามท Java กาหนดไวคอ

Page 108: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 103 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ตวแรกเปน array ตวเดมทตองการ copy (list) ตวทสองเปน index เรมตนของ array ตวเดม (0) ตวทสามเปน array ตวใหมทตองการสราง (newList) ตวทสเปน index เรมตนของ array ตวใหม (0) ตวทหาเปน จานวนของขอมลทตองการ copy (list.length) วธทสามกคลาย ๆ กบวธทสองเพยงแตเราเรยกใช method clone() แทน ซงทาไดดงน /* Array7.java */ import java.io.*; class Array7 { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90}; //original array //cloning process int[] newList = (int[])list.clone(); for(int i = 0; i < list.length; i++) System.out.println("newList[" + i +"] = " + newList[i]); } } เราเพยงแตเรยกใช method clone() ดงทเหนในโปรแกรม Array7.java เรากสามารถทจะม array ตวใหมสาหรบการใชงาน ดวยประโยค int[] newList = (int[])list.clone(); เราจาเปนทจะตองทาการ cast ใหกบ array ของเราเสยกอนเพอใหชนดของ array ทถก clone ขนมานนเปนชนดเดยวกน ซงทาไดดวยการนาเอา (int[]) ไปใสไวหนาประโยค list.clone() ทงนตองกาหนดชอ array ตวเดมใหถกตอง (list) เพอไมใหเกดการผดพลาดใด ๆ วธทสามทไดกลาวไวจะ copy ขอมลใน array เดมทมอยทงหมดไปเกบไวใน array ตวใหม ดงนน ถาหากวาเราตองการทจะสราง array ใหมจากขอมลบางสวนของ array ตวเดมเรากตองใชวธทสอง ดงตวอยางน /* Array8.java */ import java.io.*; class Array8 { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90}; //original array int[] newList = new int[list.length-2]; //new array //copy item at index 2, 3, and 4 from list into newList System.arraycopy(list, 2, newList, 0, list.length – 2); for(int i = 0; i < newList.length; i++) System.out.println("newList[" + i +"] = " + newList[i]); } }

Page 109: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 104 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

โปรแกรม Array8.java ของเราตองการทจะ copy ขอมล ณ ตาแหนงท 2 3 และ 4 จาก array list เขาส array newList ในตาแหนง 0 1 และ 2 ตามลาดบ เพราะฉะนนเราตองเรยกใช method arraycopy() ดงน System.arraycopy(list, 2, newList, 0, list.length – 2); ผลลพธของการ run คอ newList[0] = 1 newList[1] = 56 newList[2] = 90 การใช array แบบยดหยน (Dynamic Array) เราสามารถทจะใชเทคนคทเราพดมากอนหนานในการสราง array แบบไมจากดจานวนของขอมลทสามารถจดเกบไดใน array นน ๆ เราเรยกการจดเกบแบบนวาการจดเกบแบบยดหยน แตกอนทเราจะสรางไดนนเราตองกาหนดให array เรมตนของเรามขนาดเบองตนกอน หลงจากนนจงจะสามารถขยายขนาดของ array ได ดงโปรแกรมตวอยางทไดดดแปลงมาจากโปรแกรม AddNumbers.java ทเขยนขนกอนหนาน /* DynamicArray.java */ import java.io.*; import java.text.DecimalFormat; class DynamicArray { public static void main(String[] args) throws IOException { double number, sum = 0; //a number read and sum of numbers double []list = new double[2]; //array of double int count = 0; //total numbers read BufferedReader buffer; //input buffer InputStreamReader isr; //input stream StreamTokenizer token; //token from input stream DecimalFormat f = new DecimalFormat("0.00"); System.out.print("Enter numbers (space between – enter when done): "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); //get tokens from input buffer token = new StreamTokenizer(buffer); //set priority to EOL so that we can break out of the loop token.eolIsSignificant(true); //get each number from tokens //calculate the sum until EOL is reached while(token.nextToken() != token.TT_EOL) { switch(token.ttype) { //token is a number case StreamTokenizer.TT_NUMBER: //double the size of list if(count > list.length-1) { double []newList = new double[list.length*2]; System.arraycopy(list, 0, newList, 0, list.length); list = newList; //point to new list } list[count] = token.nval; //save token into list

Page 110: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 105 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

sum += list[count]; //calculate sum count++; //number of tokens read break; default: System.out.println("Token is not a number! "); break; } } //calculate average and display result double average = sum / count; System.out.println("Sum of numbers = " + sum); System.out.println("Average of numbers = " + f.format(average)); } } เราประกาศตวแปร list ใหเปน array ทเกบ double เรมตนดวยจานวนเทากบ 2ตว และในการนาขอมลเขาส array นนเราจะตรวจสอบดวาจานวนของ index ทเราใชในการเขาหาขอมลแตละตวมคาเกนจานวนของขอมลทเปนอยขณะนนหรอไม ซงถาเปนจรงเรากจะทาการขยายขนาดใหกบ array list เปนจานวนสองเทาของขนาดเดม และทาการ copy ขอมลจาก array list ไปส array ใหมน (newList) หลงจากนนเรากอางถง array ตวใหมนดวยตวแปรเดมทเราใชในการเกบขอมลครงแรก (list) เราไมตองกงวลถงหนวยความจาทเราไดใชไปในการสราง array ตวเดมเพราะ Java จะทาการตรวจสอบถงหนวยความจาทไมมการใชงาน และจะคนหนวยความจานใหกบระบบโดยอตโนมต if(count > list.length-1) { double []newList = new double[list.length*2]; System.arraycopy(list, 0, newList, 0, list.length); list = newList; } วธการขยายขนาดของ array แบบนทาใหเราไมตองกาหนดขนาดของ array ใหมขนาดใหญมากมายเกนไปตอนทเราสราง array ในครงแรก เราสนใจเฉพาะเมอจาเปนตองขยายขนาดของ array จรง ๆ เทานน ผอานอาจเปลยนแปลงการขยายขนาดของ array ดวยการเพมทละกตวกได ทงนกขนอยกบความจาเปนและเหมาะสมกบงานนน ๆ ผลลพธของการ run โปรแกรม DynamicArray.java Enter numbers (space between - enter when done): 15 5 20 15 10 15 20 Sum of numbers = 100.0 Average of numbers = 14.29 โปรแกรมตวอยางการใช array ในการนบจานวนครงของลกเตาทออกซากนจากการโยนหลาย ๆ ครง /* DiceRolling.java */ import java.io.*; class DiceRolling { public static void main(String[] args) { int face, roll; int[] frequency = new int[7];//number of times each face occur //rolling the die for 100 times roll = 1; while(roll <= 100) { //calculate face of die face = (int)(Math.random() * 6) + 1;

Page 111: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 106 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//save each time the same face occur by using //indeces as faces of die frequency[face]++; roll++; } System.out.println("Face\tFrequency"); for(int i = 1; i < frequency.length; i++) System.out.println(i + "\t" + frequency[i]); } } โปรแกรม DiceRolling.java ใชตว index ของ array เปนหนาของลกเตาทถกโยนโดยการใชการสม ผานทาง method random() ซงจะบงคบใหผลลพธของการโยนนนอยระหวาง 1 – 6 ดวยการคณ 6 เขากบผลลพธทไดจากการสม บวกเขากบ 1 การนบจานวนครงกทาไดดวยการเพมคาใหกบขอมลท index นน ๆ ของลกเตา เชน ถาการโยนไดคาเทากบ 6 เรากเพมคาดวย frequency[6]++ ซงจะทาใหคาทอย ณ ตาแหนงนนเพมขนอกหนงคา วธการใช index ของ array ในลกษณะนชวยลดขนตอนการนบจานวนของหนาลกเตาทเกดขน ไดดกวาวธอน ๆ เชน การใช if – else มาชวยในการตรวจสอบวาการโยนใหคาอะไร แลวจงเพมคาใหกบตวแปรทเกบการนบของหนานน ๆ if(face == 1) count1++; else if(face == 2) count2++; else if(face == 3) count3++; … … else if(face == 6) count6++; ซงเปนวธทตองเขยน code มากกวาและใชตวแปรเยอะกวา การใช frequency[face]++ ผลลพธของการ run Face Frequency 1 12 2 25 3 24 4 7 5 12 6 19 การคนหาขอมลใน array การคนหาขอมลใน array นนทาไดอยสองวธใหญ ๆ คอ การคนหาแบบตามลาดบ (sequential search) และ การคนหาแบบหารสอง (binary search) เราจะมาดถงวธการคนหาแบบตามลาดบกอน เพราะเปนการคนหาทงายทสด การคนหาแบบตามลาดบ (Sequential search) ในการคนหาแบบนนนเราจะเรมตนจากขอมลตวแรกสดทอยใน array ทาการเปรยบเทยบขอมลตวนกบขอมลทตองการคนหาวาเปนตวเดยวกนหรอไม ถาใชเรากหยดการคนหา ถาเราคนไปจนถงตวสดทายแตกยงไมใช เรากรวาขอมลทตองการคนหาไมไดอยใน array ลองดโปรแกรมตวอยางกน

Page 112: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 107 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

/* SeqSearch.java */ import java.io.*; class SeqSearch { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90};; int number = 90; //number to search int i = 0; //loop index boolean notFound = true; //loop control variable while(notFound) { if(number == list[i]) //if found notFound = false; //break out of loop i++; //move to next number } //in the list if(!notFound) System.out.println(number + " is in the list."); else System.out.println(number + " is not in the list."); } } เราใช while loop ในการเขาหาขอมลทกตวทอยใน array list โดยเรากาหนดใหตวแปร notFound ซงมชนดเปน boolean เปนตวควบคมการทางานของ loop ซงถาการคนหาประสพผลสาเรจ ตวแปร notFound กจะถกกาหนดใหเปน false และ while loop ของเรากจะยตการทางานทนท หลงจากนนเรากแสดงผลของการคนหาไปยงหนาจอ ดงตวอยางของการคนหาเลข 90 จากโปรแกรมของเราน 90 is in the list. ถาหากวาเราไมตองการใช boolean เปนตวกาหนดการทางานของ loop เรากอาจกาหนดให loop ทางานไปเรอย ๆ และใชคาสง break เปนตวกาหนดการหยดกได โดยการเปลยน code ใหเปน /* SeqSearch2.java */ import java.io.*; class SeqSearch2 { public static void main(String[] args) { int[] list = {2, 3, 1, 56, 90}; int number = 90; //number to search int i = 0; //loop index while(true) { if(number == list[i]) //if found break; //break out of loop i++; //move to next number } //in the list if(i >= list.length) System.out.println(number + " is not in the list."); else System.out.println(number + " is in the list."); } }

Page 113: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 108 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เรารวาถาขอมลทตองการคนหาไมอยใน list ตวแปร i จะมคาเกนกวาจานวนของขอมลทมอยใน array ดงนนการแสดงผลจะตองใชการเปรยบเทยบคาของ i กบจานวนของขอมลทมอยใน array (แทนการเปรยบเทยบดวย boolean กอนหนาน) วธการตรวจสอบแบบนลดขนตอนการทางานของ loop ลงไปไดหนงครง เพราะเราจะ break ออกจาก loop ทนท ทเราคนหาขอมลเจอ การคนหาแบบนไมคอยนยมใชกนมากเทาไร ทงนกเพราะวาจะใชเวลาในการคนหามาก ถาขอมลทตองการคนหาอยดานหลงสดของ array ยงถา array เกบขอมลไวเยอะการคนหากจะใชเวลามากยงขน การคนหาแบบหารสอง (Binary search) การคนหาในรปแบบของ binary search จะทาการแบงขอมลทงหมดออกเปนสองสวนทกครงทมการเปรยบเทยบขอมลทตองการคนหา (key) การคนหาเรมตนดวยการเปรยบเทยบ key กบขอมล ณ ตาแหนงทอยกงกลางของ array ถา key มคานอยกวาขอมล ณ ตาแหนงนการคนหากยายไปคนทางซายของขอมลน และจะคนทางขวาถา key มคามากกวาขอมลทตาแหนงน การคนหาจะดาเนนไปจนกวาจะคนพบ นนกคอ key มคาเทากบขอมลทตาแหนงนน หรอไมกยตการคนถาไมมขอมลนนใน array สงทสาคญในการคนหาแบบนกคอ ขอมลจะตองมการจดเกบแบบจดเรยงจากนอยไปหามาก เพราะถาไมอยในรปแบบนแลวการคนหากจะทาไมได วธการคนหาดวย binary search จะลดจานวนครงของการเปรยบเทยบลงไปทละครง ทาใหการคนหาใชเวลานอยลง ตวอยางเชน การคนหาใน array ทมขอมลเทากบ 1024 ตวจะใชการเปรยบเทยบเพยง 10 ครง ครงแรกลดลงเหลอ 512 ครงทสองเหลอ 256 และครงตอ ๆ ไปเหลอ 128 64 32 16 8 4 2 และ 1 จะเหนวาลดลงมาก ซงเปนจดแขงของการคนหาของ binary search โปรแกรม BinSearch.java แสดงการคนหาดวยการใช binary search /* BinSearch.java */ import java.io.*; class BinSearch { public static void main(String[] args) { int[] list = {1, 2, 3, 4, 5, 6, 7, 8 ,9, 10}; //generate key to search int key = (int)(Math.random() * 10 + 1); int low = 0; //lower index int high = list.length - 1; //higher index int middle; //number at the middle (pivot) boolean found = false; //indicate search result while(low <= high) { middle = (low + high) / 2; //calculate pivot if(key == list[middle]) { //if found - stop searching found = true; break; } else if(key < list[middle]) //key is in lower half high = middle - 1; else low = middle + 1; //key is in upper half } if(found) System.out.println("Found " + key + "!"); else System.out.println(key + " not found!"); } }

Page 114: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 109 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

โปรแกรม BinSearch.java ของเราเรมตนดวยการกาหนดให array list มขอมลเปนจานวนเทากบ 10 ตว และกาหนดใหขอมลทตองการคนหา (key) มาจากการสม หลงจากนนกกาหนดให index หว (low) และทาย (high) ของ array เปน 0 และ list.length – 1 ตามลาดบ เราจะใช while loop เปนตวเขาหาขอมลใน array list ของเราดวยการเปรยบเทยบคาของ low กบ high ซงถาเมอใดกตามทคาของ low มากกวาหรอเทากบ high กหมายความวาการคนหาของเราไมประสพผลสาเรจ คอไมมขอมลนนอยใน list เรากจะยตการทางานทนท เราหาขอมลทอยตรงกลางดวย middle = (low + high) / 2; และเปรยบเทยบการคนหาทประสพผลสาเรจดวยประโยค if(key == list[middle]) { found = true; break; } เราจะเปรยบเทยบและแบงขอมลออกเปนสองสวนดวย else if(key < list[middle]) high = middle - 1; else low = middle + 1; เราจะยาย index ทอยหลงสดใหเปน middle – 1 ถาขอมลทเปน key นอยกวาขอมลทอย ณ ตาแหนง middle และจะยาย low ไปอยท middle + 1 ถา key มคามากกวาขอมล ณ ตาแหนง middle เราจะทาไปจนกวาจะเจอขอมลทตาแหนง middle หรอไมกหยดการทางานโดยไมพบขอมลทตองการคนหาเลย การเรยงลาดบ (sort) ขอมลใน array มวธการหลากหลายวธทสามารถนามาใชในการจดเรยงขอมลใน array แตเนองจากวาเรายงตองศกษาถงสวนประกอบอน ๆ ของ Java กอนทเราจะนาเอาวธการเหลานนมาใชได ซงหนงสอสวนมากกจะนาเอาวธการจดเรยงขอมลไปไวในวชาโครงสรางขอมล (ซงกเปนหนงสอเลมตอไปจากหนงสอเลมน) ดงนนเราจะพดถงเฉพาะการนาเอา method การ sort ท Java มใหมาใชโดยตรงเพอใหการทางานเปนไปไดรวดเรวยงขน เราเพยงแตสง array ทเราตองการ sort ไปให method sort() ท Java มให ดงน Arrays.sort(list) โดยท list เปน array ทเราตองการ sort โปรแกรม Sort.java แสดงวธการเรยกใช sort จาก class Arrays //Sort.java - recursive version import java.lang.Integer; import java.util.Arrays; class Sort { public static void main(String[] args) { int[] list = new int[100]; //array with 100 ints int i; //loop index //populate list with random ints for(i = 0; i < 100; i++) list[i] = (int)(Math.random() * 100 + 1);

Page 115: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 110 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//display 100 ints to screen – 20 per line for(i = 0; i < list.length; i++) { if(i % 20 == 0) System.out.println(); System.out.print(list[i] + "\t"); } System.out.println(); Arrays.sort(list); //calling sort from class Arrays //display again for(int j =0 ; j < list.length; j++) { if(j % 20 == 0) System.out.println(); System.out.print(list[j] + "\t"); } System.out.println(); } } ยงม method อกหลายตวใน class Arrays ทเราสามารถเรยกใชได ทงนกตองดวาเรากาลงทาอะไรอย ในทนจะขอพดอกเพยง method เดยวคอ binarySearch() เพราะวาเราไดพดถงวธการเขยน code ของ binary search มากอนหนานแลว โปรแกรม BinarySearch.java แสดงถงวธการเรยกใช method binarySearch() ทวาน //BinarySearch.java - recursive version import java.util.Arrays; class BinarySearch { public static void main(String[] args) { int[] list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int key = (int)(Math.random() * 10 + 1);//key to search for int found = Arrays.binarySearch(list, key); if(found >= 0) System.out.println("Found " + key + " at index " + found); else System.out.println(key + " is not in the list!"); } } เราเรยก method binarySearch() ดวย parameter 2 ตวคอ (1) array ทมขอมลอย – ในทนคอ list และ (2) ขอมลทตองการคนหา – ซงกคอ key ในโปรแกรมดานบนน ประโยค int found = Arrays.binarySearch(list, key) ถาขอมลทตองการคนหาอยใน list การเรยก method binarySearch() กจะไดคาของ index ทขอมลนนอยสงกลบมายงตวแปร found แตถาหาไมเจอคาทสงกลบจะมคานอยกวา 0 เสมอ ดงนนการแสดงผลจงตองเปรยบเทยบคาของ found กบคาของ 0 เมอทดลอง run ดผลลพธทไดคอ Found 3 at index 2 Found 1 at index 0

Page 116: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 111 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การสราง array ทมขอมลเปน array (Array of arrays) เราไดใช array ทมขอมลเปน primitive type จากตวอยางกอนหนานหลาย ๆ ตวอยาง เรามาลองดการสราง array ทมขอมลเปน array ด เราจะเรมตนดวยการประกาศ ดงน int[][] table = new int[5][5]; ซงหมายถงการประกาศใหตวแปร table เปน array ทมขอมล 5 ตวโดยทแตละตวนนเปน array ทเกบขอมลทเปน int อย 5 ตว เราจะใช [][] สองตวเปนตวบอกให Java รวาตวแปรตวนคอ array ทใชเกบ array โดยทวไปเรามกจะเรยก array ในลกษณะนวา array 2 มต ภาพท 4.2 แสดงถงเนอทของ array table

ภาพท 4.2 การสราง array ทเกบ array (array 2 มต) โปรแกรม Array9.java ทเหนดานลางนแสดงการใช array 2 มต โดยกาหนดใหมขนาด 5 x 5 และกาหนดใหขอมลมคาอยระหวาง 1 ถง 10 ดวยการสมจาก random() ความยาวหรอขนาดของ table หาไดจากคาคงททเกบไว length เชนเดยวกนกบ array 1 มต สวนขนาดของขอมลทอยในแตละแถวหาไดจากคาคงทในแถวนน เชน table[0].length table[3].length โปรแกรม Array9.java ใช table[i].length เปนตวกาหนดขนาดในแตละแถวโดยท i เปน index ของแถวนน ๆ /* Array9.java */ import java.io.*;

int [] [] table = new int [5] [5];

index ของขอมลในแตละแถว

table[0]

table[1]

table[2]

table[3]

table[4]

[0] [1] [3] [2] [4]

ชอของ array และ ตาแหนงของขอมลแตละตว (index)

Page 117: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 112 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class Array9 { public static void main(String[] args) { int[][] table = new int[5][5]; for(int i = 0; i < table.length; i++) { for(int j = 0; j < table[i].length; j++) table[i][j] = (int)(1 + Math.random() * 10); } for(int i = 0; i < table.length; i++) { for(int j = 0; j < table[i].length; j++) System.out.print(table[i][j] + "\t"); System.out.println(); } } } ผลลพธของการ run โปรแกรม Array9.java คอ 7 3 2 8 7 5 8 5 4 8 7 6 8 6 2 7 10 9 7 5 10 4 4 2 2 เรามาดโปรแกรมตวอยางอกตวหนงทประกาศและกาหนดคาใหกบ array 2 มตดวยการกาหนดแบบอตโนมตจาก Java เอง /* Array10.java */ import java.io.*; class Array10 { public static void main(String[] args) { //declare 2-D array with specific data int[][] table = { {1, 2, 3}, {5, 6, 8}, {7, 4, 6}, {4, 8, 9} }; for(int i =0 ; i < table.length; i++) { for(int j = 0; j < table[i].length; j++) System.out.print(table[i][j] + "\t"); System.out.println(); } } } เรากาหนดให table เปน array 2 มตทมจานวนแถวเทากบ 4 และจานวนขอมลในแตละแถวเทากบ 3 โดยการกาหนดนนเราตองใสขอมลในแตละแถวในเครองหมาย {} และแบงขอมลทอยแถวในแตละแถวดวยเครองหมาย , ดงน int[][] table = { {1, 2, 3}, /* แถว 0 */ {5, 6, 8}, /* แถว 1 */

{7, 4, 6}, /* แถว 2 */

Page 118: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 113 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

{4, 8, 9} /* แถว 3 */ };

เราสามารถทจะใหขอมลอยในบรรทดเดยวกนได เชน int[][] table = {{1, 2, 3}, {5, 6, 8}, {7, 4, 6}, {4, 8, 9}}; หลงจาก run โปรแกรมแลว ผลลพธทไดคอ 1 2 3 5 6 8 7 4 6 4 8 9 การใช array ทมจานวนของขอมลในแตละแถวไมเทากน เราสามารถทจะกาหนดใหขอมลในแตละแถวของ array มจานวนไมเทากนได ดงตวอยางดานลางน double [][] list = new double[5][]; ซงเปนการประกาศ array 2 มตทมจานวนแถวเทากบ 5 แตจานวนของขอมลในแตละแถวยงไมไดถกกาหนด เราอาจกาหนดใหขอมลในแถว 0 มจานวนเทากบ 4 และขอมลในแถว 4 มจานวนทากบ 10 เปนตน ดงน list[0] = new double[4]; list[4] = new double[10]; สวนขอมลในแถวทเหลออยกแลวแตวาเราอยากทจะใหมขอมลกตว หรอเราอาจกาหนดใหขอมลในแตละแถวมจานวนเทากบคาทเพมขนตามคาของแถว (index) เชน int m = 0; while(m < 5) { list[m] = new double[m + 1]; m++; } โปรแกรม Array11.java สราง array 2 มตทมขอมลในแตละแถวเทากบคาของ index ในแถวนน ๆ /* Array11.java */ import java.io.*; class Array11 { public static void main(String[] args) { double [][]list = new double[5][]; //allocate space for each row int m = 0; while(m < 5) { list[m] = new double[m + 1]; m++; } for(int i = 0; i < list.length; i++) { for(int j = 0; j < list[i].length; j++) System.out.print(list[i][j] + "\t"); System.out.println();

Page 119: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 114 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} } } เมอ run ดผลลพธทไดคอ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 การกาหนดขนาดของ array แบบนทาใหการใชเนอทในการเกบขอมลในแตละแถวมประสทธภาพมากขน ทงนกเพราะวาเราใชเฉพาะเนอททจาเปนตองใชเทานน ถาเราใชการกาหนดแบบเกาเราตองใชหนวยความจาเทากบ 8 x 25 = 200 byte แตถาเราใชการกาหนดตามเทาทใช เรากจะใชหนวยความจาเพยงแค 8 x 15 = 120 byte การสราง array ทมความจของขอมลในแตละแถวไมเทากนเอออานวยความสะดวกในการจองเนอท ทาใหการใชหนวยความจามประสทธภาพมากยงขน แตการทางานจะตองมการระมดระวงเปนพเศษ เพราะจานวนของขอมลในแตละแถวมจานวนไมทากน ผอานตองใชความละเอยดในการออกแบบ ถาตองการใช array แบบน ตวอยางการใช Array of arrays ในการหาคา max คา min และคาเฉลย //ArrayOfArrays.java import java.io.*; class ArrayOfArrays { public static void main(String[] args) { //inititial scores int [][]score = { {45, 87, 68, 57}, {98, 70, 58, 69}, {85, 42, 68, 82} }; double average; //average of scores int max, min, total = 0; //maximum, minimum, total of scores int count = 0; //total scores max = score[0][0]; //assuming max score is at [0][0] min = score[0][0]; //assuming min score is at [0][0] //looping for 3 rows for(int i = 0; i < score.length; i++) { //looping for 4 columns for(int j = 0; j < score[i].length; j++) { if(score[i][j] > max) //find max score max = score[i][j]; if(score[i][j] < min) //find mim score min = score[i][j]; total += score[i][j]; //calculate total count++; //number of scores } } //calculate average of scores average = (double)total / count; System.out.println("Maximum score is " + max); System.out.println("Minimun score is " + min); System.out.println("Average score is " + average);

Page 120: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 115 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} } โปรแกรม ArrayOfArrays.java กาหนดให score เปน array ทเกบขอมลเปนจานวนเทากบ 3 แถว แถวละ 4 ตว เราจะหา score ทเลกทสด score ทใหญทสด รวมไปถงการคานวณหาคาเฉลยของ score ทงหมด เราใช for – loop 2 ตวในการเขาหา array ของเราเหมอนเดม พรอมทงตรวจสอบวา score ตวไหนเปน max และ score ตวไหนเปน min ดวยการกาหนดใหทงสองตวแปรมคาเปนขอมลตวแรกสดทอยใน array และจะทาการเปรยบเทยบขอมล ณ ตาแหนงทงหมดใน array กบขอมลน ประโยค if(score[i][j] > max) max = score[i][j]; จะเปลยนคาของ max ใหมคาเทากบ score[i][j] ถาขอมลทตาแหนงนมากกวาคาของ max และประโยค if(score[i][j] < min) min = score[i][j]; จะเปลยนคาของ min ใหมคาเทากบ score[i][j] ถาขอมลทตาแหนงนนอยกวาคาของ min วธการหาคาของ max และ min แบบนสามารถนาไปใชไดกบการหาคา max และ min โดยทวไปไดโดยไมตองสนใจวาขอมลทอยภายใน array จะม range อยชวงไหน ทงนเพราะเราใชขอมลตวแรกสดเปนตวตรวจสอบกอน ทาใหการหาคาของทง max และ min เปนไปไดโดยไมตองกาหนดคาใหกบตวแปร max หรอ min ใด ๆ ทงสน (ถาเราไมตองการตรวจสอบเอง เรากสามารถทจะเรยกใช method max() และ min() ทมอยใน class Math ได – ดในบทกอน ๆ) ในสวนของการหาคาเฉลยกเหมอนกบทเราไดเคยทามาแลวกอนหนาน การใช array of arrays นนกเหมอนกบทเราใชตาราง หรอ table ในการเกบขอมลตาง ๆ หนงสอหลาย ๆ เลมเรยก array of arrays ทมแค row และ column วา array 2 มต (two dimensional array) สวน array of arrays ทมขอมลเปน array อกเรากมกจะเรยกวา array 3 มต เปนดงนทกครงทมการเพมมตใหกบ array แตการมองเหนหรอการใชกคงมนอย ถาหากวาจานวนมตทใชมมากกวา 3 มต เพราะวาคนเราชนกบการมองเหนแบบ 3 มตตลอดเวลา (เราจะทงใหผอานศกษาในเรองของ array 3 มตเอง) การใช String การใช string นนสามารถทาไดหลาย ๆ วธ และวธแรกทเราจะทาความรจกนนเปนการใช array เปนหลกในการทางานกบ string นน ๆ เราคงไมสามารถทจะเรยก string ในลกษณะนไดเตมปากเตมคามากนก เพราะวาโดยความเปนจรงแลว array ทเราใชในการทางานทเกยวของกบ String นนไมใช string โดยตรงแตเปน array ทเกบ char หลาย ๆ ตวไว หรอทเรยกกนวา array of characters ซงหนงสอหลาย ๆ เลมกมกจะเรยก string วา array of characters เราจะตรวจสอบวธการใช string แบบนพอสงเขป แลวเราจะกลบมาพดถง String ของ Java อยางละเอยดอกทหนง Array of characters การประกาศ string แบบนทาไดงาย ๆ เหมอนกบทเราประกาศใช array ทเกบขอมลชนดอน เพยงแตเราเปลยนให array เกบ char แทนเทานน เชน char [] string = new char[20]; การประกาศดานบนนเปนการสราง array ทใชเกบ char จานวนเทากบ 20 ตว โปรแกรมตวอยางดานลางแสดงการใช array of characters //ArrayOfChars.java import java.io.*; class ArrayOfChars { public static void main(String[] args) {

Page 121: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 116 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//declare array of char char[] str = new char[26]; int i = 0; //populate str with characters a to z for(char c = 'a'; c <= 'z'; c++) { str[i] = c; i++; } //print all characters to screen for(i = 0; i < 26; i++) System.out.print(str[i]); System.out.println(); } } โปรแกรม ArrayOfChars.java เรมตนดวยการสราง array of chars จานวน 27 ตวจากประโยค char[] str = new char[26]; หลงจากนนกใช for – loop ในการกาหนดคาใหกบทก ๆ ตาแหนงของ str ดวยการใช char เปน index ของ loop เนองจากวาการเพมคาใหกบ char นนทจรงแลวเปนการเพมคาใหกบตวเลขทเปนตวแทนของตวอกษรนน ๆ เชน ถาเรากาหนดให char c = 'f' การเพมคาใหกบ c หนงครงจะทาให c มคาเปน 'g' ซงเปนตวอกษรทอยถดไปในตาราง ASCII เพราะฉะนนการใช for – loop นกทาใหเกดการกาหนดคาใหกบ str ทกตาแหนง for(char c = 'a'; c <= 'z'; c++) { str[i] = c; i++; } ผอานคงเดาไดวาผลลพธของโปรแกรมตวนคออะไร abcdefghijklmnopqrstuvwxyz การใช array of characters นนไมคอยจะสะดวกมากนก ทงนเพราะเปนการทางานทเกยวกบ array เราอยากทจะม string จรง ๆ ทเราสามารถทจะทากระบวนการตาง ๆ ได เชน บวก string 2 ตวเขาดวยกน หรอตรวจสอบความเทากน ความเหมอนกนของ string อยางนเปนตน และ Java กม class String ใหเราเรยกใชงานทเกยวของกบ string โดยตรง String ใน Java String ใน Java นนเปน object ดงนนเราจงจาเปนตองเรยกใช class String ในการสราง string เพอการใชงานของเรา เชน เราอาจตองการเกบชอของ user ไวในโปรแกรม หรอสงขอความทเปน string ไปให user อยางนเปนตน การประกาศใช String กไมยาก ซงทาไดดงน String str = new String("Java is fun"); หรอแบบน String str = "Java is fun"; โดยเฉพาะการประกาศในประโยคทสองน มผลเทากบประโยค 2 ประโยคตอไปน char[] str = {'J', 'a', 'v', 'a', ' ', 'i', 's', ' ', 'f', 'u', 'n'}; String str = new String(str);

Page 122: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 117 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

จะเหนไดวา string กคอ array of chars นนเอง บางครงการประกาศตวแปร string โดยทไมมการกาหนดคาใหกบ string นนเรากทาไดดวยการประกาศเหมอนกบการประกาศตวแปรชนดอน เชน String name; ซงมความหมายวาตวแปร name เปน string ทไมไดอางถงคาใด ๆ เลย และถาเรา compile โปรแกรมทมการประกาศแบบนจะม error เกดขน วธการแกไขเพอไมให Java ฟองตอน compile เราตองกาหนดคา null ใหกบ string name ดงน String name = null; ซงบอกให Java รวา string name ไมไดอางถงขอมลใด ๆ เลย เราสามารถทจะอางถงขอมลใด ๆ กไดหลงจากนน ลองมาดโปรแกรมตวอยางการทางานกบ string //StringOps.java import java.io.*; class StringOps { public static void main(String[] args) { String first = "Java "; String second = "Programming"; String third = null; int percent = 100; third = first + second; System.out.println(third + " is " + percent + "% fun!"); } } โปรแกรม StringOps.java ประกาศตวแปรทเปน String 3 ตวคอ first second และ third โดยกาหนดให first มคาเปน "Java " second มคาเปน "Programming" และ third ไมมคาอางองถง string ใด ๆ พรอมกนนเราไดกาหนดใหตวแปร percent มคาเปน 100 ประโยค third = first + second; ทาการรวม first และ second เขาดวยกน ซงทาให third มคาเปน "Java Programming" และในประโยคททาการแสดงผลไปหนาจอนนเราไดเพมการแสดงผลคาของตวแปร percent และ string คงทตวอนเขาไปดวยเพอใหผลลพธเปน Java Programming is 100% fun! เราสามารถทจะรวมคาของตวแปรอนทไมใช string เขากบ string ไดดงน สมมตวาเราเพมตวแปรตอไปน int percent = 100; String is = " is "; String fun = "%fun!"; และเรารวม String และ int เขาดวยกน ดวยประโยค third = first + second + is + percent + fun;

Page 123: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 118 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เรากจะไดผลลพธเหมอนกนกบทเราไดทากอนหนาน สาเหตททาไดเพราะ Java จะเปลยน int ใหเปน string กอนทจะรวมเอา string ทงหมดเขาดวยกน การเปรยบเทยบ String เราไมสามารถทจะเปรยบเทยบ string 2 ตวดวยการใช == ไดเหมอนกบทเราทากบตวแปรทเปน primitive type ได เชน first == third เพราะวาประโยคดงกลาวจะเปรยบเทยบวา string ทงสองตวอางถงทเดยวกนหรอไม (ททเกบ string ใด string หนง) เชน ถาเราม String myString = "Motorcycle"; String yourString = myString; ซงทาใหตวแปร myString และ yourString อางถงขอมลเดยวกน (และจะใหคา true ถามการเปรยบเทยบดวย ==) ไมใชการเปรยบเทยบถงขอมลทตวแปรทงสองอางอย เชนถาเราม string ตอไปน String keyboard = "from Thailand"; String kb = "from Thailand"; ถาเราเปรยบเทยบดวยการใช if(keyboard == kb) … เราจะไดคา false ถงแมวาตวแปรทงสองจะมคาทเหมอนกน ทงนเพราะวาเครองหมาย == จะเปรยบเทยบคาอางอง (ทอย หรอ address ในหนวยความจา) ของตวแปรทงสองไมใชคาททงสองตวแปรเกบไว เราตองใช method อนท Java มใหใน class String โปรแกรมตวอยางของการเปรยบเทยบ string //StringCompare.java import java.io.*; class StringCompare { public static void main(String[] args) { String first = "Java "; String second = "Programming"; String third = "Java Programming"; String forth; forth = first + second; //forth is "Java Programming" if(third == forth) System.out.println("third and forth refer to the same string"); else System.out.println("third and forth do not refer to the same string"); first = forth; //first and forth refer to the same string System.out.println("first is " + first); System.out.println("forth is " + forth); if(first == forth) System.out.println("first == forth is true"); else

Page 124: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 119 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.println("first == forth is false"); } } โปรแกรม StringCompare.java แสดงถงการเปรยบเทยบ string ดวยการใชเครองหมาย == ถาเราสงเกตใหดจะเหนวา string third และ forth มคาทเหมอนกน (string ทประกอบไปดวย char ทเหมอนกนหมด) เมอ run ดผลลพธทไดคอ third and forth do not refer to the same string ซงบอกใหเรารวาการใชเครองหมาย == เปรยบเทยบความเหมอนหรอความแตกตางของ string ไมได เชนเดยวกนกบประโยคเปรยบเทยบถดมาในโปรแกรม เรากาหนดให first อางถงขอมลทเดยวกนกบ forth และเมอเรา run ผลลพธทไดกเหมอนกบทเราไดคาดหวงไวคอ first is Java Programming forth is Java Programming first == forth is true ถาเราตองการทจะเปรยบเทยบ string จรง ๆ เราตองใช method equals() และ method compareTo() ดงโปรแกรมตวอยางตอไปน //StringCompare1.java import java.io.*; class StringCompare1 { public static void main(String[] args) { String first = "Java "; String second = "Programming"; String third = "Java ProgramminG"; String forth; forth = first + second; //forth is "Java Programming" if(third.equals(forth)) System.out.println("third equals forth"); else System.out.println("third not equals forth"); first = forth; //first and forth refer to the same string if(first.equals(forth)) System.out.println("first equals forth"); else System.out.println("first not equals forth"); } } เราไดเปลยนให third มคาเปน "Java ProgramminG" เพอทจะแสดงใหเหนวาในการเปรยบเทยบนน char ทกตวจะตองเหมอนกน ผลลพธทเราไดจากการ run คอ third not equals forth first equals forth เราใชประโยค third.equals(forth) ในการเปรยบ third และ forth วามคาทเหมอนกน (เทากน) ซงถาเทากนจรงผลลพธทไดจากการเปรยบจะมคาเปน true และจะใหคา false ถาไมเทากน การเปรยบเทยบ string 2 ตวเพอตรวจสอบความเทากนนนเราจะเอาตวไหนอยดานหนากได เชน

Page 125: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 120 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

third.equals(forth) หรอ forth.equals(third) กได method equals() จะตรวจสอบตวอกษรทกตวทอยใน string โดยใหความสนใจในเรองของตวอกษรวาเปนตวอกษรตวเลกหรอตวใหญ การตรวจสอบจะใหคาทเปนจรงถาเหมอนกนทงรปรางและขนาด เชน g หรอ G ไมใชตวอกษรตวเดยวกน การตรวจสอบจะเปน false ในการเปรยบเทยบบางครงเรากไมสนใจวาตวอกษรทอยภายใน string นนเปนตวเลกหรอตวใหญ ซงถาเราตองการเพยงแตตรวจสอบถงความเหมอนทางรปรางเรากตองใช method equalsIgnoreCase() ในการเปรยบเทยบ string นน ๆ ถาเราเปลยนการเปรยบเทยบในโปรแกรมตวอยางกอนหนานจากการใช equals() มาเปน equalsIgnoreCase() ดงน if(third.equalsIgnoreCase(forth)) System.out.println("third equals forth"); else System.out.println("thrid not equals forth"); เรากจะไดผลลพธเปน third equals forth การเปรยบเทยบความไมเทากน (มากกวา หรอ นอยกวา) ของ string หลาย ๆ ครงเราตองตรวจสอบถงความมากกวา หรอ นอยกวาของ string เพอใหการจดเกบ string นน ๆ อยในรปแบบทมการจดเรยง ไมวาจะเปนจากนอยไปหามาก หรอมากไปหานอย ในการตรวจสอบวา string ตวไหนมากกวาหรอนอยกวากนนน เราจะใช method compareTo() เชน myString.compareTo(yourString); สมมตวา myString มคาเปน "lovely bike" และ yourString มคาเปน "lovely kite" การเปรยบเทยบดวย compareTo() จะใหคาทเปนบวก ทงนกเพราะวา ตวอกษร 'k' ใน yourString นนมคามากกวาตวอกษร 'b' ใน myString เรามาดโปรแกรมตวอยางการใช method compareTo() กนดกวา //StringCompareTo.java import java.io.*; class StringCompareTo { public static void main(String[] args) { String first = "lovely bike"; String second = "lovely kite"; String third = "lovely"; //compare first and second if(first.compareTo(second) > 0) System.out.println("first is greater than second"); else System.out.println("second is greater than first"); //compare first and third if(first.compareTo(third) > 0) System.out.println("first is greater than third"); else System.out.println("third is greater than first"); String a = "A";

Page 126: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 121 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

String z = "Z"; String str1 = "AAA"; String str2 = "AAA"; //compare a and z if(a.compareTo(z) < 0) System.out.println(a + " is less than " + z); //compare str1 and str2 if(str1.compareTo(str2) == 0) System.out.println(str1 + " equals " + str2); } } ผลลพธทเราไดจากการ run คอ second is greater than first first is greater than third A is less than Z AAA equals AAA โปรแกรมของเราเปรยบเทยบ first กบ second ดวยการตรวจสอบคาทไดจากการเปรยบเทยบกบ 0 ซงถา first มากกวา second ประโยคนกจะเปน true แตเนองจากวา first นนไมมากกวา second การเปรยบเทยบของเราจงใหผลลพธเปน false Java จงประมวลผลประโยคทอยใน else (สงผลลพธไปหนาจอ) – การประมวลผลประโยคอน ๆ กคลายกน โดยทวไปเราจะเปรยบเทยบคาทไดจาก method compareTo() กบ 0 เสมอเพราะจะทาใหเราไดคา true หรอ false ทสามารถนาไปใชในการเลอกประมวลผลประโยคตาง ๆ ไดตามทเราตองการ การเปรยบเทยบความเหมอนและเทากนกทาไดดวยการใชเครองหมาย == ดงเชนประโยคสดทายของโปรแกรม if(str1.compareTo(str2) == 0) System.out.println(str1 + " equals " + str2); ในการเปรยบเทยบดวย method compareTo() นคาทสงกลบมาเปนไปไดเพยงแค 3 คา คอ -1, 0, และ 1 เทานน โดยท -1 หมายถง string ทอยทางซาย นอยกวา string ทอยทางขวา (string ทเปน parameter) 0 หมายถง string ทงสองนนเทากน 1 หมายถง string ทอยทางซาย มากกวา string ทอยทางขวา เชน ถาเรามประโยค string1.compareTo(string2); string1 หมายถง string ทอยทางซาย string2 หมายถง string ทอยทางขวา หรอ string ทเปน parameter การเขาหาตวอกษรทอยใน string เราสามารถทจะเขาหาตวอกษรตาง ๆ ทอยใน string ไดดวยการใช method ตาง ๆ ดงทไดแสดงไวเปนตวอยางในโปรแกรม StringChars.java //StringChars.java import java.io.*;

Page 127: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 122 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

import java.lang.Character; class StringChars { public static void main(String[] args) { //setting up constant string String string = "Learn to write programs in Java doesn't take"

+ " as long as I think it would. But to fully understand" + " it is a time consuming task.";

int charCount = 0; //count of letters int vowelCount = 0; //count of vowels int lowerCaseCount = 0; //count of lowercase letters int upperCaseCount = 0; //count of uppercase letters int spaceCount = 0; //count of white spaces //check all letters for(int i = 0; i < string.length(); i++) { char ch = string.charAt(i); //check if it's a letter if(Character.isLetter(ch)) charCount++; //check if it's an uppercase if(Character.isUpperCase(ch)) upperCaseCount++; //check if it's a lowercase if(Character.isLowerCase(ch)) lowerCaseCount++; //check if it's a white space if(Character.isWhitespace(ch)) spaceCount++; //convert it to lowercase ch = Character.toLowerCase(ch); //check if it's a vowel if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') vowelCount++; } System.out.println(charCount + " characters counted."); System.out.println(upperCaseCount + " uppercase letters counted."); System.out.println(lowerCaseCount + " lowercase letters counted."); System.out.println(vowelCount + " vowels counted."); System.out.println(charCount - vowelCount + " consonants counted."); System.out.println(spaceCount + " spaces counted."); } } ผลลพธทไดจากการ run คอ 99 characters counted. 4 uppercase letters counted. 95 lowercase letters counted. 37 vowels counted. 62 consonants counted.

Page 128: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 123 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

24 spaces counted. การทางานของโปรแกรมเรมตนดวยการกาหนดใหตวแปร string มคาเปนคาคงททอยใน " " เราจะเขาหาตวอกษรแตละตวดวย for – loop และดงเอาตวอกษรออกมาจาก string แตละตวดวยคาสง char ch = string.charAt(i) ซงจะดงเอาตวอกษร ณ ตาแหนง index i นน ๆ มาเกบไวทตวแปร ch หลงจากนนกตรวจสอบดวย method ตาง ๆ ทมอยใน class Character เชน Character.isLetter(ch) ใหคา true ถาเปนตวอกษร Character.isUpperCase(ch) ใหคา true ถาเปนตวอกษรตวใหญ Character.isLowerCase(ch) ใหคา true ถาเปนตวอกษรตวเลก Character.isWhitespace(ch) ใหคา true ถาเปนชองวาง (เคาะแปน หรอ tab) พรอมทงเพมคาใหกบตวแปรทงหลายทเปนทเกบจานวนครงของตวอกษรตาง ๆ ทปรากฏใน string หลงจากนนกเปลยนตวอกษรใหเปนตวเลกเพอใชตรวจสอบวาเปนสระในภาษาองกฤษหรอไม สาเหตทเปลยนเพราะเราไมอยากทจะเสยเวลาในการตรวจสอบสระตวเลกทหนง และตวใหญอกทหนง อยางไรกตามทงสองกเปนสระอยเสมอ ch = Character.toLowerCase(ch); if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') vowelCount++; ยงม method อกมากมายใน class Character และ class String ทเราสามารถนามาใชในการทางานทเกยวของกบ string ตวอยางตอไปนเปนการคนหาคา (sub string) ทอยใน string ดวยการใช method indexOf() //IndexOf.java import java.io.*; import java.lang.Character; class IndexOf { public static void main(String[] args) { //setting up constant string String string = "Learn to write programs in Java doesn't take" + " as long as I think it would. But to fully understand" + " it is a time consuming task."; int itCount = 0; //count of it String it = "it"; //string to seach for //search for "it" int index = string.indexOf(it); while(index >= 0) { itCount++; //move to first letter after last "it" index += it.length(); //look for next "it" index = string.indexOf(it, index); } System.out.println("it appeared " + itCount + " times."); } }

Page 129: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 124 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ผลลพธของโปรแกรมคอ it appeared 3 times. โปรแกรมของเรากาหนดให index มคาเปนตาแหนงท "it" ปรากฏอยใน string ดวยคาสง int index = string.indexOf(it) เมอการคนหาประสพผลสาเรจเรากจะใช while – loop ในการคนหาตอไป แตกอนทเราจะดาเนนการนนเราจะเพมคาหนงคาใหกบ itCount กอน หลงจากนนเราจะเลอน index ไปอยในตาแหนงของตวอกษรตวแรกทอยหลง "it" ดวยคาสง index += it.length() เนองจากวา method indexOf() จะสงคาของตาแหนงของตวอกษรตวแรกของ "it" มาให เสรจแลวกทาการคนหาตอไปดวยคาสง index = string.indexOf(it, index) ทาการคนหาไปจนกระทงหมด string เรากออกจาก while – loop ในการใช indexOf() คนหานนเราตองเปรยบเทยบคาทสงกลบมากบ 0 เพราะถาหาไมเจอคาของ index กจะเปน -1 ทาใหเราหลดออกจาก while – loop ได Method indexOf() นนมอยสองตวทรบเงอนไข (parameter) ไมเหมอนกน ดงทเหนในโปรแกรม ตวแรกรบเพยงคาเดยวคอ sub string ทตองการคนหา สวนตวทสองรบคาสองคาคอ sub string ทตองการคนหา และ จด (index) เรมตนของการคนหา ซงถาสงเกตใหดเราใช indexOf() ตวแรกในการคนหาครงแรก และตวทสองในการคนหาตวตอ ๆ ไป ทงนกเพราะวาครงแรกสดเราไมรวาคาของ index แตในครงทสองนนเราไดคาของ index แลว ผอานตองจาไวเสมอวา indexOf() จะสงคา -1 มาใหถาไมม sub string ใน string นน ๆและจะสงคาของตาแหนงท sub string นนอยถาม sub string ทวา ตอไปเราลองมาดโปรแกรมททาการดงเอากลมของตวอกษร (คา) หรอทเรยกวา sub string ออกจาก string ด //SubString.java import java.io.*; import java.lang.Character; class SubString { public static void main(String[] args) { //setting up constant string String string = "Learning Java"; String str1 = string.substring(0); //the whole string String str2 = string.substring(9); //string: "Java" String str3 = string.substring(0, 8); //string: "Learning" System.out.println("str1 > " + str1); System.out.println("str2 > " + str2); System.out.println("str3 > " + str3); } } Java ม method substring() ใหเราใชอยสองตว คอ substring() ทไมม parameter และ substring() ทม parameter อยสองตว โดยทตวแรกเปน index เรมตนของ sub string และ parameter ตวทสองเปน index ตวสดทายทอยใน sub string นนแตไมนบตวมนเอง ดงทไดแสดงไวในโปรแกรม

Page 130: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 125 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

String str2 = string.substring(9) หมายความถงการเรมนบท index = 9 ไปจนถงตวสดทายใน string นน คอ เรมทตวอกษร 'J' ไปจบทตวอกษร 'a' ซงคอคาวา "Java" สวน String str3 = string.substring(0, 8) หมายถงการเรมนบท index = 0 ไปจนถงตวท 8 คอตงแตตวอกษร 'L' ไปจนถงตวอกษร ' ' (space) แตไมนบ space ดงนน sub string ทเราไดกคอ "Learning" เราสามารถทจะดงเอา sub string ออกจาก string ทเปนคาคงทได เชน String sub = "Basic idea about Java".substring(6) จะให "idea about Java" หรอ String sub = "Basic idea about Java".substring(6, 10) จะให "idea" ตารางท 4.1 แสดงถง method ตาง ๆ ของ class String ตาราง 4.1 method ของ class String method ความหมาย length() ความยาวของ String (จานวนตวอกษร) indexOf(String) ตาแหนงเรมตนท String ตวนอย ถาไมมจะเปน -1 indexof(String, start index) ตาแหนงเรมตนท String ตวนอยตามจดทกาหนด ถาไม

มจะเปน -1 lastIndexof(String) ตาแหนงสดทายของ String ตวน เทากบ -1 ถาไมม lastIndexof(String, start index) ตาแหนงสดทายของ String ตวนตามจดทกาหนด

เทากบ -1 ถาไมม trim() String ทไมม space อยทงดานหนา และหลง substring(start index) คาของ String ณ ตาแหนงทกาหนดจนจบ substring(start index, end index) คาของ String ณ ตาแหนงทกาหนดทงสอง replace(old char, new char) เปลยน char ทกตวดวย char ตวใหมทกาหนด charAt(index) คาตวอกษร ณ ตาแหนงทกาหนด equals(String) true ถา String ทงสองตวเทากน equalsIgnoreCase(String) true ถา String ทงสองตวเทากน ไมสนใจ case startsWith(String) true ถา String เรมตนดวย String ทกาหนด startsWith(String, start index) true ถา String เรมตนดวย String ทกาหนด ณ

ตาแหนงทกาหนด endsWith(String) true ถา String จบดวย String ทกาหนด

การใช class StringBuffer ในการสราง string แทนทจะใช class String เรากสามารถทจะใช class StringBuffer แทนได การทางานกไมแตกตางกนมากมายนก เชน สมมตวาเราจะสราง string สกตวหนงเรากทาได ดงน StringBuffer string = new StringBuffer("Basic String Operations"); เราสราง object หนงตวชอ string จาก class StringBuffer โดยกาหนดคาเบองตนเปน "Basic String Operations" เราไมสามารถทจะสราง string เหมอนกบทเราสรางดวย class String ได เราตองจองเนอทใหกบตวแปรดวยคาสง new กอน หลงจากนนกกาหนดคาใหกบตวแปรน เราอาจประกาศดวยการประกาศแบบน

Page 131: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 126 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

StringBuffer string = null; string = new StringBuffer("Just another way to declare"); แตไมใชแบบน StringBuffer string = "Just another way to declare"; ขอดของการใช StringBuffer กคอ เราสามารถทจะเปลยนแปลง string ทเราสรางขนได (object จาก class String ทเราใชกอนหนานทาไมได) และเรายงสามารถทจะกาหนดขนาดของ string จาก class StringBuffer ไดตามความพงพอใจของเรา ลองมาดโปรแกรมตวอยางการใช object จาก class StringBuffer กน //StringBufferTest.java import java.io.*; class StringBufferTest { public static void main(String[] args) { //setting up constant string StringBuffer string = new StringBuffer("fish"); System.out.println("string is " + string); //append "er" after "fish" string.append("er"); System.out.println("string is " + string); //append "man" after "fisher" using method insert() string.insert(string.length(), "man"); System.out.println("string is " + string); } } โปรแกรม StringBufferTest.java แสดงการสราง object จาก class StringBuffer ดวยคาสง StringBuffer string = new StringBuffer("fish") จะทาใหคาของ string เปน uiui หลงจากทเราแสดงขอมลทอยใน string แลวเรากนาเอา string "er" มาเชอมเขากบ string "fish" ดวยคาสง string.append("er") จะทาใหคาของ string เปน ทาใหขอความทอยใน string เปลยนเปน "fisher" และหลงจากทเราแสดงผลทไดใหมนไปยงหนาจอ เรากเปลยนขอมลใน string ใหมดวยการนาเอา string "man" มาเชอมเขากบ string ทเราไดกอนหนานดวยการใช method insert() ดงน string.insert(string.length(), "man")

f i s h

f i s h e r

Page 132: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 127 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

จะทาใหคาของ string เปน เราเรยก insert() ดวย parameter 2 ตวคอ 1). ความยาวของ string เดมซงกคอจดเรมตนของการเชอม และ 2). string ตวใหมทเราตองการเชอม คอ "man" เมอ run ดแลวผลลพธทไดคอ string is fish string is fisher string is fisherman เราสามารถทจะเปลยนขนาดของ object ทมาจาก class StringBuffer ไดดงน string.setLength(6) ซงจะทาใหขอมลทอยใน string เปลยนไป หลงจากทเราเปลยนขนาดของ string และเพมประโยคสาหรบการแสดงผลในโปรแกรมของเราใหเปน System.out.println("string after set length is " + string) ผลลพธทเราจะไดจากการ run กจะกลายเปน string after set length is fisher เราไมไดถกจากดใหใสขอมลทเปน string เทานนใน object ทมาจาก class StringBuffer เราสามารถทจะเรยกใช append() หรอ insert() กบขอมลชนดอน ๆ ได เชนโปรแกรมตวอยางตอไปน //StringBufferTest1.java import java.io.*; class StringBufferTest1 { public static void main(String[] args) { //setting up constant string StringBuffer string = new StringBuffer(); string.append(2); System.out.println("string is " + string); //append " fisher" after 2 string.append(" fisher"); System.out.println("string is " + string); //append "men" after "fisher" using method insert() string.insert(string.length(), "men"); System.out.println("string is " + string); string.append(" with "); System.out.println("string is " + string); string.append(100); string.append(" fish."); System.out.println("string is " + string); } }

f i s h e r m a n

Page 133: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 128 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เราไมไดทาอะไรมากมายนกเพยงแตเรยกใช method append() ดวยคาทเปน int เชน string.append(2) หรอ string.append(100) เปนตน Java ยงยอมใหเราเชอมขอมลทมความหลากหลายของชนดของขอมลเขาส object ทมาจาก class StringBuffer ไดโดยไมจากดจานวน ผลลพธของโปรแกรมหลงจากการปรบปรงคอ string is 2 string is 2 fisher string is 2 fishermen string is 2 fishermen with string is 2 fishermen with 100 fish. สวนหนงของ class StringBuffer ทนาสนใจกคอ การกาหนดขนาดใหกบ buffer ทรองรบขอมลใน object ตาง ๆ ทเกดจาก class น นนกคอ Java จะกาหนดขนาดของ buffer ใหเทากบขอมลทมอยใน buffer บวกกบอก 16 ตวอกษรเสมอ เชน ถาเราสราง object StringBuffer name = new StringBuffer("Chiang Mai"); ซงมจานวนตวอกษรทงหมด (นบชองวางดวย) เทากบ 10 ตว Java จะจองเนอทใหมความจเทากบ 26 ตว เราสามารถตรวจสอบความจของ buffer ดวยการเรยกใช method capacity() ได เชน ถาเราสรางประโยคตอไปน StringBuffer s = new StringBuffer("Chaing Mai"); System.out.println("Length of " + s + " is " + s.length()); System.out.println("Capacity of " + s + " is " + s.capacity()); หลงจากการประมวลผล เราจะไดผลลพธดงน Length of Chaing Mai is 10 Capacity of Chaing Mai is 26 ตวอยางตอไปนคงเปนตวอยางสดทายทเราจะแสดงใหเหนถงการใช method อกตวหนงในการเปลยนแปลงขอมลทอยใน string ใหอยในรปแบบของการกลบหวกลบหาง (reverse) //ReverseString.java import java.io.*; class ReverseString { public static void main(String[] args) { //setting up a constant string StringBuffer string = new StringBuffer("I love Chaing Mai"); //create an empty string StringBuffer revStr = new StringBuffer(); revStr.append(string); //append string to revStr revStr.reverse(); //reverse it System.out.println("Reverse of [" + string + "] is [" + revStr + "]"); } } ผลลพธของการ run คอ Reverse of [I love Chaing Mai] is [iaM gniahC evol I]

Page 134: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 129 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

หลงจากทสราง string ดวยคา "I love Chiang Mai" แลวเรากสราง object อกตวหนงโดยไมมการอางถงคาใด ๆ ทงสนดวยคาสง StringBuffer revStr = new StringBuffer() หลงจากนนเราเชอม string เขากบ revStr ดวยการใช method append() เชนเดยวกบตวอยางอน ๆ ทเราไดทามากอนหนาน เสรจจากการเชอมเรากใชคาสง revStr.reverse() เพอทาการ reverse ขอมลทอยใน revStr ทเหลออยกคอการสงผลลพธของการ reverse ไปยงหนาจอ ผอานอาจสงสยวาทาไมเราไมสราง object ดวยการสง string ไปใหกบ revStr ในตอนแรกทเราสราง revStr เชน StringBuffer revStr = new StringBuffer(string) เราทาไมไดเพราะ Java ไดสราง method ในการสราง object จาก class StringBuffer ไวเพยงสามตวคอ 1. StringBuffer() โดยไมใสเงอนไขใด ๆ 2. StringBuffer(int len) ตองใสขนาดของ buffer 3. StringBuffer(String str) ตองใส object จาก class String เทานน ยงม method อกมากมายทเราสามารถนามาใชในงานทเกยวของกบ string แตเราคงไมสามารถพดในทนไดหมด จงเพยงแตหวงวาผอานจะทาการคนควาตอไปเพอความเขาใจในเรองทเกยวของกบ string ตอไป ตารางท 4.2 แสดงถง method ตาง ๆ ของ class StringBuffer ตาราง 4.2 method ของ class StringBuffer method ความหมาย capacity() ความจของ StringBuffer ตวน length() ความยาวของ StringBuffer ตวน setLength(new length) กาหนดความยาวของ StringBuffer ดวยความยาวใหม append(value) เชอมคาเขาทางดานหลงของ StringBuffer ตวน insert(index, value) เพมคาเขาส StringBuffer ณ ตาแหนงทกาหนด replace(start index, end index, String) เปลยนคาตามจดทกาหนด ดวย String delete(start index, end index) ลบคาออกตามจดทกาหนด deleteCharAt(index) ลบตวอกษรตามจดทกาหนด setCharAt(index, character) เปลยนตวอกษร ณ ตาแหนงทกาหนด charAt(index) คาตวอกษร ณ ตาแหนงทกาหนด substring(index) คา substring ตามจดเรมตนทกาหนดจนจบ String substring(start index, end index) คา substring ตามจดทกาหนดเทานน toString() object ทมคาของ String ทอยใน StringBuffer reverse() สลบตวอกษรทกตวใน StringBuffer

การกาหนดใหขอมลของ array เปน string (Array of Strings) เนองจากวา string เปน object ดงนนเราจงสามารถทจะเกบ string ไวใน array ได การจดเกบ string ไวใน array กไมยงยาก กคลาย ๆ กบทเราเกบขอมลชนดอนไวใน array นนเอง มาถงตอนนถาเราลองมองยอนกลบไปดการประกาศ method main() ของเรา เราจะเหนการประกาศแบบน public static void main(String[] args) { … ภายในเครองหมาย () เราจะเหนการประกาศ String [] args ซงเปนการประกาศใหตวแปร args เปนตวแปรทใชเกบ array of strings ซงการประกาศนกเหมอนกบการประกาศ array โดยทวไปเพยงแตเราเปลยนใหการจดเกบขอมลมาเปน string เทานนเอง ลองมาดโปรแกรมตวอยางการสราง array of strings กนด //ArrayOfStrings.java import java.io.*;

Page 135: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 130 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class ArrayOfStrings { public static void main(String[] args) { //declare array of 5 strings String[] names = new String[5]; //initialize array names[0] = "Kafe"; names[1] = "River Side"; names[2] = "Good View"; names[3] = "Cottage"; names[4] = "Club G"; String word = names[2].substring(0, 4); System.out.println("First word from names[2] is " + word); for(int i = 0; i < 5; i++) { System.out.println(names[i]); } } } เราไดประกาศให names เปน array of Strings ทสามารถเกบขอมลไดสงสด 5 ตว ดวยคาสง String[] names = new String[5]; หลงจากนนเรากใสขอมลใหกบตาแหนงตาง ๆ ของ array names และเมอใสครบแลว เราดงเอาคาแรกทอยใน names[2] มาแสดง เมอเสรจแลวเรากแสดงขอมลทงหมดไปยงหนาจอ ดวยการใช for – loop ผลลพธของการ run คอ First word from names[2] is Good Kafe River Side Good View Cottage Club G โปรแกรมตวอยางทเหนเปนโปรแกรมอยางงาย ทเขยนขนมาเพอแสดงการใช array of Strings กระบวนการตาง ๆ ทสามารถทาไดกบ array โดยทวไปกสามารถทาไดกบ array of Strings ดงนนผอานควรยอนกลบไปดเรองของ array ทเราไดพดถง และลองประยกตใชกระบวนการตาง ๆ กบ array of Strings ดเพอใหเกดความเขาใจมากยงขน สรป ในบทนเราไดพดถงการเกบขอมลดวย array การใช String และ StringBuffer รวมไปถงกระบวนการตาง ๆ ทเราสามารถทาไดกบตวแปร หรอ object ตาง ๆ ทเกดจาก class String และ class StringBuffer ผอานควรทาความเขาใจกบ method ตาง ๆ ทเราไดพดถงเพอการนาไปใชอยางมประสทธภาพ จดหลก ๆ ทเราไดพดถง คอ

การสราง array ในการเกบขอมลชนดเดยวกนหลายตวไวในตวแปรตวเดยว การเขาหาขอมลแตละตวใน array ดวยการใช index ขนาดของ array สามารถดงออกมาจากตวแปรคงท length Array สามารถทจะเกบขอมลทเปน array ได เราสราง object ทเปน string จาก class String พรอมทงกาหนดคาทไมสามารถเปลยนแปลงได ขนาดของ string ตองดงออกมาจาก method length() String ม method หลาย ๆ ตวใหเราใชในการจดการกบ string เราสราง string ทสามารถเปลยนแปลงไดจาก class StringBuffer

Page 136: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 131 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

StringBuffer ม method หลายตวทเราเรยกใชในการจดการกบ string ตาง ๆ ขนาดของ string จาก class StringBuffer หาไดจาก method length() และความจของ object ทมาจาก StringBufer หาไดดวยการเรยกใช method capacity()

แบบฝกหด 1. จงเขยนโปรแกรมทรบขอมลทเปน int จาก keyboard จานวน 10 ตว เกบไวใน array พรอมทงหา

คาสงสด คาตาสด จานวนของขอมลทเปนเลขคทงหมด และจานวนของขอมลทเปนเลขคทงหมด 2. จงเขยนโปรแกรมทใช Math.random() ในการสรางขอมลจานวน 100 ตว เกบไวใน array ใหแสดง

ขอมลทงหมดไปยงหนาจอโดยใหมจานวนขอมลเปน 5 แถว ๆ ละ 20 ตว 3. จงเขยนโปรแกรมทสราง array 2 มตขนาด 3 x 3 จานวน 2 ตวทมขอมลเปน int ใหใสขอมลใน

array ดวยการใช Math.random() ทกาหนดใหคาของขอมลทสรางขนอยระหวาง 1 – 9 หลงจากนนใหนาเอา array 2 ตวนมาบวกกน (Matrix addition) เกบผลลพธทงหมดทไดไวใน array ตวทสาม พรอมทงแสดง array ทงสามตวไปยงหนาจอ

4. จงเขยนโปรแกรมทรบ object จาก class String จานวนสามตวจาก keyboard ใหตรวจสอบวา

string ตวไหนใหญทสด และ string ตวไหนเลกทสด แสดงผลลพธไปยงหนาจอ 5. จงเขยนโปรแกรมทใช array เกบ string จานวน 10 ตวทอยในรปแบบของ day/month/year เชน

02/10/00 ใหโปรแกรมตรวจสอบขอมลทอยใน string ทกตว เสรจแลวใหสงผลลพธทงหมดในรปแบบของ 2 October 2000 ไปยงหนาจอ

6. จงเขยนโปรแกรมทใช array ในการเกบ char จานวน 10 ตว ใหทาการ reverse ขอมลทอยใน

array น ผลลพธทไดใหเกบไวใน array ตวเดม 7. จงเขยนโปรแกรมทใช StringBuffer เกบ string จานวน 10 ตว ใหนา string ทงหมดไปเกบไวใน

string ตวใหมโดยให string ทมจานวนของ char นอยอยทางดานหนา และ string ทมจานวนของ char มากอยทางดานหลง (เรยงจากนอยไปหามาก)

8. จงเขยนโปรแกรมทใช array ในการเกบชอของลกคาจานวน 20 ชอ ใหทาการคนหาชอของลกคาทม

ตวอกษรขนตน ตามท user เปนผกาหนดจาก keyboard ใหแสดงชอทกตวทมอกษรขนตนดงกลาวออกทางหนาจอ

9. กาหนดให array1 และ array2 เปน array ทเกบ int จานวนเทากบ 10 ตวโดยท ขอมลของแตละ

array ไดถกจดเรยงใหอยในรปของ มากไปหานอย จงเขยนโปรแกรมทนาเอาขอมลของ array ทงสองตวมารวมกนโดยทยงรกษาคณสมบตของการเรยงจากมากไปหานอย เกบไวใน array ตวใหม แสดงผลลพธของทงสาม array ออกทางหนาจอ

10. จงเขยนโปรแกรมทรบ String 1 ตวทประกอบไปดวย ชอตน และนามสกลทถกแบงดวยชองวาง

(space) เชน Micha Sapporo หลงจากนนใหแบง String ตวนออกเปน 2 ตวใหเปน ชอตน 1 ตว และนามสกล 1 ตว

11. จงปรบปรงโปรแกรมในขอ 10 ใหทาหนาทลบชองวางทอาจนาหนา และตามหลง ชอทนาเขาจาก

keyboard 12. จงเขยนโปรแกรมทรบ String 2 ตวจาก keyboard ใหทาการคนหาวา String ตวทสองมอยใน

String ตวแรกหรอไม ถาม มอยกตว อยทตาแหนงใดบาง 13. จงเขยนโปรแกรมทรบ String 2 ตวจาก keyboard ใหนาเอา String ตวทสองไปใสไวในตาแหนงท

ถกกาหนดจาก user ถาตาแหนงท user กาหนดเปนไปไมไดใหนา String นนไปใสไวดานหลงของ String ตวแรก

14. จงเขยนโปรแกรมททาหนาทดงน

Page 137: Beginning JAVA [Thai]

บทท 4 การใช Array และ String 132 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

รบ String ในรปแบบของ 112 Newell Street, Walla Walla, WA 99210 ทาการตด String ใหอยในรปแบบของ No. 112 Street: Newell Street City: Walla Walla State: WA Zip: 99210

15. จงเขยนโปรแกรมททาการสลบคาทมอยใน String เชน ถา String เปน I love Chiang Mai ผลลพธ

ทไดจากการสลบจะเปน Mai Chiang love I

Page 138: Beginning JAVA [Thai]

เราไดเรยนรถงโครงสรางหลกของการเขยนโปรแกรมโดยทวไปจากบทกอน ๆ เราไดเรยกใช class ตาง ๆ (บาง class) ท Java มใหในการเขยนโปรแกรม รวมไปถงการสราง object จาก class String และ class StringBuffer ในบทนเราจะมาทาความเขาใจในเรองของการสราง class การสราง object จาก class ทเราสรางขน การนาเอา class มาชวยแกโจทยและปญหาทางดานคอมพวเตอร หลงจากจบบทนแลว ผอานจะไดรบทราบในเรองของ

o ความหมายของ class และการสราง class o การสราง constructor o การสราง method o การ overload method o การสราง object จาก class o การใช attribute ตาง ๆ ของ class o การสราง nested class o การสราง และการเรยกใช package

Class และ การสราง class เราไดเหนจากบทกอน ๆ วาเราตองกาหนดโปรแกรมทเราเขยนขนดวยคาวา class เสมอ แตเราไมไดพดถงเลยวา class คออะไร โดยทวไปการเขยนโปรแกรมดวยภาษาทเรยกกนวา Object-Oriented Programming (OOP) นนคาวา class มกจะหมายถงคณลกษณะ หรอคณสมบต (prescription) ของวตถใดวตถหนง (ทเกดจาก class นน ๆ) ซงถาพดแบบภาษาชาวบานทว ๆ ไปเราอาจเรยก class ดงกลาววาเปนแมแบบของ class (อน ๆ ทตามมากได) หรอวาเปนตวกาหนดคณสมบตของ object ทไดถกสรางขน ถาเรามองไปรอบ ๆ ตวเรา เราจะเหนวตถหลากหลายชนด เชน เกาอ keyboard ถวยกาแฟ และอะไรอน ๆ อกมากมาย ซงวตถหลายชนมรปรางหนาตาเหมอนกน มการใชสอยทคลาย หรอ เหมอนกน เชน เกาอมสขา หรอสามขา มพนกพง หรอไมมพนกพง แตการใชงานเหมอนกนคอ เอาไวนง หรออกตวอยางหนง เชน รถยนต มสลอ ขบเคลอนไปไดทงขางหนา และขางหลง ตองใชนามนเปนเชอเพลง มสภายนอกทตางกน แตมคณสมบตทเหมอนกนคอเอาไวเดนทางไปยงทตาง ๆ และโดยทวไปแลวผขบขสวนใหญจะไมรถงการทางานของเครองยนตทอยภายใน รแตเพยงขอมลทจาเปนบางสวน เชนเปดประตอยางไร start เครองยงไง เขาเกยรอยางไร อยางนเปนตน การเขยนโปรแกรมในรปแบบของ OOP กเหมอนกน ถาเราพฒนาโปรแกรมใดสกโปรแกรมหนงใหผอนใช ผใชกลมนนไมจาเปนทจะตองรวาเราเขยนอยางไร ควรรเพยงแตวาจะใชสวนตาง ๆ ทเราเขยนขนอยางไร และนากลบไปใชใหมไดอยางไร (เหมอนเชนทเราเรยกใช method ตาง ๆ จาก class String เราไมรวาเขาเขยน code อยางไร รแตวาใชงานอยางไร) ถามองกลบไปด class String ทเราใชในบททสนน จะเหนวาเราสามารถทจะใช method ตาง ๆ ทมโดยไมมการจากดจานวนครงทใช โปรแกรมตวไหนเรยกใชกได การทางานกยงคงเหมอนเดม ผลลพธของการเรยกใชกเหมอนเดม object ทมาจาก class String ไมวาจะเปนตวไหน เรากสามารถทจะใช method ตาง ๆ กบ object เหลานได ในการออกแบบ class นนโดยทวไปเราตองออกแบบใหเหมาะสมกบงานของเรา เชนถาโปรแกรมของเราตองวนวายกบคนเรากอาจออกแบบให class ของเรามคณสมบตและคณลกษณะ ทเกยวของกบคน เชน มชอ นามสกล ทอย สถานะภาพ อาชพ และอะไรอน ๆ ทานองน โดยทวไปการออกแบบ class นนมสวนประกอบทจาเปน และ สาคญอยสองสวน คอ

Page 139: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 134 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

o Field หมายถงตวแปรสาหรบการเกบขอมลของ object ทบงบอกถงความเหมอน หรอ ความแตกตางกนของ object ทเกดมาจาก class เดยวกน หนงสอหลายเลมเรยก field ทวานวา Data member หรอ สมาชกของ class ทเปนทเกบขอมล หรอทเราเรยกกนจนคนปากวา variable (identifier)

o Method หมายถงกระบวนการ (operation) ตาง ๆ ทเราสามารถทาไดกบ object นน ๆ ของ class

ซงกระบวนการตาง ๆ ททาไดสวนใหญจะกระทากบ data member Field หรอ Data member สามารถทจะกาหนดใหเปนขอมลไดทกชนด รวมไปถงการเปนตวอางอง (reference) ถง object ทมาจาก class อน (เชน ตวแปรทมชนดเปน String หรอ array ทเราไดพดถงกอนหนาน) หรอแมแตกระทงการเปนตวอางองถง class ของมนเอง Method จะประกอบไปดวยชอของ method และชดคาสงตาง ๆ ทตวมนเองมหนาทในการทาตามคณลกษณะทไดถกออกแบบไว ซงโดยสวนใหญจะกระทากบ data member (แตกไมจาเปนเสมอไป เชนในกรณของ method main()) เพอใหเหนภาพชดเจนยงขน เรามาลองออกแบบ class ขนมาสก class หนงทเกยวของกบ Student

ภาพท 5.1 ตวอยางการสราง class Student Class Student ทเราสรางขนประกอบไปดวยสวนประกอบสองสวนดงทไดกลาวไปแลว คอ สวนทเปน data member และสวนทเปน method ซงภายในสวนสองสวนน ยงมสวนประกอบอนอกทมความสาคญตอการออกแบบ และการใช class กอนอนเรามาดสวนประกอบของ data member กน ตวแปรทเปนสมาชกของ class (Class variable และ Instance variable) Object ทเกดมาจาก class นนเราเรยกกนวา instance ของ class และ object นจะมสวนประกอบท class มให คอ ตวแปรตาง ๆ ทอยใน class ตวแปรเหลานจะมขอแตกตางกน คอ อาจเปนตวแปรทเปน class variable และอาจเปนตวแปรทเปน instance variable หลงจากทเราสราง object แลว object จะไดรบ copy ของตวแปรท class มให ซงตวแปรเหลานจะเปนตวบงบอกวา object ตวไหนแตกตางกนอยางไร คาของตวแปรของ object แตละตวจะมคาเหมอนหรอ

class Student { String id; String firstname; String lastName; String dateOfBirth; static int count = 0;

Student(String iden, String fName, … … } public int getCount() { return count; } //method ตวอน ๆ ทเหลออย … … }

Data member

class name

Constructor

Method

Instance variable

Class variable

Parameter list

Page 140: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 135 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

แตกตางกนนนขนอยกบการกาหนดของโปรแกรมเอง เชน ถาเราสราง object สองตวจาก class Student ขนมาใชงาน object สองตวนจะม copy ของตวแปรทงสตวของมนเอง เราเรยกตวแปรเหลานวา instance variable สวนตวแปรอกชนดหนงคอ class variable นนกาหนดไววา object ทกตวทเกดจาก class จะใชตวแปรชนดนรวมกน และตวแปรนสามารถทจะกาหนดและสรางขนมาใชได ถงแมวาจะไมม object เกดขนจาก class นกตาม เพราะวาตวแปรนเปนของ class ดงนนทง class และ object กสามารถทจะใชมนได ถาคาของตวแปรนเปลยนไป object หรอ class ทอางการใชถงตวแปรตวนกจะไดคาใหมทเปลยนไป ซงตรงกนขามกบตวแปรทเปน instance variable ถาหาก object ตวไหนเปลยนคาของตวแปรใด ๆ (copy) คาทเปลยนไปจะไมมผลตอตวแปรใด ๆ ใน object ตวอน การประกาศใหตวแปรใด ๆ กตามเปน class variable นนเราตองใชคาสง static นาหนาตวแปรนนเสมอ ดงทไดแสดงในภาพท 5.2

ภาพท 5.2 การใชตวแปรแบบ class variable และแบบ instance variable ตวแปรทงสองชนดมการใชทแตกตางกน และตางกมความสาคญทงค โดยทวไปการใช class variable นนนยมใชในกรณทเราตองการทจะเกบคาทเปนคาท object ทงหมดตองใชรวมกน เชนคาคงทตาง ๆ ทมความจาเปนใน class นน ๆ ตวอยางของเราใช count เปนตวแปรทใชรวมกนระหวาง object ตาง ๆ สวนตวแปรทเปน instance variable นนมความจาเปนอยางมากในการออกแบบ class ตาง ๆ ทงนเพราะตวแปรชนดนจะเปนผกาหนดความแตกตางระหวาง object ตาง ๆ ทไดถกสรางขนจาก class นน ๆ เชน object จาก class Student ทถกสรางขนอาจม id ทไมเหมอนกน ชอตน และ ชอสกลทแตกตางกน วนเดอนปเกดทไมเหมอนกน อยางนเปนตน ขอแตกตางระหวาง class กบ object class object เปนแมแบบทมสมาชกทง data และ

method ตองเกดมาจาก class ใด class หนง

ไมมตวตนขณะทโปรแกรมกาลง execute มตวตนขณะโปรแกรมกาลง execute ไมมการเปลยนแปลงขณะโปรแกรม execute สามารถเปลยนแปลงคาของ data ขณะ

execute

ทง Joe และ Jon ม copy ของตวแปรเหลาน

Object ทกตว share ตวแปร count

0

class Student { static int count = 0; String id;

String firstname; String lastName; String dateOfBirth;

Joe id

firstNAme lastName

dateOfBirth

Jon id

firstNAme lastName

dateOfBirth

Page 141: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 136 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Method จากแผนภาพท 5.1 เราจะเหนวาม method อยใน class Student ของเรา (บางสวน) method เปนกระบวนการ (ทรวบรวมชดคาสง) ทเราสามารถเรยกใชใหทางานตาง ๆ ใหเรา ซงอาจเปนการทางานทเกยวของกบ ตวแปรทอยใน class หรอกระบวนการอน ๆ ทจาเปนของ class นน ๆ และเชนเดยวกนกบตวแปรทไดกลาวไวกอนหนาน method กไดถกแบงออกเปนสองชนด คอ class method และ instance method Class method กคอ method ทสามารถทจะไดรบการประมวลผลถงแมวาจะไมม object อยเลย ถาเรามองยอนกลบไปด method main() ของเรา เราจะเหนวาไมม object ใด ๆ เกดจาก class ทม method main() อยเลย และการประกาศใช class method กเชนเดยวกนกบ class variable เราตองใชคาสง static นาหนาเสมอ สวน instance method นนเปน method ทตองมการใชรวมกนกบ instance variable ทงนเพราะวา method ประเภทนถกสรางขนมาจาก class เดยวกนกบท object ถกสรางขนมา การกระทาใด ๆ กตามตองทาผาน instance method เทานน การเขาหาตวแปร และ method ของ class ในการทจะเขาหาตวแปรหรอ method ของ class นนไมวาจะเพออะไรกตามแต เราจะตองเขาหาผานทาง object ของ class ตามดวย . (dot) และตามดวยชอของตวแปร หรอ ชอของ method เชน studentA.firstName; หรอ studentB.getAge(); ในตอนนเราจะดเพยงแควธการเขาหา แตตอไปเราจะดเรองการกาหนดนโยบายของการเขาหาตวแปร หรอ method เหลาน ถาม method หรอ ตวแปรอยเรากเขาหาแบบทไดกลาวมาแลว Java จะฟองดวย error ถาหากอางถงตวแปรหรอ method ทไมไดถกสรางขน เพอใหเหนภาพของการสราง class รวมไปถงสวนประกอบตาง ๆ ของ class เรามาด class Student ทไดถกสรางขนเพอเปนตวอยาง //Student.java - Simple class for student import java.lang.Integer; import java.util.Calendar; class Student { String id; //student id String firstName; //student's first name String lastName; //student's last name String dateOfBirth; //student's date of birth in //the form: dd/mm/yyyy static int count = 0; //number of object created //class constructor to initialize fields to given values Student(String iden, String fName, String lName, String dOfB) { id = iden; firstName = fName; lastName = lName; dateOfBirth = dOfB; count++; } //method to return count public int getCount() {

Page 142: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 137 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

return count; } //method to return student's id public String getId() { return id; } //method to returnstudent's first name public String getFirstName() { return firstName; } //method to return student's last name public String getLastName() { return lastName; } //method to return student's date of birth public String getDateOfBirth() { return dateOfBirth; } //method to calculate student's age from //year of birth public int getAge() { //retrieve a year String year = dateOfBirth.substring(6); //convert it to an int int birthYear = Integer.parseInt(year); //get current year from system's calendar Calendar now = Calendar.getInstance(); int thisYear = now.get(Calendar.YEAR); //return the difference return thisYear - birthYear; } //method to display students' info to screen public void display() { System.out.print(getId() + " "); System.out.print(getFirstName() + " "); System.out.print(getLastName() + " "); System.out.println("Age: " + getAge()); } } เราไดกาหนดให class Student ม field อยทงหมด 5 field คอ id, firstName, lastname, dateOfBirth, และ count โดยทสตวแรกเปน instance variable ทเอาไวเกบขอมลโดยเฉพาะของ object แตละตวทไดถกสรางขน และตวสดทายเปน class variable ทเอาไวเกบจานวนของ object ทไดถกสรางขน เรายงไดสราง method อก 7 ตวซงมหนาทในการทางานทตางกน โดยเฉพาะ method ทมชอเหมอนกนกบ class นนกคอ method Student Student(String iden, String fName, String lName, String dOfB) { id = iden; firstName = fName; lastName = lName;

Page 143: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 138 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

dateOfBirth = dOfB; count++; } Student() เปน method พเศษทมชอเรยกกนโดยทวไปวาเปน constructor ของ class ซง constructor นสวนใหญจะทาหนาทในการกาหนดคาเบองตนใหกบ object ทไดถกสรางขนจาก class เชน กาหนดคาใหกบ field ทก field หรอบาง field (ทงนตองแลวแตการออกแบบการทางานของ constructor นน ๆ) ตวอยางของเรากาหนดให constructor ทาการกาหนดคาใหกบ field ทก field (ยกเวน class variable ทชอ count) ใหมคาเปนไปตามคาทไดรบเขามาจากตวแปรทอยใน parameter list แต constructor จะมคณสมบตพเศษคอ การกาหนดคานนจะไดรบการกระทาโดยอตโนมต เราไมตองเรยกใช constructor การเรยกใช constructor น Java จะเปนผเรยกใหในตอนทเราสราง object ขนมา กอนทเราจะพดถง constructor และการถกเรยกใชงานโดยอตโนมตนนเรามาดกนถง method และ วธการสราง method รวมไปถงการสงคาใหกบ method และการสงคากลบของ method การสราง method ในการสราง method นนเราจะตองกาหนดชอใหกบ method กาหนด parameter (ถาม) กาหนดการสงคากลบของ method (ถาม) โดยทวไป method ไดถกแบงออกเปนสองแบบ คอ

o Method ทสงคากลบใหแกผทเรยกใช method o Method ทไมมการสงคาใด ๆ กลบไปใหผเรยก

โครงสรางของ method โดยทวไปจะมรปแบบดงน

ภาพท 5.3 การสราง method เราลองหยบเอา method getAge() จาก class Student มาดกนเพอใหเกดความเขาใจในเรองสวนประกอบตาง ๆ ทมอยใน method ทวาน public int getAge() { String year = dateOfBirth.substring(6); int birthYear = Integer.parseInt(year);

ชนดของคาทสงกลบ ชอของ method Parameter (ถาม)

ชดคาสงตาง ๆ ท method ตวนมอย (body of method)

returnType methodName( arg1, arg2, …, argn ) { // body of method … … }

ชนดของคาทสงกลบ เปนชนดไหนกได ใชคาสง void ถาไมมคาทตองสงกลบ

Page 144: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 139 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Calendar now = Calendar.getInstance(); int thisYear = now.get(Calendar.YEAR); return thisYear - birthYear; } ถาเราแยกสวนประกอบตาง ๆ ออก เรากจะไดขอมลดงน ชนดของคาทสงกลบ int ชอของ method คอ getAge Parameter ไมม ชดคาสงคอ String year = dateOfBirth.substring(6); int birthYear = Integer.parseInt(year); Calendar now = Calendar.getInstance(); int thisYear = now.get(Calendar.YEAR); return thisYear - birthYear; ถาสงเกตใหดจะเหนวาดานหนาสดของ method getAge() จะมคาวา public อย คาวา public นจะเปนตวกาหนดนโยบายการเขาหา method ซงเราจะไดพดถงในตอนตอไป แตตอนนเราจะดเฉพาะสวนประกอบโดยทวไปท method ตองม สวนประกอบทสาคญอกสวนหนงกคอ คาวา return ในบรรทดสดทาย เนองจากวา method getAge() ของเราตองสงคากลบ ดงนนเราจงจาเปนทจะตองบอกให Java รวาเรามคาทตองการสงกลบ ดงทไดประกาศไว ถาหากวาเราไมมการใช return พรอมทงคาทตองการสงกลบ Java กจะฟองดวย error ตอนทเรา compile โปรแกรม เรามาลองด method ทไมมการสงคากลบใน class Student ของเรา ซงมอยเพยงตวเดยว คอ public void display() { System.out.print(getId() + " "); System.out.print(getFirstName() + " "); System.out.print(getLastName() + " "); System.out.println("Age: " + getAge()); } ชนดของคาทสงกลบ ไมม ชอของ method คอ display Parameter ไมม ชดคาสงคอ System.out.print(getId() + " "); System.out.print(getFirstName() + " "); System.out.print(getLastName() + " "); System.out.println("Age: " + getAge()); Method display() ทาหนาทเปนเพยงตวแสดงขอมลของ object ทเกดจาก class Student ออกทางหนาจอ โดยการเรยกใช method อน ๆ ทมอยใน class Student การทจะให method ไมตองสงคากลบนนเราตองใช คาวา void นาหนาชอ method เสมอ และ method ทมคาวา void นาหนาตองไมมคาวา return ใด ๆ ทมคาในการสงกลบ ยกเวนคาวา return ทตามดวย ; (semicolon) เทานน เชนถาเราใช void เรากสามารถทจะใช return ตามดวย ; หรอไมใชเลย อยางใด อยางหนง เพราะฉะนน method display() ทเหนกสามารถทจะเขยนไดอกแบบหนงดงน public void display() { System.out.print(getId() + " "); System.out.print(getFirstName() + " "); System.out.print(getLastName() + " "); System.out.println("Age: " + getAge());

Page 145: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 140 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

return ; } ขอแตกตางระหวาง method ทสงคา และ method ทไมสงคา method ทสงคา method ทไมสงคา มคาวา return และ คาทตองสงกลบ ไมจาเปนตองมคาวา return แตถามจะตอง

ตามดวย ; อยางเดยวเทานน ขนตน method ดวยชนดของขอมลทตองสงกลบ

ขนตน method ดวยคาวา void เสมอ

กระบวนการทเกดขนเมอมการใช parameter list เราลองมาดโปรแกรมตวอยางทมการสราง method ทมการใช parameter list กอนทเราจะกลบมาด class Student อกครงหนง //Parameters.java class Parameters { public static void main(String[] args) { double radius = 2.0; double area = findArea(radius); System.out.println("Area of a circle is : " + area); } public static double findArea(double r) { return Math.PI * r * r; } } โปรแกรม Parameters.java สราง method ทเราเรยกวา class method ขนมาใชงานหนงตว (การประกาศให method เปน class method กเหมอนกบการประกาศใหตวแปรเปน class variable เราตองใชคาวา static นาหนา) ซง method นมหนาทในการคานวณหาพนทของวงกลมทมรศมทกาหนดไวในตวโปรแกรม (ในทนคอ 2) method findArea() ม Parameter หนงตวทมชนดเปน double และจะสงคาของพนททคานวณไดกลบไปใหผเรยก ซงในทนคอ class Parameters การเรยก method findArea(() นนเราเรยกดวยประโยค double area = findArea(radius); ซงเมอ Java เหนการเรยกเชนน Java กจะไป execute method findArea() ดวย parameter ทมชนดเปน double และสงคา 2.0 ไปให หลงจากทคานวณคาพนทไดแลวกจะสงกลบออกมา และนาไปเกบไวในตวแปรชอ area ภาพท 5.4 แสดงการสงคาผานทาง parameter list

Page 146: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 141 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ภาพท 5.4 การสง parameter ใหกบ method และการสงคากลบออกจาก method การสงคาผานทางตวแปรทอยใน parameter list นนมอยสองแบบคอ 1) การสงทเรยกวา pass-by-value หรอการสงเฉพาะคาเขาไปใน method นน ๆ และ 2) การสงแบบทเรยกวา pass-by-reference ในการสงคาทเปน primitive type นน Java จะกาหนดใหการสงเปนแบบ pass-by-value เทานน ซงไดแสดงไวในภาพท 5.5

ภาพท 5.5 การสงคาแบบ pass-by-value ตวแปร total ทอยใน method main() นนจะไมไดรบผลกระทบจากการเปลยนคา ทเกดขนภายใน method increment() ทงนกเพราะวา กระบวนการทเกดขนไมไดกระทากบตวแปร total แตเปนการกระทากบ copy ของ total

class Parameters { public static void main(String[] args) { double radius = 2.0; double area = findArea(radius); … … } … …

public static double findArea(double r) { return Math.PI * r * r; }

คาทไดจากการคานวณจะถกสงไปให ตวแปร area

คาของ radius จะถกสงเขามาไวในตวแปร r

ชนดของคาทสงกลบออกมา ตองเปนชนดเดยวกน

class PassByValue { public static void main(String[] args) { int total = 10; … … int newTotal = increment(total); … } …

public static int increment(int sum) { sum += 10; return sum; }

total

10

10

copy ของ total

การประมวลผลทากบ copy ของ

total

ตวแปร sum อางถง copy ของ total ทอยใน

main()

Page 147: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 142 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การสงคาไปยง method แบบ pass-by-value นคาทสงเขาไปจะถกนาไปใชภายในตว method เทานน การเปลยนแปลงใด ๆ ทเกดขนจะไมมผลกระทบกบตวแปรทเปนเจาของคานน ภายนอก method เลย ซงตรงกนขามกบ การสงคาในแบบทเรยกวา pass-by-reference ลองมาดตวอยางโปรแกรมการสงคาแบบ pass-by-value กน //PassByValue.java class PassByValue { public static void main(String[] args) { int total = 10; System.out.println("Before calling: total is " + total); System.out.println("Value returns from increment() is " + increment(total)); System.out.println("After calling: total is " + total); } public static int increment(int sum) { sum += 10; return sum; } } ผลลพธทไดจากการ run คอ Before calling: total is 10 Value returns from increment() is 20 After calling: total is 10 increment() ถกเรยกภายใน main() จากประโยค System.out.println("Value returns from increment() is " + increment(total)); ซงมการสงคาของ total ไปให (ซงมคาเปน 10) คานถกนาไปใชใน increment() ผานทางตวแปรทชอวา sum ภายใน increment() ตวแปร sum ถกเปลยนคาดวยการนาเอา 10 ไปบวกเพม ทาให sum มคาเปน 20 ซงคานจะถกสงกลบไปยง main() ทาใหการแสดงผลทางหนาจอมคาเปน 20 แตหลงจากนน เรากาหนดใหมการแสดงคาของ total อกครงหนง ซงผลลพธทไดคอคาของ total ยงคงเปน 10 อย จะเหนวาคาของ total ทไดรบการเปลยนแปลงภายใน increment() (ผานทางตวแปร sum) ไมมผลตอตวแปร total อยางใดเลย การเปลยนแปลงเกดและตายภายใน increment() เทานน เรามาลองดโปรแกรมตวอยางอกโปรแกรมหนง //PassByValue2.java class PassByValue2 { public static void main(String[] args) { String myString = "Business Computers"; System.out.println("Before string is: " + myString); changeString(myString); //calling changeString() System.out.println("After myString is: " + myString); } public static void changeString(String string) { System.out.print("\tInside changeString(), "); System.out.println("myString is: " + string); string = "at Far Eastern College";

Page 148: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 143 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} } โปรแกรม PassByValue2.java สราง string หนงตวมขอความวา "Business Computers" และสง string นไปให method changeString() ซงทาหนาทในการเปลยนคาของ string ทสงเขามาใหเปน "at Far Eastern College" แตหลงจากทเรา run โปรแกรมด เรากไดผลลพธตามทเหนดานลางน Before string is: Business Computers Inside changeString(), myString is: Business Computers After myString is: Business Computers จะเหนวาการเปลยนแปลงคาของ string ทสงผานเขามานนจะเปนเพยงการเปลยนแปลงแบบชวคราวเทานน การเปลยนแปลงเกดขนภายใน changeString() และไมมผลกระทบใด ๆ กบคาของตวแปร myString แตอยางใดเลย การสงคาแบบอางอง pass-by-reference การสงคาแบบ pass-by-reference นน สงทเราสงเขาไปใน method นนไมใชคาของตวแปร แตเปนตวอางองถงตวแปร หรอ object นน ๆ โดยตรง เราอาจพดไดวาสงทเราสงไปนนเปนทอย หรอ address ของตวแปร หรอ object นน ๆ กได เรามาลองดตวอยางการสงแบบ pass-by-reference กนในภาพท 5.6

ภาพท 5.6 การสงแบบ pass-by-reference ตวอยางการสงแบบ pass-by-reference ทเหนในภาพท 5.6 นนเราสราง object จาก class Circle หนงตว โดยใหมชอวา red และม radius เทากบ 5.0 เราเรยก method change() ผานทาง object red ดวยการสง object red และคาใหมของ radius ไปให เมอ method change() ถกเรยกดวย parameter ดงกลาว Java จะทาการสราง copy ใหกบ red และจดเกบ copy นไวท c เนองจากวาทง red และ c ตางกอางถง object ตวเดยวกน ดงนนการเปลยนแปลงใด ๆ ทเกดขนยอมมผลกระทบตอ object ตวเดมททง red และ copy ของ red อางถง (หรอเปนตวแทนอย) เราไดสราง method changeRadius() ขนมาเพอใชในการเปลยนคาของ radius ซง code ทงหมดของโปรแกรมตวน มดงน

copy of red

สราง copy ของ red

c อางถง copy ของ

red

copy made

public static void main(String[] args) {

Circle red = new Circle(5.0); … … … red.change(red, 2.0); …

public Circle change(Circle c, double radius) { c.changeRadius(radius);

return c; }

reference reference

Radius: 5.0

red

Circle object

ประโยค c.changeRadius(radius) ทาการเปลยนแปลงขอมลของ object เดมผานทาง

copy ของ red

ทง red และ copy ของ red ตางกอางถง object เดม

Page 149: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 144 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//PassByReference.java //a Circle class to demonstrate pass-by-reference scheme class Circle { private double radius; //a radius of a circle //constructor to initialize radius Circle(double r) { radius = r; } //method to calculate area of a circle public double area() { return Math.PI * radius * radius; } //a method to change radius of a given circle public Circle change(Circle c, double radius) { c.changeRadius(radius); //calling method changeRadius() return c; //with a given radius } //a method to change a given radius private void changeRadius(double r) { radius = r; } //a method to return radius public double getRadius() { return radius; } } //a class to test pass-by-reference scheme class PassByReference { public static void main(String[] args) { //create a red circle with a radius of 5.0; Circle red = new Circle(5.0); //calculate area of a red circle double area = red.area(); System.out.println("Radius of red circle is " + red.getRadius()); System.out.println("Area of red circle is " + area); //change radius of a red circle red.change(red, 2.0); area = red.area(); System.out.println("Radius of red circle now is " + red.getRadius()); System.out.println("Area of red circle now is " + area); } } เราม class อยสอง class โดยท class ตวแรก หรอ class Circle เปน class ทเอาไวใชสรางวงกลม ตาง ๆ รวมไปถง method หรอกระบวนการตาง ๆ ทเราตองการใชในการเปลยนแปลง หรอกาหนดคาใหกบ

Page 150: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 145 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

วงกลมนน ๆ สวน class ตวทสองเปน class ทใชสาหรบการทดสอบ การสราง object จาก class Circle และตรวจสอบการสงคาแบบ pass-by-reference หลงจากททดลอง run เรากไดผลลพธดงน Radius of red circle is 5.0 Area of red circle is 78.53981633974483 Radius of red circle now is 2.0 Area of red circle now is 12.566370614359172 จากผลลพธเราจะเหนวาประโยคทแสดงคาของ radius นนแสดงคาไดถกตองทงกอน และหลงการเปลยนแปลงคาของ radius สงทเราตองจาไวในเรองของการสงคาใหกบ method กคอ การสงคาทเปน primitive type เชน int หรอ double นน method จะไดรบแตเพยงคาเทานน การเปลยนแปลงใด ๆ ภายใน method จะไมมผลกระทบตอตวแปรดานนอก แตถาเราสง object ไปให method การเปลยนแปลงทเกดขนภายใน method (ตอตวแทนของ object นน ๆ) จะมผลกระทบตอ object ทอยภายนอกดวย สมมตวาเราตองการทจะทาการสลบคาของตวแปรสองตว ผานทาง method เราจะทาอยางไร? เรามาลองดตวอยางแรกกนกอนวาจะทาใหเราไดหรอไม //Swap.java import java.io.*; class Values { int val1; int val2; //default constructor Values() { val1 = val2 = 0; } //assignment constructor Values(int a, int b) { val1 = a; val2 = b; } //display val1 and val2 public void show() { System.out.println("(" + val1 + ", " + val2 + ")"); } } class Swap { public static void main(String[] args) { //create two objects from Values Values obj1 = new Values(10, 20); Values obj2 = new Values(30, 50); obj1.show(); //display values of obj1 obj2.show(); //display values of obj2 swap(obj1, obj2); //swap contents of obj1 and obj2 obj1.show(); obj2.show();

Page 151: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 146 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} //swapping contents of given objects private static void swap(Values pointA, Values pointB) { Values temp = new Values(); temp = pointA; //copy pointA to temp pointA = pointB; //copy pointB to pointA pointB = temp; //copy temp to pointB } } เรากาหนดใหการสลบคาของ object ทงสองเกดขนภายใน swap() ซงเราคดวานาจะทาได 100% แตหลงจากท run โปรแกรมด เรากลบไดผลลพธดงน (10, 20) (30, 50) (10, 20) (30, 50) ซงบอกใหเรารวา swap() ของเราใชไมได เราตองเปลยนแปลง code ของ swap() ใหมเพอใหการสลบเกดขนจรง และหลงจากทเราเปลยน code ใหเปน private static void swap(Values pointA, Values pointB) { Values temp = new Values(); temp.val1 = pointA.val1; temp.val2 = pointA.val2; pointA.val1 = pointB.val1; pointA.val2 = pointB.val2; pointB.val1 = temp.val1; pointB.val2 = temp.val2; } ผลลพธทเราไดคอ (10, 20) (30, 50) (30, 50) (10, 20) ซงแสดงถงการสลบคาทไดผลจรง สาเหตท swap() ตวแรกของเราทางานไมได กเนองจากวา การเปลยนแปลงคาของ object เกดขนจาก copy ของ object ทงสองทมาจาก parameter ไมใชตว object จรง ๆ ดงนนการเปลยนแปลงทเกดขนจงเกดขนภายในตว swap() ไมมผลกระทบใด ๆ กบ object ภายนอกเลย เราตองทาการเปลยนคาใหกบสมาชกทอยใน object นนโดยตรงดงเชนท swap() ตวทสองไดแสดงไว เราไดพดถง class Student ทเราสรางคางไวโดยเราไดสารวจ การสราง method ตาง ๆ รวมไปถงการสงคาเขาส method ตอนนเราจะมาดถงรายละเอยดของ method ตาง ๆ ทมอยใน class Student รวมไปถงโปรแกรมทเรยกใช object ทเกดจาก class Student กอนทเราจะพดถง method ทมอยใน class Student เรามาดตวโปรแกรมทเรยกใช method เหลานด //TestStudent.java

Page 152: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 147 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class TestStudent { public static void main(String[] args) { //create two student objects with given info. Student stu1 = new Student("19757", "Jim", "Jones", "02/10/1962"); Student stu2 = new Student("20135", "Ray", "Smith", "12/09/1977"); //display each student's info. stu1.display(); stu2.display(); //display total number of students System.out.println("Total number of objects created: " + stu1.getCount()); //access field in class via object String date = stu1.dateOfBirth; System.out.println("Date of birth of stu1 is " + date); } } เราไดสราง object stu1 และ stu2 จาก class Student ดวยขอมลดงทเหน Student stu1 = new Student("19757", "Jim", "Jones", "02/10/1962") Student stu2 = new Student("20135", "Ray", "Smith", "12/09/1977") หลงจากนนเรากเรยกใช method display() ในการแสดงผลขอมลของ object ทงสองตว โดยทเราไดออกแบบ method display() ของเราใหมการเรยกใช method อน ๆ ทมอยใน class Student ดงน public void display() { System.out.print(getId() + " "); System.out.print(getFirstName() + " "); System.out.print(getLastName() + " "); System.out.println("Age: " + getAge()); return ; } ผอานจะสงเกตไดวาเราเรยก method getId() getFirstName() getLastName() และ method getAge() ภายในประโยคของ System.out.println(…) ซง method เหลานจะสงคาของ field ตาง ๆ ทไดถกกาหนดไวใหกบประโยคในการแสดงขอมลไปยงหนาจอ หลงจากทขอมลของ object ทงสองตวไดถกแสดงไปยงหนาจอแลว เรากเรยกประโยค System.out.println("Total number of objects created: " + stu1.getCount()); String date = stu1.dateOfBirth; System.out.println("Date of birth of stu1 is " + date); สาหรบการแสดงจานวนของ object ทไดถกสรางขนทงหมด และวน เดอน ป เกดของ object ทชอ stu1 ไปยงหนาจอ และผลลพธของการ run ทไดคอ 19757 Jim Jones Age: 41 20135 Ray Smith Age: 26 Total number of objects created: 2 Date of birth of stu1 is 02/10/1962

Page 153: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 148 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ผอานตองกาหนดใหการเรยก method ทมอยใน class ผานทาง object ทไดสรางขน ดวยการใช . (dot) ตามดวยชอของ method ทตองการเรยกใช เชน stu1.display(); เชนเดยวกนกบการเรยกใช data member เรากตองขนตนดวยชอของ object ตามดวย . (dot) ตามดวย ตวแปรทตองการใช เชน stu1.dateOfBirth; เนองจากวาเราไมไดกาหนดนโยบายการเขาหา ตวแปร หรอ method ทมอยใน class ดงนนการเขาหาจงไมขอกาหนดใด ๆ เราสามารถทจะเขาหาขอมลทกตวโดยไมมขอจากด กอนทเราจะพดถงนโยบายการเขาหาขอมลทอยใน class เราอยากทจะพดถง method getAge() ทมอยใน class Student สกเลกนอย method getAge() ไดถกออกแบบใหทาการคานวณหาอายดวยการหาจากการลบปเกด ออกจากปปจจบน ดงนนเราจงตองเรยกใช method จาก class Calendar ในการคานวณหาปปจจบน ดงน public int getAge() { //retrieve a year String year = dateOfBirth.substring(6); //convert it to an int int birthYear = Integer.parseInt(year); //get current year from system's calendar Calendar now = Calendar.getInstance(); int thisYear = now.get(Calendar.YEAR); //return the difference return thisYear - birthYear; } กอนทเราจะคานวณหาอายได เราตองดงเอา field ทเปนปเกดทอยในรปแบบของ dd/mm/yyyy ออกมากอนดวยการใช method substring() ทเราไดพดไวกอนหนาน เมอไดแลวเรากเปลยน string ทมคาเปนปเกดนใหเปน int ดวยการเรยกใช Integer.parseInt() หลงจากนนเรากดงเอาปปจจบนออกจากเครองดวยคาสง Calendar now = Calendar.getInstance(); int thisYear = now.get(Calendar.YEAR); ซงกอนทเราจะดงปออกไดเราตองสราง instance จาก class Calendar กอนและเมอไดแลวเรากใช method get() ในการดงเอาปปจจบนออกมา กระบวนการทเหลออยกคอการสงสวนตางระหวางปปจจบน กบปเกดออกไปยงผทเรยกใช method น (การดงเอาคาของปออก ผอานตองระวงในเรองของปทใชในเครอง ณ เวลานนดวยวาอยในรปแบบของ พทธศกราช หรอ ครสตศกราช Windows ใหม ๆ ยอมใหมการตงคาตามตาแหนงทตงของประเทศนน ๆ) การสราง class Student ของเรานนเราไมไดกาหนดนโยบายการเขาหา field หรอ method ตาง ๆ ของเราอยางไรเลย ผอานคงสงเกตเหนวา ตวแปรทกตวของเราไมมคาใด ๆ นาหนาเลย เชน private public หรอแมกระทงคาวา protected หวขอตอไปจะพดถงเรองของการกาหนดนโยบายการเขาหาตวแปร และ method ของ class วาจะมประโยชนอยางไรในการออกแบบ class (ผอานลองตงคาถามใหตวเองกอนเรมหวขอถดไปวา ถาใสคาวา private หนาตวแปรทกตวจะมผลตอโปรแกรม TestStudent.java อยางไร ถาใสหนา method ตาง ๆ หละ?)

Page 154: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 149 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การกาหนดนโยบายในการเขาหาสมาชกของ class (attributes) จาก class Circle ของเราทไดสรางขน ในการประกาศตวแปร radius นนเราไดกาหนดใหมคาวา private อยดานหนาของตวแปร ดงน private double radius; ทาไมเราถงทาเชนน? สาเหตทเราทาเชนนกเพอทจะกาหนดการเขาหาตวแปรตวน โดยทวไปแลวถาเราไมใสคาวา private ไวหนาตวแปรใด เรากสามารถทจะเขาหาตวแปรตวน ผานทางโปรแกรมอน ๆ ทเรยกใช class Circle การกาหนดนโยบายของการเขาหานน เราสามารถทาไดสวธ คอ 1. ไมใชคาใด ๆ นาหนาตวแปร (friendly) 2. ใชคาวา private นาหนาตวแปร (not too friendly) 3. ใชคาวา public นาหนาตวแปร (friendly) 4. ใชคาวา protected นาหนาตวแปร (somewhat friendly) ถาเราไมใชคาใด ๆ นาหนาตวแปรการเขาหาตวแปรตวนจะทาไดเฉพาะ class ทอยภายในพนทเดยวกน เชนภายใน class เดยวกน หรอภายใน package (ดเรองการสรางและใช package ทายบท) เดยวกน ดงโปรแกรมตวอยางทแสดงใหดน //Access.java class Dot { //no access control String name; int value; Dot(String s, int v) { name = s; value = v; } } class Access { public static void main(String[] args) { Dot myDot = new Dot("I am a dot.", 10); //access both name and value fields from class Dot System.out.println("Name is " + myDot.name); System.out.println("Value is " + myDot.value); } } เมอเรา run ดผลลพธทไดคอ Name is I am a dot. Value is 10 โปรแกรม Access.java สามารถทจะเขาหา field ทงสองทเราสรางขนใน class Dot ของเราผานทาง object ชอ myDot (หมายความวาใคร ๆ กเขาหาตวแปรของเราไดถาเขารวาเรามตวแปรอะไรบาง – อนตราย?) ทนเราลองนาเอาคาวา private ไปใสไวหนาตวแปรทงสองของเรา ดงน private String name;

Page 155: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 150 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

private int value; การ compile โปรแกรมอกครงหนงจะทาใหเกด error ดงน Access.java:20: name has private access in Dot System.out.println("Name is " + myDot.name); ^ Access.java:21: value has private access in Dot System.out.println("Value is " + myDot.value); ^ 2 errors เราไมสามารถทจะอางถงตวแปรทงสองไดเพราะคาวา private เราตองเขาหาดวยวธอน เชน เขยน method ทสงคาของตวแปรทงสองกลบ (โดยเขยนไวใน class Dot) เหมอนกบทเราไดทาไวใน class Circle เรากาหนดใหตวแปร radius ของ class Circle เปน private data member ดงนนเราจงตองเขยน method ในการเขาหาตวแปร radius ของเรา ดงน public double getRadius() { return radius; } เพราะฉะนนถาเราไมตองการใหโปรแกรม หรอ ผใด (object) เขาหาตวแปรของเรา เรากนาคาวา private ไปแปะไวดานหนาของตวแปรนน ๆ ถาสงเกตใหดจะเหนวา method changeRadius() ใน class Circle กมคาวา private อยดานหนาเหมอนกน ทงนกเพราะวาเราไมตองการใหใครเขาหา method ตวนยกเวน method ทอยภายใน class เดยวกน การเขาหา method นผานโปรแกรม หรอ object ตวอนจะทาไมได และ Java compiler จะฟองดวย error ทนท เราจะกลบมาดคาวา protected ในโอกาสตอไป ทงนเพราะคา ๆ นมเงอนไขซบซอนอยพอสมควร สาหรบคาวา public นนจะยอมใหทกโปรแกรม หรอ object เขาหาตวแปร หรอ method ไดโดยไมมเงอนไขใด ๆ ทงสน การกาหนดนโยบายการเขาหาตวแปรหรอ method ทาใหการควบคมโปรแกรมทาไดดยงขน อะไรทผใชไมควรรไมควรเหน เรากซอนสงเหลานไว การกระทาในลกษณะนเราเรยกวา encapsulation ซงเปนหนงในขอกาหนดของการออกแบบและเขยนโปรแกรมในรปแบบของ OOP ในสวนตวของผเขยนแลว ชอบทจะใช private กบตวแปรทกตว และ method บางตวทไมมการเขาหาจากภายนอก เพราะจะทาใหการใชตวแปรมขอจากด สวนทเขาหาขอมลเหลานของเราไดเปนไดเฉพาะ method ทเราไดกาหนดไวเทานน Constructor อกครง Constructor มไวสาหรบการกาหนดคาเบองตนใหกบตวแปรทอยใน class และการเรยกใช constructor นนเราไมตองทาโดยตรง constructor จะถกเรยกโดยอตโนมตผานทางการสราง object จาก class ดงทไดแสดงไวในโปแกรมทสราง object จาก class Circle จากประโยคของการสรางวงกลมทวา Circle red = new Circle(5.0); ขนตอนทเกดขนเมอประโยคนถก execute คอ Constructor ของ Circle ถกเรยกดวยคา 5.0 ซงหมายความวาตวแปร radius ทอยใน class Circle จะไดรบคาทกาหนดให คอ 5.0 หลงจากนนตาแหนง หรอ address ของ object ทถกสรางและกาหนดคานจะถกเกบไวใน red เพอใหเหนภาพชดขน เราจะเพมประโยคดานลางนเขากบ constructor ของ class Circle System.out.println("Constructor activated with parameter value of " + radius);

Page 156: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 151 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เพราะฉะนน constructor ของ class Circle กจะเปน Circle(double r) { radius = r; System.out.println("Constructor activated with value of " + radius); } และเราจะลองสราง object สองตวจาก class Circle ดงน class PassByReference { public static void main(String[] args) { Circle red = new Circle(5.0); Circle blue = new Circle(3.5); } หลงจากท compile และ run ผลลพธทไดคอ Constructor activated with value of 5.0 Constructor activated with value of 3.5 เราจะเหนวา object สองตวถกสรางดวย radius ทตางกน คอ 5.0 และ 3.5 และทง ๆ ทไมมประโยคของการแสดงผลใน method main() ใด ๆ เลย เรากลบไดผลลพธดงทเหน ทงนกเพราะวา constructor ของเราทมอยใน class Circle ไดรบการเรยกใชโดยอตโนมต เราสามารถทจะสราง constructor ใหกบ class ไดมากกวาหนงตวทงนการกระทาดงกลาวจะตองอยภายใตเงอนไขท Java กาหนดไว คอ parameter ทสงไปยง constructor ตองไมมจานวนทเทากน และ ถาจานวนของ parameter เทากน ชนดของ parameter ตองไมเหมอนกน (หนงสอเกอบทกเลมเรยกขนตอนนวาการกาหนด signature) ลองดโปรแกรมตวอยาง //TestMean.java class Mean { private double x, y, z; //constructor with one value Mean(double value) { x = value; y = 0.0; z = 0.0; } //constructor with two values Mean(double value1, double value2) { x = value1; y = value2; z = 0.0; } //constructor with three values Mean(double value1, double value2, double value3) { x = value1; y = value2; z = value3; }

Page 157: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 152 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public double findMean() { return (x + y + z) / 3; } } class Mean ของเราม constructor อยสามตว โดยทตวแรกม parameter หนงตว constructor ตวทสองม parameter สองตว และ constructor ตวทสามม parameter สามตว ภายใน class เราไดสราง method findMean() สาหรบการคานวณหาคาเฉลยของตวแปรทงสามของ class และเราไดเขยนโปรแกรมสาหรบตรวจสอบการใช constructor ดงกลาวดงน class TestMean { public static void main(String[] args) { //create objects with diferent parameters Mean m = new Mean(12.0); Mean n = new Mean(10.0, 20.0); Mean p = new Mean(10.0, 20.0, 30.0); System.out.println("Mean of m is " + m.findMean()); System.out.println("Mean of n is " + n.findMean()); System.out.println("Mean of p is " + p.findMean()); } }

โปรแกรม TestMean.java ประกาศใช object จาก class Mean สามตวดวยจานวนของ parameter ทตางกน คอ หนงตว สองตว และสามตวตามลาดบ หลงจากทเราเรยก method findMean() สาหรบ object ทงสามตวแลว ผลลพธทเราไดจากการ run คอ Mean of m is 4.0 Mean of n is 10.0 Mean of p is 20.0 จะเหนวา Java เลอกใช constructor ไดถกตองตามการออกแบบทเรากาหนดไว ซงวธการแบบนเราเรยกวา constructor overloading เรามาลองดการ overload ของ constructor ทมจานวนของ parameter เหมอนกนแตตางชนดกนด อกสกตวอยางหนง //TestMean1.java class Mean { private double x, y, z; //constructor with three values Mean(double value1, double value2, double value3 { x = value1; y = value2; z = value3; } //constructor with three values (different type) Mean(double value1, int value2, String value3) { x = value1; y = (double)value2; z = Double.parseDouble(value3); } public double findMean() { return (x + y + z) / 3; } }

Page 158: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 153 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class Mean ของเรากาหนดใหม constructor สองตว โดยกาหนดใหตวแรกรบ parameter ทเปน double ทงสามตว สวน constructor ตวทสองรบ parameter ทเปน double int และ String ตามลาดบ ซงเราไดเปลยนคาทไมใช double ของทงสอง parameter ใหเปน double ภายในตว constructor เอง class TestMean1 { public static void main(String[] args) { //create objects with diferent parameters Mean p = new Mean(10.0, 20.0, 30.0); Mean q = new Mean(10.0, 20, "40.0"); System.out.println("Mean of p is " + p.findMean()); System.out.println("Mean of q is " + q.findMean()); } } โปรแกรม TestMean1.java ประกาศการใช object สองตวคอ p และ q จาก class Mean ดวย parameter ตางกนดงทเหน ผลลพธทไดของการ run คอ Mean of p is 20.0 Mean of q is 23.0333333333333332 เชนเดยวกบโปรแกรมกอนหนาน ผลลพธทไดแสดงถงการเรยกใช constructor ทถกตองของ Java ยงมวธอนทเราสามารถทจะ overload constructor ได วธนเราจะเรยก constructor ตวอนจาก constructor อกตว การเรยก constructor จาก constructor วธการเรยก constructor จาก constructor กไมยาก เราเพยงแตกาหนดวธการเรยกใหเหมาะสม ซง Java ยอมใหมการเรยก constructor จาก constructor ผานทางคาวา this ดงตวอยางทไดแสดง ดงน //TestMean2.java class Mean { private double x, y, z; //constructor with one value Mean(double value) { x = value; y = 0.0; z = 0.0; } //constructor with two values Mean(double value1, double value2) { //calling constructor with one argument this(value1); y = value2; } //constructor with three values Mean(double value1, double value2, double value3) { //calling constructor with two arguments this(value1, value2); z = value3; }

Page 159: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 154 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public double findMean() { return (x + y + z) / 3; } } class TestMean2 { public static void main(String[] args) { //create objects with diferent parameters Mean m = new Mean(12.0); Mean n = new Mean(10.0, 20.0); Mean p = new Mean(10.0, 20.0, 30.0); System.out.println("Mean of m is " + m.findMean()); System.out.println("Mean of n is " + n.findMean()); System.out.println("Mean of p is " + p.findMean()); } } เราไดดดแปลงโปรแกรมของการหาคาเฉลยของเลขสามตวกอนหนานให ม constructor ทเรยกใช constructor ดงน Mean(double value) { x = value; y = 0.0; z = 0.0; } Mean(double value1, double value2) { //calling constructor with one argument this(value1); y = value2; } Mean(double value1, double value2, double value3) { //calling constructor with two arguments this(value1, value2); z = value3; } constructor ตวแรกกาหนดคาใหกบตวแปรเชนเดยวกบทไดทาไวกอนหนาน สวน constructor ตวทสองและสามเรยกใช constructor ทมอยภายใน class Mean ดวยการเรยกผาน this() โดยท constructor ตวทสองเรยก constructor ตวแรกดวยคาสง this(value1) เมอ Java เหนการเรยกเชนน กจะไปหา constructor ทมอยใน class วามตวไหนบางทมเงอนไขตามทถกเรยก ซงกเปนไปตามนนคอ Java ไปเรยก constructor ทม parameter เพยงตวเดยวมาทาการกาหนดคาเบองตนใหกบ object ท execute constructor ตวน คอ x จะมคาเปน value1 y และ z จะมคาเปน 0.0 จากการกาหนด หลงจากนนการกาหนดคาให y เปน value2 กไดถกกระทาภายใน constructor ตวทสอง constructor ตวทสามกเชนเดยวกน การเรยก constructor ทม parameter 2 ตวกเกดขน กระบวนการเดมทไดกลาวไวกอนหนานกไดถกกระทาขน เมอทาเสรจแลว การกาหนดคาใหกบตวแปร z จงมขน (ผลลพธของโปรแกรม TestMean2.java กเหมอนกบทเราไดกอนหนาน) การเรยกใช constructor ทมอยแลวทาใหการเขยน code ทซาซอนลดลง การเขยนโปรแกรมกมประสทธภาพมากขน

Page 160: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 155 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การ overload method เนองจากวา constructor กเปน method ชนดหนงดงนนถาเราสามารถทจะ overload constructor ไดเรากสามารถทจะ overload method ไดเชนกน เพราะฉะนนเราจะมาดเรองการ overload method ซงกไมแตกตางจากการ overload constructor เทาใดนก เรามาเรมตนดวย method ทแสดงผลออกทางหนาจอ จากตวแปรชนดตาง ๆ ทสงเขาไปยง method น //Overload.java class Ball { private double x, y, z; //constructor Ball() { x = y = z = 0.0; } //display coordinates public void display() { System.out.println("(" + x + ", " + y + ", " + z + ")"); } } class Overload { public static void main(String[] args) { Ball ball = new Ball(); //create object display(25); //display int display(350.0); //display double display("I love overloading."); //display string display('A'); //display char display(ball); //display object } //accept int as a parameter public static void display(int data) { System.out.println(data); } //accept double as a parameter public static void display(double data) { System.out.println(data); } //accept string as a parameter public static void display(String data) { System.out.println(data); } //accept char as a parameter public static void display(char data) { System.out.println(data); } //accept object as a parameter public static void display(Ball blue) { blue.display(); //calling display() from class Ball }

Page 161: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 156 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} โปรแกรม Overload.java สราง method display() เพอรองรบ parameter ตาง ๆ จานวน 5 ตว คอ รบ int รบ double รบ string รบ char และรบ object และกเชนเดยวกบการ overload constructor method ทเราเขยนขนตางกม signature ทไมเหมอนกน ดงนน java กสามารถหา method ทถกตองตามการเรยกใช ผลลพธทไดจากการ run โปรแกรมคอ 25 350.0 I love overloading. A (0.0, 0.0, 0.0) การใช overload นนมขอดในการเขยนโปรแกรมคอ เราไมจาเปนตองหาชออน ๆ ทเหมาะสมกบหนาทของ method นน ๆ นอกเหนอจากทเราไดเลอกไวแลว และการใชชอเดยวเพอรองรบ parameter หลายตวทาใหผใชไมตองคนหา method ตวอน ททาหนาทแบบเดยวกน ตว Java เองกไดสราง method ไวมากมายทมการใช overload ในการสรางเพอรองรบการใชงานของ user ทมความหลากหลายของขอมลทสงเขาไปยง method นน ๆ ทาใหผใชไมตองเสยเวลาในการคนหา method ทตวเองตองการใช ผอานควรฝกการเขยนโปรแกรมดวยการใช overload method เพอใหเกดความชานาญ และเขาใจถงวธการของ method overload มากยงขน การสราง class ภายใน class (nested class) ตวอยางของการสรางและเรยกใช class ทเราไดทราบถงกอนหนาน เปนการสราง class ทมเพยงเฉพาะตวแปร และ method อยภายใน class เทานน ยงไมมขอมลภายใน class ทตวมนเองกเปน class เชนเดยวกน เราจะมาดถงวธการสราง class ภายใน class อยางงาย ๆ เพอใหไดรบทราบวา Java ยอมใหมการสราง class ภายใน class เชนเดยวกนกบทเราสามารถสราง method อน ๆ เราจะลองเขยนโปรแกรมตวอยางแบบงาย ๆ ท class ซอนกนอย //NestedClass.java class Parent { private String name; Child c = new Child("Galvin"); //create a Child object Parent(String n) { name = n; } public void showName() { System.out.println("Parent: " + name); c.showName(); //calling Child's showName() } class Child { private String name; //create a GrandChild object GrandChild gc = new GrandChild("Jeff"); Child(String n) { name = n; } public void showName() { System.out.println("Child: " + name); gc.showName(); //calling GrandChild's showName()

Page 162: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 157 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} class GrandChild { private String name; GrandChild(String n) { name = n; } public void showName() { System.out.println("GrandChild: " + name); } }//class GrandChild }//class Child }//class Parent class NestedClass { public static void main(String[] args) { Parent p = new Parent("Rebecca"); p.showName(); } } โปรแกรม NestedClass.java สราง object จาก class Parent หนงตว แสดงขอมลทอยใน class ผานทาง method showName() ซงใหผลลพธ ดงน คอ Parent: Rebecca Child: Galvin GrandChild: Jeff class Parent ของเราไดสราง class อก class หนงทอยภายในชอ Child และ class Child กไดสราง class อก class หนงชอ GrandChild โดยทก class จะม method ชอ showName() ซงเอาไวใชในการแสดงคาของตวแปรของแตละ class ไปยงหนาจอ เราไดสราง object จาก class Child ภายใน class Parent ชอ c และเราเรยก method showName() ของ class Child จาก method showName() ของ class Parent ในทานองเดยวกนรากไดสราง object จาก class GrandChild ภายใน class Child และกเรยก method showName() ของ class GrandChild จาก method showName() ของ class Child ดวย เพราะฉะนนขนตอนของการ execute คอ Parent.showName() Child.showName() GrandChild.showName() เราสามารถทจะสราง object จาก class ทอยดานในผานทาง object ทอยดานนอก ดงเชนตวอยางน class NestedClass { public static void main(String[] args) { Parent p = new Parent("Rebecca"); p.showName(); Parent.Child newChild = p.new Child("John"); Parent.Child.GrandChild newGrandChild =

newChild.new GrandChild("Jen"); newChild.showName(); newGrandChild.showName(); } }

Page 163: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 158 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เราเพมประโยคใหมเขากบ class NestedClass ของเราเพอแสดงการสราง object จาก class ทอยภายใน ประโยค Parent.Child newChild = p.new Child("John"); สราง object จาก class Child ผานทาง object ทมาจาก class Parent ดวยการเรยกใช p.new Child("John") เราตองทาการสรางผานทาง object ของ class Parent เทานนเราไมสามารถทจะสราง object จาก class Child ผานทาง class Parent โดยตรง เชน ประโยค Parent.Child newChild = Parent.new Child("John"); จะไมไดรบการ compile และ Java จะฟองดวย error ทนท การสราง object จาก class GrandChild ผานทาง class ทอยภายนอกทงสองกคลาย ๆ กน ผลลพธของการ run โปรแกรมทถกดดแปลงแลว คอ Parent: Rebecca Child: Galvin GrandChild: Jeff Child: John GrandChild: Jeff GrandChild: Jen เนองจากวาเราสราง object ของ class Child ผานทาง class Parent ดงนนเมอเรยกใช method showName() เราจงไดผลลพธ Child: John GrandChild: Jeff อกครงหนง สวน object ทสรางขนใหมจาก class GrandChild เมอเรยก method showName() เราจงไดเพยงแต GrandChild: Jen เทานน ตวอยางโปรแกรมการสราง nested class ทเหนเปนเพยงแคตวอยางทแสดงใหดถงการสราง nested class เทานน การออกแบบ nested class ตองคานงถงความสมพนธของทง class ทอยดานนอก และ class ทอยดานในวามความสมพนธกนอยางไร ถาความสมพนธนนสามารถทจะเขยน class แยกกนออกมาได การออกแบบกควรใหเปน class ทแยกกนอย เพราะจะทาใหการออกแบบทาไดงายกวา การสรางและเรยกใช object กจะไมซบซอนเทาใดนก มาถงตอนนเราไดทราบถงการสราง class การออกแบบ method และการสราง object จาก class พอสมควร ตวอยางทจะแสดงใหดตอไปเปนความพยายามทจะออกแบบ class Array ขนมาใชงาน เพอทจะแสดงใหเหนถงศกยภาพของการใช Java ในการเขยนโปรแกรม class MyArray ทเราสรางขนจะกาหนดใหเปน array ทใชเกบ Object เพอใหมความยดหยนในการทางานกบขอมลตาง ๆ ทงนและทงนน class MyArray เปนเพยงแคตวอยางตวอยางหนงเทานน ผอานสามารถทจะทาไดมากกวาทโปรแกรมตวอยางนแสดงใหด //MyArray.java class MyArray { Object []arr; //array of objects int maxSize; //maximum size of array int count; //number of items in array //default constructor MyArray() {

Page 164: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 159 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

count = 0; //no item as yet maxSize = 10; //default maximum size arr = new Object[maxSize]; //allocate space for arr } //constructor MyArray(int size) { count = 0; //no item as yet maxSize = size; //set maximum size arr = new Object[maxSize]; //allocate space for arr } //method to add item into arr public void add(Object item) { //expand capacity if arr is full //double the size if(count == maxSize) { //double arr's size maxSize *= 2; //create temporary array Object []temp = new Object[maxSize]; //copy items into new array: temp System.arraycopy(arr, 0, temp, 0, arr.length); //refer arr to temp arr = temp; } arr[count++] = item; //add new object into arr } //overload method add to accomodate double public void add(double item) { add(String.valueOf(item)); } //overload method add to accomodate int public void add(int item) { add(String.valueOf(item)); } //return formatted output when user uses System.out.println() //10 items per line public String toString() { //create new buffer to hold data StringBuffer buffer = new StringBuffer(); for(int i = 0; i < maxSize; i++) { //append newline if this line already has 10 items if(i % 10 == 0) buffer.append("\n"); //stop appending when there is no item left (null) if(arr[i] == null) break; //append tab + item in arr buffer.append("\t" + arr[i]); } //returning an output String return new String(buffer + "\n"); } }

Page 165: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 160 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เรากาหนดใหม constructor สองตว โดยทตวแรกเปน default constructor ทกาหนดใหขนาดของ array มความจครงแรกไดเพยง 10 ตว สวนตวทสองเปน constructor ทผใชสามารถกาหนดขนาดของ array ได เราไดออกแบบให array ของเราเปน array แบบยดหยน หรอทเรยกวา dynamic array โดยเรากาหนดใหมการขยายขนาดของ array ใหเปนสองเทาของขนาดเดมถามการใสขอมลเกนจานวนท array สามารถรองรบได ใน method add() public void add(Object item) { //expand capacity if arr is full //double the size if(count == maxSize) { //double arr's size maxSize *= 2; //create temporary array Object []temp = new Object[maxSize]; //copy items into new array: temp System.arraycopy(arr, 0, temp, 0, arr.length); //refer arr to temp arr = temp; } arr[count++] = item; //add new object into arr } method add() ของเราจะตรวจสอบคาของ count (จานวนของขอมลทมอยใน array) กบ maxSize (ความจสงสดทสามารถเกบขอมลได) วาเปนคาเดยวกนหรอไม ถาเปนคาเดยวกนเราจะขยายขนาดของ array ออกเปนสองเทา ดวยการสราง array ตวใหมชอ temp ทมความยาวเปนสองเทาของ array ตวเดม maxSize *= 2; Object []temp = new Object[maxSize]; หลงจากนนเรากทาการโยกยายขอมลจาก array ตวเกาส array temp ดวยการใชคาสง System.arraycopy(arr, 0, temp, 0, arr.length); คาสงนจะทาการยายขอมลจาก arr เรมตนท index = 0 ไปส temp เรมตนท index 0 จนกวาจะหมดความยาวทกาหนดให (arr.length) ซงกคอจานวนของขอมลทอยใน arr ทงหมด เมอโยกยายขอมลเสรจแลวเรากอางถง array ตวใหมดวย array ตวเดมของเราคอ arr ดวยคาสง arr = temp; เรายงไดทาการ overload method add() ของเราเพอใหสามารถรองรบการเพมขอมลทเปน double และ int เขาส array ของเราได วธการแบบนไมคอยจะดสกเทาไร เพราะเปนการนาเอาขอมลทไมใชชนดเดยวกน (โดยตรง) เขาไปเกบไวใน array ซงถาหากมกระบวนการอน ๆ ทเราตองการทากบขอมลเหลานน เราจะตองเสยเวลาในการตรวจสอบชนดของขอมลทกตวทมอยใน array ของเรา เราทาการ overload ดวยการใช method ของ class String คอ String.valueOf() ดงทเหนน public void add(double item) { add(String.valueOf(item)); } เนองจากวา String เปน Object ชนดหนงดงนนการ add String เขาส array ของเราจงไมมปญหาอะไร หลงจากนนเราไดเขยนโปรแกรมเพอตรวจสอบ ดงน

Page 166: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 161 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//TestMyArray.java import java.lang.Integer; class TestMyArray { public static void main(String[] args) { //create array of 10 objects MyArray array = new MyArray(10); //add 40 objects into array (randomized) int count = 0; while(count < 40) { int data = (int)(Math.random() * 100 + 1); array.add(new Integer(data)); ++count; } System.out.println(array); //display contents array.add(45.23); //add double array.add(88.23); array.add(89); //add int array.add(12); System.out.println(array); } } เรากไดผลลพธ ดงน 9 76 20 86 98 12 27 35 41 31 54 65 83 3 36 96 24 63 19 75 3 91 87 72 3 12 7 46 96 11 1 70 27 47 14 51 22 74 95 98 9 76 20 86 98 12 27 35 41 31 54 65 83 3 36 96 24 63 19 75 3 91 87 72 3 12 7 46 96 11 1 70 27 47 14 51 22 74 95 98 45.23 88.23 89 12 ผอานควรสงเกตถงผลลพธทไดโดยเฉพาะขอมลในบรรทดสดทาย (ทเราไดเพมขอมลทเปน double และ int หลงจากการ display ครงแรก) สวนประกอบทสาคญอกสวนหนงทตองกลาวไวในทน คอ method toString() และกอนทจะพดถง method toString() เราควรดประโยคอกประโยคหนงกอน นนกคอ System.out.println(array); ประโยค System.our.println() จะรบเฉพาะขอมลทเปน String หรอ primitive datatype ทเราไดพดถงกอนหนาน แตสงทเราสงไปใหเปน object จาก class MyArray ทาไมเราถงทาได? เราสง Object ไปให System.out.println() ไดกเพราะวาเราไดเขยน method toString() รองรบไวเรยบรอยแลว เมอไรกตามท Java เหนขอมลทไมใช String หรอ primitive datatype Java จะทาการคนหา method toString() ถาม Java กจะใช method toString() นน แตถาไมมกจะฟองดวย error ทนท เรามาดกนวาเราเขยน method toString() อยางไร

Page 167: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 162 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public String toString() { //create new buffer to hold data StringBuffer buffer = new StringBuffer(); for(int i = 0; i < maxSize; i++) { //append newline if this line already has 10 items if(i % 10 == 0) buffer.append("\n"); //stop appending when there is no item left (null) if(arr[i] == null) break; //append tab + item in arr buffer.append("\t" + arr[i]); } //returning an output String return new String(buffer + "\n"); } ภายใน method toString() เราใช StringBuffer ในการเกบสวนประกอบตาง ๆ ทเราตองการสงกลบออกไป ซงจะประกอบไปดวย ขอมลตาง ๆ ทอยใน array (arr[i]) tab (\t) newline (\n)

เรานาขอมลเหลานไปเกบไวใน buffer ดวยการใช method append() ทก ๆ ครงทเราไดขอมลครบ 10 ตวเราจะทาการ append newline เขาส buffer ถาหากวาเราไดขยายขนาดของ array แตไมไดใสขอมลครบตามขนาดทไดขยายขน เราจะยตการนาขอมลเขาส buffer เนองจากวาขอมลเหลานมคาเปน null และเรากไมตองการแสดงคาเหลาน เมอเราไดขอมลทงหมดทตองการแลว เรากสงกลบออกไป โดยสงออกไปในรปแบบของ String (เพราะ System.out.println() ตองการ String) ดวยคาสง return new String(buffer + "\n"); ผอานสามารถนาเอาเทคนคนไปใชกบการแสดงขอมลอน ๆ ผานทาง System.out.println() ไดโดยไมมขอจากดใด ๆ ทงสน เราสามารถทจะสราง class เพอการใชงานของเราโดยไมมขดจากดใด ๆ ทงนกตองขนอยกบลกษณะงานนน ๆ วาอยในรปแบบไหน ความยาก งายของงานเปนอยางไร ตวอยางการสราง array ขนมาใชงานเปนเพยงตวอยางเลก ๆ เพยงตวอยางเดยวทเราไดแสดงใหดถงขอดของภาษา Java ยงมสงอน ๆ ทผอานสามารถทจะสรางขนมาสาหรบงานของตวเองได Package Package เปนทรวมของ class ตาง ๆ ทถกเรยกใชในโปรแกรม หรอ method ตาง ๆ class ทก ๆ ตวของ Java ไดถกจดถกเกบอยใน package ตาง ๆ เชน java.lang หรอ java.io การเอา class ตาง ๆ มารวมกนไวใน package เดยวกนทาใหการเรยกใช class ตาง ๆ เหลานทาไดงายขน ถาผอานมองยอนกลบไปดโปรแกรมตวอยางตาง ๆ ทเราเขยนขน กจะเหนการเรยกใช package เหลานในโปรแกรมหลาย ๆ ตว เราจะมาดถงวธการสราง package เพอเกบ class และการเรยกใช package เหลานในโปรแกรมตวอยาง การสราง package การสราง package นนไมยาก ขนตอนกไมซบซอนเทาไร ขนตอนแรกทเราตองทากคอ ใสคาวา package ตามดวย ชอของ package นนกอนประโยคใด ๆ ในไฟลทเกบ class นน ๆ ทเราสรางขน (ยกเวนประโยคทเปน comment) เชน //package Shape package Shape;

Page 168: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 163 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public class Rectangle { … … } ถาเราไมใสคาวา public ไวดานหนาของ class หรอ method ทอยใน package ทเราสรางขน โปรแกรม หรอ class ตวอน ๆ ทอยนอก package กไมสามารถทจะเรยกใช class นได ยกเวน class อน ๆ ทอยใน package นเทานน package ตวอยางของเราใชชอวา Sample โดยเรากาหนดให Sample ประกอบไปดวย class One และ class Two และเราไดสราง package อกตวหนงใน Sample ใหชอวา oneMore และใน package oneMore นเราจะเกบ class Three ไว ดงทเหนจาก code ขางลางน //sample package package Sample; public class One { public One() { System.out.println("This is class One in Sample package."); } } //sample package package Sample; public class Two { public Two() { System.out.println("This is class Two in Sample package."); } } //sample package package Sample.oneMore; public class Three { public Three() { System.out.println("This is class Three in Sample.oneMore package."); } } ในการ compile ไฟลทงสามทไดสรางขนน เราใชคาสง javac -d e:\bc221Book\source ตามดวยชอไฟล เชน javac -d e:\bc221Book\source One.java เราตองใช option -d ในการ compile ไฟลทงสามเพอบอกให Java รถงแฟมปลายทางทเราตองการเกบ class ไฟลทเกดขนจากการ compile ในทนเราจะเกบ class ไฟลไวใน e:\bc221Book\source ภายในไฟล One.java และ Two.java เราไดใชคาสง package Sample เปนตวบอกถงทเกบ class ไฟล และในตวไฟล Three.java เราใชคาสง package Sample.oneMore เพราะฉะนน class ไฟลทเกดขนจะถกเกบไวในแฟม (directory) เหลาน ดงทไดแสดงไวในรปทเหนดานลางน

Page 169: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 164 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

รปท 5.7 แฟมเกบ class file ทเกดขนจากการ compile ดวย option -d หลงจากนนเรากสรางโปรแกรมตรวจสอบการเรยกใช package ทเราไดสรางขน โดยทเรากาหนดใหมการเรยกใช class ตาง ๆ ดวยการใชคาสง import ดงน //test the package import Sample.One; import Sample.Two; import Sample.oneMore.Three; class TestPackage { public static void main(String[] args) { One object1 = new One(); Two object2 = new Two(); Three object3 = new Three(); } } หลงจากนนเราก compile โปรแกรม TestPackage.java ดวยคาสง javac -classpath e:\bc221Book\source TestPackage.java โดยเราใช option –classpath ตามดวยทอยของ class ตาง ๆ ทเราไดสรางขนในการ compile และเมอทดลอง run ดผลลพธทไดคอ This is class One in Sample package. This is class Two in Sample package. This is class Three in Sample.oneMore package. ในการสราง package นน Java จะไปสรางแฟมทมชอเหมอนกบทเรากาหนดไว ดงทไดเหนในตวอยาง และเราสามารถทจะกาหนด sub-directory ดวยการใช . (dot) เชนทเราไดทาไว (Sample.oneMore) และเราตองไมลมใชคาวา public นาหนา class และ method ตาง ๆ ทเราตองการใหโปรแกรม หรอ class หรอ method อน ๆ ทอยนอก package ใช เราไมจาเปนตอง compile ดวยการใชคาสงทม option –classpath ในการ compile โปรแกรมทเรยกใช package ตาง ๆ ของ Java เพราะ Java ไดจดการเรองตาง ๆ เหลานใหเราเรยบรอยแลว ถาเราใช class ตาง ๆ ทอยใน package ทสรางขนบอยครง หรอทกครง เรากสามารถทจะกาหนดให Java คนหา class ตาง ๆ เหลานโดยไมตองกาหนด option –d ในการ compile เราเพยงแตกาหนด classpath ไวกอนการ compile ครงแรกเพยงครงเดยว ดงน

Package ชอ oneMore ใน e:\bc221Book\source\Sample

Package ชอ Sample ใน e:\bc221Book\source

Class ไฟลทถกสรางขน

Page 170: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 165 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

set classpath=e:\bc221Book\source ถาเราไมอยากทจะกาหนด classpath ทกครงทเราตอง compile เรากกาหนด classpath ไวในไฟล autoexec.bat สาหรบ Windows รนเกา ๆ สวน Windows รนใหมเราตองกาหนด classpath ไวใน environment variables (คลาย ๆ กบการกาหนด path ของ Java ในบททหนง) ถาเราม package อน ๆ ทเราตองการใช เรากใช ; เปนตวแบง classpath เชน set classpath=e:\bc221Book\source; c:\myOthers\Shape สรป ในบทนเราไดสารวจถงวธการสราง class การสราง object การสราง method และการสราง method และ constructor ทม signature ทแตกตางกนในการรองรบการเรยกใชดวย parameter ทตางกน การกาหนดนโยบายการเขาหาขอมลทอยใน class รวมไปถงการสราง nested class และการสราง package โดยสรปแลวเราไดทราบถง

สวนประกอบของ class ชอของ class จะตองเปนชอเดยวกนกบๆฟลทเกบ class นนอย การประกาศตวแปรทเรยกวา class variable ตองใชคาวา static นาหนา ตวแปรทเปน instance variable สามารถทจะเขาหาไดผานทาง object ทเกดจาก class นน การสราง method จะตองบอกถงสงทตองสงกลบ ชนดและจานวนของ parameter (ถาม) Method ทประกาศใหเปน static สามารถถกเรยกใชไดถงแมวาจะไมม object ใด ๆ ถกสรางขน การเขาหาขอมลใน class มสามแบบคอ private public และ protected (ไมนบแบบทไมมคาใด ๆ

นาหนา) การสราง class สามารถทจะสรางใหอยใน class อนได การสราง และ การใช package จะตองใชคาวา public นาหนา class หรอ method ทตองการให

ผอนทอยนอก package ใช แบบฝกหด 1. จงออกแบบ class ทใชเกบขอมลเกยวกบ นกศกษา เชน รหส ชอ-นามสกล ทอย และขอมลอน ๆ ท

เหนวาเหมาะสม ใหเขยนโปรแกรมทดสอบการสราง object ตาง ๆ จาก class ทไดสรางขนน 2. จงออกแบบ class ทใชเกบขอมลทเกยวของกบนาหนก เชน ตน กโลกรม และ กรม โดยใหออกแบบ

ใหม constructor ทรองรบการสราง object ดวยจานวน parameter ทตางกน ชนดของ parameter ทตางกน รวมไปถงการออกแบบ method ททาการบวก การลบ object ตาง ๆ ทไดถกสรางขน ใหเขยนโปรแกรมทดสอบ

3. จาก class MyArray ทสามารถเกบขอมลทเปน object ตางชนดกนได จากตวอยางทใหไว จงเขยน

method ทสงจานวน object ทมอยใน array ใหชอวา getCount() และ method dataAt() ทสงคาของขอมล ณ ตาแหนงทกาหนดใหกลบไปยงผเรยก เชน ถาเรยกดวย

Object obj = arr.dataAt(7); จะสงขอมล ณ ตาแหนงท 7 มาใหกบตวแปร obj ใหเขยนโปรแกรมทดสอบ method ทเขยนขน

4. จงเขยนโปรแกรมทม method ในการคานวณหาพนทของวงกลมทม parameter ตางชนดกน เชน ผ

เรยกใช method อาจสงขอมลทมชนดเปน int double float หรอ String ทเปนตวเลข เชน "234" ใหเขยนโปรแกรมตรวจสอบ method เหลาน

5. จงเขยนโปรแกรมทตรวจสอบการใช overloaded constructor ในการกาหนดคาใหกบ instance

variable ทมอยใน class นน ๆ ใหเขยนโปรแกรมทดสอบ

Page 171: Beginning JAVA [Thai]

บทท 5 Objects และ Classes 166 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

6. จงออกแบบ class สาหรบเกบขอมลทเกยวของกบนกศกษา เชน รหสประจาตว ชอ นามสกล ทอย

และขอมลอน ๆ ทจาเปน รวมไปถง method ตาง ๆ ทใชในการกาหนดคา หรอประมวลผลเกรดเฉลย และ method สาหรบการแสดงผลไปยงหนาจอ

7. จงออกแบบ class สาหรบเกบขอมลของ วน เดอน ป ในรปแบบของ dd:mm:yyyy โดยกาหนดให

ขอมลนนาเขามาจาก keyboard ใหเขยน Method ททาหนาทในการเปลยนขอมลนใหอยในรปแบบทขนตนดวย วน ตามดวย วนท เดอน และ ป เชน วนจนทรท 12 สงหาคม พ.ศ. 2546 หรอ Monday 12 August 2003 ใหเขยนโปรแกรมทดสอบ

8. จงออกแบบ class Matrix สาหรบการประมวลผลตาง ๆ เชน การบวก การลบ การคณ และ

กระบวนการอน ๆ ทเกยวของ ใหเขยนโปรแกรมทดสอบ 9. จงออกแบบ class ทใชสาหรบการคานวณหาอายของ user ทใสเขามาจาก keyboard ในรปแบบ

ของ dd/mm/yyy โดยใหผลลพธทหาไดอยในรปแบบของ จานวนของวน ทงหมด ใหเขยนโปรแกรมทดสอบ

10. จงออกแบบ class MyString ทม method สาหรบการประมวลทเกยวของกบ string ตาง ๆ เชน การ

บวก string สองตว การคนหาคาใน string การลบคาทอยใน string การนบจานวนตวอกษรทอยใน string ใหเขยนโปรแกรมทดสอบ

Page 172: Beginning JAVA [Thai]

เราไดพดถงการสราง class และสวนประกอบตาง ๆ ทสาคญของ class รวมไปถงการสราง method ในบททหา สาหรบบททหกนเราจะสารวจในเรองของการสราง class ใหมจาก class เดมทมอย การนาเอาสวนประกอบของ class เดมมาใชใน class ใหม การถายทอดคณสมบตและ กระบวนการตาง ๆ จาก class เดมส class ใหม หลงจากจบบทนแลว ผอานจะไดทราบถงเรองของ

o การใช class เดมสาหรบการสราง class ใหม (Extended class) o การถายทอดคณสมบต (Inheritance) o คณสมบต และการใชประโยชนจาก polymorphism o การสราง abstract class และ abstract method o การใช และ การสราง interface

การสราง class ใหมจาก class เดมทมอยแลวเปนการพฒนาโปรแกรมททาใหการเขยน code ใชเวลานอย และเปนการใช code อยางคมคาทสด Java ยอมใหมการสราง class เดมจาก class ใหมไดอยางงาย ๆ โดยทผเขยนโปรแกรมแทบจะไมตองทาอะไรมากมาย (ยกเวน code ใหมทเขยนขน) กอนทจะพดถงศพทตาง ๆ ทเกยวของกบการสราง class ใหมจาก class เดมเราจะมาดกนถงตวอยางของการสราง class ใหมจาก class เดมกอน เราจะเรมตนดวยการสราง class งาย ๆ class หนงทเกยวกบรถทใชเครองยนต (motor vehicle) โดยกาหนดใหมขอมลทไมซบซอน เชน ยหอ (make) รน (model) ปทผลต (year) และ จานวนทนง (seats) พรอมทงกาหนดใหม method สาหรบการเขาหาขอมลเหลานน หลงจากทได class MotorVehicle แลวเรากออกแบบ class อน ๆ ทไดรบคณสมบตจาก class MotorVehicle ดงทแสดงใหเหนคราว ๆ จาก diagram น (เราจะดโครงสรางของ class ทงหมดตอไป)

ภาพท 6.1 ตวอยางของ base-class และ derived-class

MotorVehicle

Car Motorcycle

Compact OffRoad Scooter Chopper

Page 173: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 168 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เราออกแบบให class MotorVehicle เปน class แมแบบ หรอทเรยกวา parent class (หรอ base class หรอ super class) ซงจะเปน class ทอยดานบนสดของ class ตาง ๆ ในกลมน เรากาหนดให class MotorVehicle ม class ลก (children) อยสอง class คอ class Car และ class Motorcycle class ลกทงสองตางกม class ทเปนลกของมนเองอกสอง class โดยท class Car มลกเปน class Compact และ class OffRoad สวน class Motorcycle ม class Scooter และ class Chopper เปน class ลก เราจะกาหนดให class ลกไดรบคณสมบตจาก class แมทงหมด คอ ขอมลทกตวทมอยใน class MotorVehicle เรามาดกนถง ขอมล และ method ทเรากาหนดใหมใน class MotorVehicle //MotorVehicle.java – Inheritance class MotorVehicle { protected String make; //e.g. Ford, Honda protected String model; //e.g. Taurus, Steed protected int year; //e.g. 2001, 2003. protected int seats; //e.g. 4, 2 //constructor MotorVehicle(String make, String model, int year, int seats) { this.make = make; this.model = model; this.year = year; this.seats = seats; } public String getMake() { return make; } public String getModel() { return model; } public int getYear() { return year; } public int getSeats() { return seats; } } เรากาหนดใหตวแปรทมอยใน class MotorVehicle ใชนโยบายของการเขาหาแบบ protected ซงเปนการกาหนดให class ลกทเกดขนจาก class MotorVehicle สามารถทจะเรยกใชตวแปรเหลานได class อน ๆ ทไมไดมาจาก class นจะมองไมเหนขอมลเหลาน เรากาหนดใหม constructor เพยงตวเดยวสาหรบการสราง object โดยเราเลอกใชคาสง this ในการแยกแยะตวแปรทอยใน class กบตวแปรทเปน parameter MotorVehicle(String make, String model, int year, int seats) { this.make = make; this.model = model; this.year = year; this.seats = seats; } คาวา this เปนคาท Java สงวนไวสาหรบการบงบอกถง object ทไดรบการกระทาดวยกระบวนการตาง ๆ ณ เวลานน ๆ เชนในตวอยางประโยค this.make = make;

Page 174: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 169 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เมอ Java ประมวลผล constructor ตวน Java จะทาการกาหนดคาจากตวแปร make ทเปน parameter ของ constructor ใหกบตวแปร make ทอยใน class ซงเปน copy ท object ตวนใชอย เราไมจาเปนทจะตองใช this เปนตวบงบอกตวแปรเสมอไป ถาเราใชตวแปรทอยใน parameter list ทมชอไมเหมอนกบ ตวแปรของ class (เชนตวอยางอน ๆ ทเราไดแสดงไวในบททหา) สวน method อน ๆ ทมอยกเปนเพยง method ทสงคาของตวแปรเหลานใหกบผเรยก สาหรบ class อน ๆ ทเราไดสรางขนมดงน //Car.java - Derived from MotorVehicle class Car extends MotorVehicle { protected int doors; Car(String make, String model, int year, int seats, int doors) { super(make, model, year, seats); this.doors = doors; } public int getDoors() { return doors; } //display Car's information as string //using base class methods public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(super.getMake() + ", " + super.getModel() + ", " + super.getYear() + ", " + " seating: " + super.getSeats() + ", " + doors + "doors."); return new String(buffer); } }

เราสราง class Car จาก class MotorVehicle ดวยการใชคาสง class Car extends MotorVehicle ซงเปนคาสงท Java กาหนดใหใชถาตองการสราง class ใหมทตองการใชคณสมบตของ class อน ภายใน class Car ทเราไดสรางขนเรากาหนดใหมตวแปรหนงตวทเปนตวกาหนดจานวนของประตทรถคนนมอย และเพอใหการแสดงผลไปยงหนาจอทาไดงายขน เรากสราง method toString() สาหรบการแสดงผลของ object ทเกดจาก class Car ของเรา เราเรยกขอมลทเราไดรบการถายทอดจาก class MotorVehicle ดวยการใชคาสง ดงน super.getMake(); เมอ Java เหนการใชคาสงแบบน Java กจะไปคนหา method getMake() ทอยใน class ทเปน class แม หรอทเรยกกนวา super class พรอมทงประมวลผลคาสงตาง ๆ ทมอยใน method getMake() ผอานจะเหนวาเราไมตองประกาศตวแปรขนมาใชใหมใน class Car ของเราเลย เราสามารถเรยกใชตวแปรเหลานจาก class MotorVehicle ไดเลย เรามาทดสอบ class ทงสองดวยการสราง object จาก class Car สองตว เชนทเหนในโปรแกรม TestVehicle.java น //TestVehicle.java class TestVehicle { public static void main(String[] args) { //create two cars, ford and honda

Page 175: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 170 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Car ford = new Car("Ford", "Taurus", 2001, 5, 5); Car honda = new Car("Honda", "City", 2003, 4, 4); //display informatin about cars System.out.println(ford); System.out.println(honda); } } ผลลพธทเราไดจากการ run คอ Ford, Taurus, 2001, seating: 5, 5 doors. Honda, City, 2003, seating: 4, 4 doors. เราไดใชนโยบายการเขาหาแบบทใชคาวา protected ซงเราไมไดอธบายไวเลยกอนหนาน สาเหตกเนองจากวาคาวา protected โดยสวนใหญจะใชกนในเรองของการถายทอดคณสมบตจาก class แมไปยง class ลก โดยกาหนดไววา class ลกสามารถทจะใชตวแปร (หรอ method ทใชคาวา protected นาหนา) จาก class แมไดอยางไมมเงอนไข แตถาเราใชคาวา private แทน class ลกไมสามารถทจะเขาหาตวแปร หรอ method เหลานได ดงตวอยางตอไปน Car(String make, String model, int year, int seats, int doors) { super(make, model, year, seats); this.doors = doors; System.out.println("base class: " + super.make); } ใน class MotorVehicle เราเปลยนนโยบายการเขาหาตวแปร make ใหเปน private private String make; และเพมประโยค System.out.println("base class: " + super.make); ใน constructor ของ class Car ซงเปนประโยคทพยายามเขาหาตวแปรใน class MotorVehicle ดวยการใช super.make Java จะไมยอมใหเรา compile พรอมกบฟองวาเราไมสามารถเขาหาตวแปรตวนได วธเดยวทเราจะเขาหาตวแปรเหลานได กคอการเขาผานทาง method getMake() ทเราไดกาหนดนโยบายการเขาหาใหเปน public เทานน โดยทวไปเรามกจะกาหนดใหตวแปรทใชรวมกนใน class ลก (ทมอยใน class แม) ทงหลายมนโยบายการเขาหาทเปนแบบ private เพอปองกนการใชทไมพงประสงคจาก class อน และเรากควรจะกาหนดให method ทอยใน base class มนโยบายการเขาหาทเปนแบบ protected ดวยเหตผลเชนเดยวกน และเหตผลอกอนหนงกคอ คาวา protected เมอมการนามาใชแลว class อน ๆ ทอยใน package เดยวกนกสามารถทจะเขาหาตวแปร หรอ method เหลานได ดงนนถาตองการให class ตาง ๆ ของเราทสรางขนในตวอยางเปน class ทการใชนโยบายการเขาอยางถกตอง เรากตองเปลยน class ของเราใหเปน ดงน class MotorVehicle { private String make; //e.g. Ford, Honda private String model; //e.g. Taurus, Steed private int year; //e.g. 2001, 2003 private int seats; //e.g. 4, 2 //constructor MotorVehicle(String make, String model, int year, int seats) { this.make = make; this.model = model; this.year = year;

Page 176: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 171 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

this.seats = seats; } protected String getMake() { return make; } protected String getModel() { return model; } protected int getYear() { return year; } protected int getSeats() { return seats; } } class Car extends MotorVehicle { private int doors; Car(String make, String model, int year, int seats, int doors) { super(make, model, year, seats); this.doors = doors; } protected int getDoors() { return doors; } public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append(super.getMake() + ", " + super.getModel() + ", " + super.getYear() + ", " + "seating: " + super.getSeats() + ", " + doors + " doors."); return new String(buffer); } } เราไมสามารถทจะเปลยนนโยบายการเขาหาของ method toString() ใหเปน protected ไดกเพราะวา Java ไดกาหนดใหการเขาหาของ method toString() เปนแบบ public ไวแลว ซงเราจะไดอธบายตอไปในเรองของการ override เพอใหเหนถงความพเศษของ การถายทอดคณสมบต และเพอเปนการแนะนาเรองของการ override เราจะสราง class Compact ขนมาอก class หนง โดยกาหนดให class Compact นเปน class ทไดรบการถายทอดคณสมบตจาก class Car ดงน //Compact.java Derived from Car class Compact extends Car { //constructor -using base class (Car) constructor Compact(String make, String model, int year, int seats, int doors) { super(make, model, year, seats, doors);

Page 177: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 172 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} //override Car's toString() method //presenting Comapct car's details as string public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("Compact car: "); buffer.append(super.toString()); return new String(buffer); } } class Compact ของเราเรยกใชขอมลทกอยางท class แมมให ตวแรกทเราเรยกใชกคอ constructor ของ class Car (ซง constructor ของ class Car กเรยกใช constructor ของ class MotorVehicle) ตวทสองทเราเรยกใชกคอ method toString() ของ class Car ซงเราไดเพมคาวา "Compact car: " ไวกอนหนาขอมลอน ๆ ดวยการใช method append() ของ class StringBuffer ดงน buffer.append("Compact car: "); buffer.append(super.toString()); เมอทดลอง run ดวยการใชคาสง Compact honda = new Compact("Honda", "City", 2003, 4, 4); System.out.println(honda); ผลลพธทได คอ Compact car: Honda, City, 2003, seating: 4, 4 doors. ซงตางจากการ run กอนหนาน (ตอนทเราสราง object จาก class Car) เราใชเทคนคทเรยกวา method overriding ในการแสดงผลขอมลของ object ทเกดจาก class Compact ในการ override (ซงตางกบ overload ทเราไดทากอนหนาน – overload ทากบ method ทอยใน class เดยวกนและตองเปน method ทม parameter list ไมเหมอนกน) method จาก class แม หรอทเรยกวา base class นนเราสามารถทจะเขยน code ใหทางานในลกษณะใดกได โดยทวไปการ override method ทาใหการเรยกใชงานทาไดงายขน ไมสบสน เพราะ method ชอเดยวกนมอยใน class ทกตว แตทาหนาทตามทไดกาหนดไวใน method ของ class นน ๆ เราสามารถทจะ override method ทมอยใน class แมไดทกตว และ object ทเกดจาก class ลก หรอทเรยกวา derived class นนเมอมการเรยกใช method ทไดรบการ override Java จะไปเรยก method ทอยใน class ลก ไมใช method ทอยใน class แม จากตวอยางของ class Compact ทไดกลาวไว เราไดใชทง การถายทอดคณสมบต และการ override method โดยเราไดรบการถายทอดในเรองของตวแปร และไดใชเทคนคการ override ในการใช method toString() Method ทไดรบการ override ใน class ลกนนไมสามารถทจะเปลยนแปลงนโยบายของการเขาหาใหเปนอยางอนทมความเขมงวดกวาได เชน ถา method ใน class แมมนโยบายการเขาหาทเปน public ใน class ลกกไมสามารถทจะเปลยนใหเปน private ไดเพราะการเขาหาแบบ private นนเขมงวดมากกวา แตถาใน class แมนโยบายเปน private เราสามารถทจะเปลยนใหเปน public ได พดงาย ๆ กคอวา เราเพมความเขมงวดนโยบายการเขาหาใน class ลกไมได แตลดลงได เรามาลองดตวอยางของการถายทอดคณสมบตกนอกสกตวอยางหนง สมมตวาเราม class ตาง ๆ ดงทแสดงใน diagram น

Page 178: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 173 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ภาพท 6.2 ตวอยาง class ทเกยวของกบ shape ตาง ๆ โดยกาหนดใหการถายทอดคณสมบตเปนไปดงทเหนใน diagram คอ Shapes เปน base class Polygons และ Circle เปน class ลกของ Shapes สวน Triangle Rectangle และ Square เกดมาจาก class Polygons ในทก ๆ class เรากาหนดใหม method what() เพยง method เดยว ดงทแสดงไวใน code ทเหนน //Shapes.java - Base class for all shapes class Shapes { //self info. protected String what() { return "I am a shape"; } //Polygons.java – Polygon class Polygons extends Shapes { //self info. protected String what() { return "I am a polygon."; } } //Circle.java - sub-class of Shapes class Circle extends Shapes { //self info protected String what() { return "I am a circle."; } } //Triangle.java - sub-class of Polygons class Triangle extends Polygons { //self info. protected String what() { return "I am a triangle."; } } //Square.java - sub-class of Polygons

Shapes

Polygons Circle

RectangleTriangle Square

Page 179: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 174 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class Square extends Polygons { //self info. protected String what() { return "I am a square."; } } //Rectangle.java - sub-class of Polygons class Rectangle extends Polygons { //self info. protected String what() { return "I am a rectangle."; } } เราเขยนกาหนดใหโปรแกรมตรวจสอบเปนดงน //TestShapes.java - driver program class TestShapes { public static void main(String[] args) { //creating different shape objects from Shapes Shapes shape = new Shapes(); Shapes poly = new Polygons(); Shapes sq = new Square(); Shapes cir = new Circle(); //display info. about particular shapes System.out.println(shape.what()); System.out.println(sq.what()); System.out.println(cir.what()); System.out.println(poly.what()); } } ในโปรแกรมตรวจสอบเราไดสราง object สตวจาก class Shapes แตทาการกาหนดการสรางผานทาง constructor ของ class นน ๆ ทเราตองการสราง เชน Shapes sq = new Square(); ถามองดอยางผวเผนจะเหนวาการประกาศแบบนไมนาทจะทาได เนองจากวาเรากาหนดให sq เปน object ทมสถานะเปน Shapes แตกลบไปเรยก constructor ของ Square แต Java ยอมใหการสราง object แบบนเกดขนไดกเพราะวา Square เปน class ทเกดมาจาก class Shapes (พดงาย ๆ กคอ Circle เปน Shapes แบบหนง) และภายใน class Shapes เรากาหนดใหม method what() อย ดงนน class ลกทเกดมากสามารถทจะเขาหา method นไดแต ภายในตว class ลกทงหมดกม method what() อยดงนนการเรยก method what() ขนมาใชจงเปนการเรยก method ทมอยภายใน class ลก (overriding) ดงทแสดงใหเหนจากผลลพธน I am a shape I am a square. I am a circle. I am a polygon.

Page 180: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 175 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Polymorphism (ความมรปแบบทหลากหลาย) การทางานในลกษณะทไดกลาวมานนเราเรยกวา late binding หรอทเรยกกนมากมายในหนงสอหลาย ๆ เลมวา polymorphism ซงหมายถงความเปลยนแปลงรปแบบตามสภาพของ object ทไดถกสรางขน หรอทเปนอย คาวา late binding หมายถงเวลาท compiler จดสรรหนวยความจาใหกบตวแปรในขณะทโปรแกรมกาลงถก execute (run อย) ไมใชในขณะทกาลง compile โปรแกรม Polymorphism ทาไดเฉพาะ method เทานนเราไมสามารถจะใชวธการแบบนกบตวแปรทอยใน class ได การเขาหาตวแปรจะตองทาผานทาง object ทเกดจาก class นน ๆ เทานน สมมตวาเราตองการทจะเขยน method ทคานวณหาเสนรอบวงของ object ตาง ๆ ทสรางขนมาจาก class Shapes เรากอาจทาไดดวยการเขยน method ลงไปใน class นน ๆ (ทถกสรางมาจาก class แม) แตการกระทาดงกลาวคงไมคอยดเทาไรนก ถาเราไมรวา object ทเราตองการสรางขนมานนรปรางหนาตาเปนอยางไร และคงจะไมคอยเขาทาเทาไรนกทจะหาเสนรอบวงของ shape ทเรายงไมรวาเปน shape อะไร แต Java เออโอกาสใหเราสามารถทจะประกาศ (declare) method ใน class แมแตไปกาหนดหนาท (define) ใน class ลก วธการดงกลาวเราเรยกวา การสราง abstract class Abstract class เปน class ทมการประกาศ method ใน class แม แตไมมการกาหนดหนาทใด ๆ เรองของการกาหนดหนาทจะเปนภาระของ class ลก ดงเชน ตวอยางตอไปน //Shapes.java - Base class for all shapes public abstract class Shapes { private String iAm; Shapes(String whatIam) { iAm = new String(whatIam); } //self info. public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("I am a " + iAm); return new String(buffer); } //dummy method - implementation is done in derived classes //to calculate a perimeter of a shape public abstract double perimeter(); } เราเปลยนแปลง class Shapes ของเราใหเปน abstract class พรอมทงประกาศ method perimeter() ทไมม code ใด ๆ อยเลย หลงจากนนเรากสราง class อน ๆ ทไดรบการถายทอดคณสมบตจาก class Shapes ดงน //Polygons.java – Polygon public abstract class Polygons extends Shapes { //constructor Polygons(String type) { super(type); } //self info. public String toString() { return super.toString();

Page 181: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 176 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} //dummy method to be implemented by derived classes public abstract double perimeter(); } //Triangle.java - sub-class of Polygons public class Triangle extends Polygons { private double side1, side2, side3; //constructor Triangle(String type, double side1, double side2, double side3) { super(type); //calling base-class constructor this.side1 = side1; this.side2 = side2; this.side3 = side3; } //self info. public String toString() { return super.toString(); } //calculating a perimeter of this triangle public double perimeter() { return side1 + side2+ side3; } } //Circle.java - sub-class of Shapes public class Circle extends Shapes { private double radius; //constructor Circle(String type, double radius) { super(type); this.radius = radius; } //self info public String toString() { return super.toString(); } //calculating a perimeter of this circle public double perimeter() { return 2.0 * Math.PI * radius; } } //Square.java - sub-class of Polygons public class Square extends Polygons { double side; //constructor

Page 182: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 177 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Square(String type, double side) { super(type); this.side = side; } //self info. public String toString() { return super.toString(); } //calculating a perimeter of this square public double perimeter() { return side * 4; } } หลงจากทเราไดสราง class Polygons class Circle class Triangle และ class Square พรอมทงกาหนดหนาทของ method perimeter() ใน class Circle class Triangle และ class Square เรยบรอยแลวเรากเขยนโปรแกรมเพอตรวจสอบวา method ของเราใชงานไดถกตองหรอไม ดงน //TestShapes.java - driver program class TestShapes { public static void main(String[] args) { Shapes cir, tri; Polygons sq; //instantiate shapes sq = new Square("square", 4.0); cir = new Circle("circle", 2.0); tri = new Triangle("triangle", 3.0, 4.0, 5.0); //display info. about particular shapes System.out.println(sq + " with a perimeter of: " + sq.perimeter()); System.out.println(cir + " with a perimeter of: " + cir.perimeter()); System.out.println(tri + " with a perimeter of: " + tri.perimeter()); } } ในโปรแกรม TestShapes.java เราประกาศตวแปร cir และ tri จาก class Shapes ตวแปร sq จาก class Polygons สาเหตทเราประกาศตวแปรแทนการสราง object กเพราะวา Java ไมยอมใหเราทา เนองจากวา class Shapes และ class Polygons เปน class ทถกกาหนดใหเปน abstract class แตเราสามารถทจะใชตวแปรทงสามในการสราง object (instantiation) จาก class Circle class Square และ class Triangle ได ประโยคในการสราง object ทงสาม sq = new Square("square", 4.0); cir = new Circle("circle", 2.0); tri = new Triangle("triangle", 3.0, 4.0, 5.0); อาจดแปลกไปจากการสราง object ทเราไดเคยทามา แตเราสามารถทาไดกเพราะวา class Shapes เปน base class ของ class ทงหมด สวน class Polygons กเปน base class ของ class Square และ class

Page 183: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 178 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Triangle การสราง object ทงสามจงสามารถทาได พดงาย ๆ กคอวา ทง sq cir และ tri ตางกเปน shape ทงนน (e.g. a square is a shape, a circle is a shape, a triangle is a shape etc.) ผลลพธทเราไดจากการ run คอ I am a square with a perimeter of: 16.0 I am a circle with a perimeter of: 12.566370614359172 I am a triangle with a perimeter of: 12.0 Polymorphism มประโยชนมากในการกาหนดหนาทของ method ท object ตาง ๆ ใชรวมกน ซงหนาทตาง ๆ เหลานจะขนอยกบคณลกษณะของ object ทเกดจาก class นน ๆ ดงทเราไดแสดงใหดในการหาเสนรอบวงของรปทรงตาง ๆ หากเราตองการเรากสามารถทจะสราง array ในการเกบ shape ตาง ๆ เหลานได ดงตวอยางทแสดงใหเหนน //TestShapes.java - driver program class TestShapes { public static void main(String[] args) { Shapes []shapes = new Shapes[5]; //instantiate 5 shapes for(int i = 0; i < 5; i++) shapes[i] = randomShape(); //display info. about particular shapes for(int i = 0; i < 5; i++) { System.out.print(shapes[i] + " with a perimeter of: "); System.out.println(shapes[i].perimeter()); } } public static Shapes randomShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle("circle", Math.random() * 12.0); case 1: return new Square("square", Math.random() * 10.5); case 2: return new Triangle("triangle", 2.5, 4.0, 5.5); } } } เราเลอกทจะใหการสรางรปทรงตาง ๆ เกดแบบ random ดงนนเราจงเขยน method randomShape() ขนมาใชสาหรบการสรางรปทรงทไมมขอกาหนดทตายตว รปทรงทเกดขนจะถกกาหนดโดย method random() ของ class Math ผลลพธทไดจากการ run คอ I am a square with a perimeter of: 15.282560130191253 I am a triangle with a perimeter of: 12.0 I am a circle with a perimeter of: 0.209235603993188 I am a triangle with a perimeter of: 12.0 I am a circle with a perimeter of: 7.8292546239806695 หากเราอยากรวา object ทสรางขนมานนเกดจาก class อะไรเรากสามารถหาไดจากการใช method getClass() และ method getName() ทมอยใน class Class ของ Java เชนถาเราตองการรวา object ท shapes[0] เกบไวเกดมาจาก class อะไรเรากใชคาสงดงน

Page 184: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 179 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Class object = shapes[0].getClass(); System.out.println(object.getName()); ถาเราอยากรวา object ตวนม class แมหรอไมเรากใช method getSuperclass() เชน Class shape = object.getSuperclass(); System.out.println(shape.getName()); ยงม method ใน class Class อกหลายตวทเราสามารถนามาใชได แตโดยสวนใหญแลว เราแทบทจะไมตองใช method เหลานในการพฒนาโปรแกรมทวไปเลย เพราะ method เหลานจะใหขอมลทเกยวกบ class ทผใช (หรอ ของ Java) สรางขนมาเทานนเอง การสงและรบ object ตวอยางตอไปนเปนการสง object เขาไปใน method พรอมกบการสง object กลบดวยการเปลยนแปลงบางอยาง สมมตวาเราตองการสราง วงกลมจาก สเหลยมดานเทาทมอยแลว เรากอาจเขยน method ททาหนาทนใหเรา ดงน //SquareToCircle.java - Passing and returning object to/from method class SquareToCircle { public static void main(String []args) { Shapes square; //a square object Shapes circle; //a circle object //creating a square with side = 3 square = new Square("square", 3.0); System.out.println(square + " with an area of " + square.area()); //creating a circle from a square circle = SqToCir(square); System.out.println(circle + " with an area of " + circle.area()); } //method to convert a square to a circle public static Shapes SqToCir(Shapes square) { //finding a radius from an area of a square double SqArea = square.area(); double radius = Math.sqrt(SqArea / Math.PI); //instantiating a circle Circle circle = new Circle("circle", radius); return circle; } } เพอใหการทางานของเราประสพผลสาเรจ เราไดเพม abstract method area() ใน class Shapes และ class Polygons และทาการกาหนดหนาทของ method area() ใน class Square และ class Circle ซงเปนการคานวณหาพนทของรปทรงทไดถกสรางขน ใน class Shapes เรากาหนด ดงน (ใน class Polygons กทาแบบเดยวกน) public abstract class Shapes { …

Page 185: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 180 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

… //code อน ๆ เหมอนเดม … … public abstract double perimeter(); public abstract double area();

} ใน class Circle เรากาหนด code ของ method area() ดงน //calculate area of this circle public double area() { return Math.PI * radius * radius; } และใน class Square เรากาหนด code ของ method area() ดงน //calculate area of this square public double area() { return side * side; } ในตวโปรแกรมของเรา เราสราง object สองตวคอ square และ circle โดยกาหนดให square มความยาวของดานแตละดานเทากบ 3.0 หลงจากทแสดงขอมลของ square เรยบรอยแลวเรากสง square ไปให method SqToCir() ซงเปน method ททาการเปลยน square ใหเปน circle โดยกาหนดใหทงสอง object มพนทเทากน public static Shapes SqToCir(Shapes square) { //finding a radius from an area of a square double SqArea = square.area(); double radius = Math.sqrt(SqArea / Math.PI); //instantiating a circle Circle circle = new Circle("circle", radius); return circle; } เราเรมตนดวยการหาพนทของ square ทสงเขามา หลงจากนนเรากหารศมของวงกลมทเราตองการสรางจากพนท ทหาได เมอไดแลวเรากสราง circle ดวยรศมน เสรจแลวจงสงวงกลมทไดนกลบไป ผลลพธทเราไดจากการ run โปรแกรมของเราคอ I am a square with an area of 9.0 I am a circle with an area of 9.0 ขอดของการกาหนดให base class เปน abstract class นน กคอ เราไมตองกาหนดหนาทของ method ใน class แม เพราะวาเราอาจไมรขอมลทงหมดท method ตองการใช ดงเชน method perimeter() และ method area() เนองจากวาเรายงไมรวา shape ทมอยเปน object ชนดอะไร ขอมลเปนอยางไร แตเรารขอมลทงหมดท Circle และ Square ตองการใชในการคานวณหาเสนรอบวง และพนทจาก การสราง object ของ class ทงสอง

Page 186: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 181 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การสราง Interface จากเทคนคการใช polymorphism ในตวอยางกอนหนาน เราตองกาหนดใหม method ใน class แม และไปกาหนดหนาทของ method เหลานใน class ลก ซงเปนการสราง class ในลกษณะทซาซอนพอสมควร ถาเราตองคณสมบตของ polymorphism ใน class ทเกดจาก class แมน เรากไมจาเปนทจะตองสราง class แมขนมา แตไปสราง interface ขนมาแทน Interface เปนทรวบรวมคาคงท และ abstract method ตาง ๆ ทจะตองมการเรยกใชใน class อน ๆ ทเรยก interface นไปใช การสราง interface กไมยาก แทนทเราจะใชคาวา class เรากใชคาวา interface แทน เราจะใช class ตาง ๆ ทเราไดสรางไวกอนหนานในเรองของรปทรงตาง ๆ เปนตวอยาง และเราจะตองทาการเปลยนแปลง class ตาง ๆ ดงน ใน class Shapes และ class Polygons เราจะตดเอา abstract method perimeter() และ area() ออกพรอมกบเปลยนการประกาศ class Shapes ใหเปนดงน public abstract class Shapes implements Calculate { private String iAm; Shapes(String whatIam) { iAm = new String(whatIam); } //self info. public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("I am a " + iAm); return new String(buffer); } } เราเพมคาวา implements Calculate เขาสดานหลงสดของ class Shapes โดยมเงอนไขวาเราตองม interface ชอ Calculate อยแลว การสราง interface กทาไดไมยาก เราเพยงแตกาหนดให Calculate เปนชอของ interface ทเราตองการใช พรอมทงกาหนดใหม method ตาง ๆ ทเราตองการทจะใหมใน class อน ๆ เชน //interface for Shapes public interface Calculate { double perimeter(); double area(); } ในการเขยน Method ทอยใน interface นนเราไมจาเปนทจะตองกาหนดนโยบายของการเขาหา การกาหนดนโยบายจะตองทาใน class ทเรยกใช (implement) interface น class อน ๆ ทเหลออยกไมมการเปลยนแปลงอะไรมากมาย ยกเวน การคานวณหาพนทของรปทรงตาง ๆ ใน class Triangle เราเพม method //calculating an area of this triangle //using Huron's formula public double area() { double s = perimeter() / 2.0; double area = Math.sqrt((s * (s-side1) * (s-side2) * (s-side3))); return area; }

Page 187: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 182 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ใน class Circle เราเพม method //calculate area of this circle public double area() { return Math.PI * radius * radius; } ใน class Square เราเพม method //calculate area of this square public double area() { return side * side; } หลงจากทเปลยนแปลง code บางสวนในโปรแกรมทดสอบ ดงน //TestShapes.java - driver program import java.text.DecimalFormat; class TestShapes { public static void main(String[] args) { Shapes []shapes = new Shapes[5]; //instantiate 5 shapes for(int i = 0; i < 5; i++) shapes[i] = randomShape(); //display info. about particular shapes DecimalFormat f = new DecimalFormat("0.00"); for(int i = 0; i < 5; i++) { System.out.print(shapes[i] + " perimeter = "); System.out.print(f.format(shapes[i].perimeter())); System.out.println(" area = " + f.format(shapes[i].area())); } } public static Shapes randomShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle("circle", Math.random() * 12.0); case 1: return new Square("square", Math.random() * 10.0); case 2: return new Triangle("triangle", 4.0, 5.0, 6.0); } } } ผลลพธทไดคอ I am a triangle perimeter = 15.0 area = 9.90 I am a square perimeter = 10.32 area = 6066 I am a circle perimeter = 45.32 area = 163.46 I am a triangle perimeter = 15.00 area = 9.92 I am a circle perimeter = 6.76 area = 3.64

Page 188: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 183 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เนองจากวาเราไดทาการเรยกใช interface Calculate ใน class แม ดงนนเราไมจาเปนทจะตองเรยกใช interface Calculate ใน class ลกเพราะ class ลกเหลานไดรบการถายทอดคณสมบตจาก class แมเรยบรอยแลว เหตผลอกอยางหนงทเรากาหนดให class Shapes มการ implements Calculate กคอ เราไมตองการเปลยนแปลง code ทเราไดเขยนขนกอนหนานมากมายนก เรามาลองดตวอยางของการใช interface ท Java มใหสกตวอยางหนง โดยเราจะเรยกใช interface ActionListener ในการตรวจจบเหตการณทจะเกดขนจากตวโปรแกรม ตวอยางนอาจมขอมลทเรายงไมไดพดถงมากพอสมควร แตประเดนหลกทตองการแสดงกคอการเรยกใช interface เราจะปรบปรงโปรแกรม Interests.java ทเราไดเขยนขนในบททสาม ซงเปนโปรแกรมสาหรบการคานวณหาดอกเบยทบตน เราจะสราง class ขนใหมดงน class Account ใชเปนการเกบ balance คานวณดอกเบย แสดงผล class นเรยกใช interface BankRate class Timer เปน class ทมอยใน Java ใชสาหรบการกระทาทตองใชเวลา class Interests1 เปนโปรแกรมทดสอบสวนตาง ๆ ทเราสรางขน interface BankRate ใชเกบคาคงท RATE ทใชในการคานวณหาดอกเบย interface ActionListener ใชในการตรวจสอบเหตการณทเกดจากผใชโปรแกรม เชน ออกจากโปรแกรม เรากาหนดใหความสมพนธของ class เปนไปตาม diagram ทเหนน

ภาพท 6.2 การเรยกใช interface เราเรมตนดวย interface BankRate และ class Account //interface for bank rate public interface BankRate { double RATE = 5.0; } //Account.java public class Account implements BankRate { private double balance; //constructor - initializing balance Account(double balance) { this.balance = balance; } //method to get balance protected double getBalance() { return balance; } //method to deposit

Account

BankRate ActionListener

Timer

GetInterest

interface

Page 189: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 184 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

protected void deposit(double amount) { balance += amount; } //method to calculate interest protected double interest() { return balance * RATE / 100.0; } //method to display info. about this account public String toString() { return "Balance = " + getBalance(); } } เราเขยน class Account อยางงาย ๆ โดยกาหนดใหม method สาหรบการกาหนด balance การคานวณหาดอกเบย และการแสดงผลผานทาง method toString() ตอไปเราจะมาด class Interests1 ซงเปนโปรแกรมทดสอบการใชงานของ class และ interface //Interests1.java import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import javax.swing.Timer; class Interests1 { public static void main(String[] args) { //create account with initial balance of 1000 final Account acc = new Account(1000); //inner class performing interest calculation //and listening to event from user //stop performing when user hit stop button in //the dialog window class GetInterest implements ActionListener { public void actionPerformed(ActionEvent event) { double ints = acc.interest(); acc.deposit(ints); System.out.println(acc); } } //create object from class GetInterest GetInterest intsPeek = new GetInterest(); //set performing time interval to one second final int DELAY = 1000; //calling actionPerformed() every 1000 milliseconds Timer t = new Timer(DELAY, intsPeek); //start the timer t.start(); //display dialog window - stop performing and exit //program when user hit the button JOptionPane.showMessageDialog(null, "Stop?"); System.exit(0); } }

Page 190: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 185 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ในโปรแกรม Interests1.java เราสราง object acc จาก class Account ดวยคา balance เรมตนท 1000 ภายใน method main() เราสราง class GetInterest ทเรยกใช interface ActionListener ของ Java ซงจะคอยตรวจสอบเหตการณ (event) ทอาจเกดขนจาก user พรอมทงการคานวณหาดอกเบย method actionPerformed() จะถกเรยกโดย object intsPeek จาก class Timer ดวยคา delay 1 วนาท ดวยประโยคน Timer t = new Timer(DELAY, intsPeek); แตกระบวนการทงหมดจะเรมไดดวยการเรยก method start() ของ class Timer ดงน t.start() โปรแกรมของเราจะคานวณหาดอกเบยไปจนกวา user จะกดปม OK ทแสดงไวใน dialog window ทปรากฏอยในหนาจอ ซง dialog window นถกสรางขนมาดวยคาสง JOptionPane.showMessageDialog(null, "Stop?"); ซงมหนาตาดงน

เมอ user กดปม OK เรากจะยตโปรแกรม และออกจากระบบดวยคาสง System.exit(0); ตวอยางผลลพธทไดจากการ run โปรแกรมในชวงเวลาหนง กอนการกดปม คอ Balance = 1050.0 Balance = 1102.5 Balance = 1157.625 Balance = 1215.50625 Balance = 1276.2815624999998 Balance = 1340.0956406249998 Balance = 1407.1004226562497 Balance = 1477.4554437890622 Balance = 1551.3282159785153 Balance = 1628.894626777441 Balance = 1710.3393581163132 Balance = 1795.8563260221288 Balance = 1885.649142323235 Balance = 1979.931599439397 เราตองการทจะแสดงใหเหนถงการใช interface ทงทมอยใน Java และทเขยนขนเอง สวนการใชสวนประกอบอน ๆ ท Java มใหเปนเพยงสงทผอานจะไดสมผสในโอกาสตอไป เรามทางเลอกสองทางในการสราง และกาหนดหนาทของ method ดงทเราไดพดไว คอ 1. กาหนดให class แมเปน abstract class พรอมทงกาหนดใหม ชอของ method ทตองการ การ

กาหนดหนาทของ method จะเปนภาระของ class ลกเอง

Page 191: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 186 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

2. กาหนดให class เรยกใช interface ทมการกาหนดชอของ method และ class ตองกาหนดหนาทของ method นนเอง

สรป เราไดพดถงการสราง class ใหมจาก class ทมอยกอนแลว การถายทอดคณสมบตจาก class แมส class ลก การ override method การใช polymorphism การสรางและใช interface โดยสรปแลวสงสาคญทเราไดพดไวคอ

เราสามารถสราง class ใหมจาก class ทมอยกอนแลวดวยการใชคาวา extends ซง class ทเรา extends มานนเราเรยกวา base class หรอ parent สวน class ทเราสรางขนใหมเราเรยกวา sub class หรอ child

เราสราง abstract class ดวยการใชคาวา abstract ซงภายใน class ทเปน abstract class นนจะม method ประกาศอย แตหนาทของ method ยงไมไดถกกาหนด การกาหนดจะทาใน class ลกเดทานน และเราไมสามารถทจะสราง object จาก abstract class ได

sub class ไมไดรบการถายทอด constructor ของ super class ถาเรากาหนดนโยบายการเขาหาของ method หรอตวแปรใหเปน private ใน class แม class ลกจะไมสามารถเขาหาตวแปร หรอ method ได

ตวแปรทประกาศจาก class แมสามารถทจะใชเปนตวชไปยง object ของ class ลกได ซงทาใหการเรยกใช method ทอยใน class ลกเปนไปได

abstract class เปน class ทไมตองกาหนดหนาทให method ทก ๆ ตวใน class interface ประกอบไปดวย คาคงท abstract method และ inner class class ทไมกาหนดหนาทใหกบ method ทกตวทตวมนเองตองใช interface จะตองประกาศใหเปน

abstract class แบบฝกหด 1. จากขอมลทใหเปนคในแตละขอ จงแสดงถงความสมพนธวาสวนไหนเปน super class และสวนไหน

เปน sub class ผจดการ ลกจาง นกศกษา อาจารย คน นกศกษา อาจารย บคลากร สาม ภรรยา พอ ลก 2. สมมตวา class RumRaisin extends มาจาก class Icecream จงหาวาประโยคใดตอไปนเปน

ประโยคท Java ยอมรบ RumRaisin scoop1 = new RumRaisin(); Icecream scoop2 = new Icecream; scoop2 = scoop1; scoop1 = scoop2; scoop2 = new RumRaisin(); scoop1 = new Icecream(); 3. จงวาด diagram ทแสดงถงความสมพนธของการถายทอดคณสมบตของ class ทใหน บคลากร ผจดการ นกศกษา อาจารย หองเรยน อปกรณประกอยการเรยน

Page 192: Beginning JAVA [Thai]

บทท 6 การสราง class ใหมจาก class เดม และ การถายทอดคณสมบต 187 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

รองอธการฝายวชาการ รองอธการฝายบรหาร บรรณารกษ เจาหนาทการเงน หวหนาฝายการเงน 4. เราไดพดถงการใช method clone() ในบททเราพดถงเรอง array จง override method clone()

เพอทาการสราง object ใหมจาก class Shapes ทไดกลาวไวในบทน 5. จงเพม method withdraw() ททาหนาทในการถอนเงนออกจากบญช ของ class Account ทได

กลาวไวในบทน ใหเขยนโปรแกรมทดสอบ 6. จาก class Shapes ในบทน class ทไมไดพดถงและไมมการกาหนดหนาทใด ๆ เลย คอ class

Rectangle จงเขยน code ททาให class Rectangle นสมบรณ 7. จงออกแบบ class Student ทเกบขอมลของนกศกษาวทยาลยแหงหนง โดยใหม sub class ทมทง

นกศกษาระดบปรญญาตร และระดบปรญญาโท รวมไปถงนกศกษาภาคพเศษ พรอมทงเขยน method ในการกาหนด และเขาหาขอมลเหลาน กาหนดใหม method toString() ในทก class สาหรบการแสดงขอมลของ object ทเกดจาก class นน ๆ ใหเขยนโปรแกรมทดสอบ

8. จงออกแบบ class Employee ทม sub class เปน TempEmployee และ RegularEmployee โดย

กาหนดใหลกจางทกคนม ชอ และอตราจางงานทคดเปนจานวน บาท ตอชวโมง จงเขยน method ททาการคานวณหาคาจางของลกจางทกคน โดยกาหนดใหการคดคาจางของ TempEmployee ขนอยกบจานวนชวโมงททา หากทาเกน 40 ชวโมงใหคดคาจางเพมเปน หนงเทาครงของอตราจางประจา ของจานวนชวโมงททาเกน สวนลกจางประจา (RegularEmployee) จะไดคาจางตามอตราทไดตกลงไวลวงหนาโดยไมคานงถงจานวนชวโมงของงานททา จงใชเทคนคของ polymorphism ในการออกแบบ ใหเขยนโปรแกรมทดสอบ

* class Employee ควรเปน abstract class 9. จงปรบปรง class Shapes หรอ sub class ทมาจาก Shapes ใหม method ในการสราง object จาก

class หนงใหเปน object จากอก class หนง ดงเชนททาเปนตวอยางในการสราง object Circle จาก Square จงเขยนโปรแกรมทดสอบ

Page 193: Beginning JAVA [Thai]

ในบททเจดนเราจะพดถงการใช และการออกแบบ exception หรอทเรยกวาการควบคมและดกจบ error ทอาจเกดขนในการ compile และ run โปรแกรม หลงจากจบบทนแลว ผอานจะไดทราบถง

o ความหมายของ exception o วธการใชและควบคม exception o การใช throws และ try o การออกแบบ และใช exception ทเขยนขนเอง

ในภาษา Java นน exception เปนการบอกถงสงผดปรกตทเกดขนในโปรแกรม ซงอาจเปน error หรอเหตการณทไมคอยเขาทาทตองการความดแลเปนพเศษ โดยทวไปในการเขยนโปรแกรมทดนน เราจะตองตรวจสอบถงเหตการณทอาจทาใหโปรแกรมของเราลมเหลวในการทางาน เชน ขอมลถกหารดวยศนย เขาหาขอมลใน array ดวยการใช index ทไมมอยจรง หรอ อางถงหนวยความจาทเปน null เปนตน ถงแมวาเรามวธการตรวจสอบ error ตาง ๆ เหลานดวยการใช if-else หรอ การตรวจสอบอน ๆ ททาใหโปรแกรมของเราทางานไดราบรน แตจะทาให code ของเราดแลววนวายเพราะถามการตรวจสอบ error มาก code ของเรากจะดซบซอนมากยงขน แตไมไดหมายความวาเราจะไมตรวจสอบ และดกจบ error เหลาน การนาเอา exception เขามาเปนตวชวยในการตรวจสอบและดกจบ ทาใหเกดการแยกสวนของ code ททางานไดราบรน ออกจากสวนของ code ทจดการเกยวกบ error ทาใหเราสามารถทจะคนหาสวนของ code ทงสองไดงายขน ถามการเปลยนแปลง code ในอนาคต ขอดอกอนหนงของ exception กคอ ทาใหการตรวจสอบและดกจบเปนไปอยางเฉพาะเจาะจง ตรงกบ error ทเกดขน ทาใหการแกไขเปนไปอยางถกตอง และเนองจากวา error มหลากหลายรปแบบ เราตองเขยน code ขนมารองรบไมเชนนนแลว โปรแกรมของเรากจะไมผานการ compile เราไมจาเปนทจะตองใช exception ในการตรวจสอบและดกจบ error ในโปรแกรมเสมอไป เพราะการใช exception จะเสยคาใชจายในการประมวลผลมาก ทาใหโปรแกรมทางานชาลง ดงนนเราจะตองตดสนใจใหดวาควรจะใช exception ในกรณไหน อยางไร ตวอยางของโปรแกรมทไมตองใช exception กนาจะเปนการใสขอมลนาเขาแบบผด ๆ ของ user ซงถอเปนเรองปกต ถาเรามวแตเสยเวลาในการดกจบดวยการใช exception แทนการตรวจสอบและดกจบทวไปโปรแกรมของเรากจะเสยเวลาในการประมวลผลสวนอน ๆ ไป การใช exception ใน Java นนจะโดยทวไปจะเปนการโยน (throw) การจดการ error ทเกดขนใหกบ สวนของ code ททาหนาทในดานการจดการกบ error นน ๆ ทเกดขน ซง code สวนนจะคอยดกจบ (catch) ถามการโยนเกดขน แตไมจาเปนท code สวนนจะตองแกไข error ทเกดขนอาจเปนเพยงการดกจบเทานน เพอใหโปรแกรมทางานตอไปไดเทานน เราคงไมพดถงขอมลตาง ๆ ทเกยวกบ error และ exception มากนกแตจะเนนการใช exception ในการตรวจสอบและดกจบ error แบบพอประมาณ ผทสนใจกสามารถทจะหาอานไดจากหนงสอ Java ทว ๆ ไป หรอใน web sit ของ Java เอง Exception โดยปกตจะเปน object จาก sub class (class ใด class หนง) ของ class Throwable ท Java มให และ class หลก ๆ สอง class ทเกดจาก class Throwable โดยตรงทเปน class หลกของ class ทเปน class เฉพาะของการจดการกบ error คอ class Error และ class Exception (ภาพท 7.1)

Page 194: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 189 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ภาพท 7.1 Class Throwable และ sub classes โดยการออกแบบของ Java เราไมควรทจะ catch error ทเกดขนจากการตรวจสอบของ class Error เพราะ error ทเกดขนจะเปน error ท โดยทวไปจะไมเกดขน (หรอไมคาดวาจะเกด) ซงมอยสาม class คอ ThreadDeath LinkageError และ VirtualMachineError เราคงจะไมเขาไปวนวายกบ class ทงสามเพราะวา เราไมสามารถทจะแกไข error ทเกดขนนไดโดยตรง และตองใชการตรวจสอบอยางละเอยดกบ error ทเกดขน (แตคงตองหวงในใจวา error ทวาคงไมเกดขนกบเรา) เราจะมาดตวอยางการใช exception ในการจดการกบ error ทเกดขนในโปรแกรมของเรา ดวยโปรแกรมตวอยางตอไปน //ThrowException.java class ThrowException { public static void main(String[] args) throws Exception { int number = 10; int divider = 0; System.out.println("Divide " + number + " by " + divider); int result = number / divider; System.out.println("Result is " + result); } } โปรแกรมตวอยางดานบนนทาการ throw exception ซงเปน exception ทเกดขนในขณะทโปรแกรมกาลงไดรบการประมวลผล (เชน การหารตวเลขทเปน int ดวย 0 – เราตงใจให error นเกดขน) โปรแกรมตวอยางของเราไมไดทาการดกจบใด ๆ ทาแตเฉพาะการตรวจสอบ error ทเกดขนเทานน ดงทเหนจากผลลพธของการ run น Divide 10 by 0 java.lang.ArithmeticException: / by zero at ThrowException.main(ThrowException.java:10) จะเหนวา Java จะฟองใหเรารวา error ทเกดขนเปน error ชนดไหน (ArithmeticException) ทพยายามหาร int ดวย 0 พรอมกบบอกวาเกดขนในบรรทดทเทาไร หลงจากนนกยตการทางาน ถาหากวาเราตองการทจะแกไข หรอทาการใด ๆ สกอยางหนงกบ error ทเกดขนเราตองใช try และ catch ดงตวอยางตอไปน

Throwable

ExceptionError

Other sub classes Other sub classes

Page 195: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 190 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//TryAndCatchExample1.java //adopted from Ivor Horton's class TryAndCatchExample1{ public static void main(String[] args) { int number1 = 15; int number2 = 0; try { System.out.println("Try to divide by zero in a try block."); int result = number1 / number2; System.out.println("Leaving a try block."); } catch(ArithmeticException ex) { System.out.println("Exception caught in a catch block."); } System.out.println("After a try block."); } } โปรแกรม TryAndCatchExample1.java เปนโปรแกรมตวอยางการใช try และ catch ในการจดการกบการหาร int ดวย 0 (เราจะไมใชการ throws exception เหมอนกบตวอยางแรก) เรากาหนดให number1 มคาเปน 15 และ number2 มคาเปน 0 พรอมทงกาหนดให result = number1 / number2; ใน block ของ try ซงประโยคดงกลาวจะทาใหเกดการโยน exception ไปยง block ของ catch และใน block ของ catch เราจะดกดวย exception ทชอ ArithmaticException เราไมไดทาอะไรมากมายไปกวาการแสดงขอความวามการดกจบ error ผลลพธทไดจากการ run คอ Try to divide by zero in a try block. Exception caught in a catch block. After a try block. จากผลลพธทได code ทไดรบการประมวลผลคอ ประโยคทอยใน block ของ try 2 ประโยคแรก โดยเฉพาะประโยคทสอง ททาใหการประมวลกระโดดไปยง block ของ catch ทาใหประโยคทสามไมไดรบการประมวลผล และหลงจากทประมวลผลประโยคทอยใน block ของ catch แลว การประมวลผลประโยคสดทายทตามหลง block ของ catch จงเกดขน เราสามารถใช ตวแปร ex ทเราไดประกาศใน parameter list ของ method catch() แสดงถงขอความทบงบอกเกยวกบ error ทเกดขน ดวยการเพมประโยคตอไปนใน block ของ catch System.out.println(ex.getMessage()); ex.printStackTrace(); ประโยคแรกเรยกใช method getMessage() ทเกดขนทาการแสดงผลไปยงหนาจอ สวนประโยคทสองเปนการตรวจสอบถงทมาของ error ทเกดขน ดงทแสดงใหเหนจากการ run โปรแกรมอกครงหลงจากการเปลยนแปลง code ใน block ของ catch Try to divide by zero in a try block. Exception caught in a catch block. / by zero java.lang.ArithmeticException: / by zero

Page 196: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 191 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

at TryAndCatchExample1.main(TryAndCatchExample1.java:11) After a try block. เราไมจาเปนทจะตองแสดงผลทเกดขนไปยงหนาจอ สวนใหญแลวขอมลเหลานจะเปนประโยชนตอการตรวจสอบถง error ทเกดขนเทานนเอง สงทสาคญทเราตองกงวลกคอ การตรวจสอบและดกจบ error ทอาจเกดขน Java กาหนดให try และ catch เปนของคกน เราไมสามารถทจะแยก block สองออกจากกนได ถาเรากาหนดใหมประโยคอะไรกไดสกประโยคหนงระหวาง block ของ try และ catch โปรแกรมของเราจะ compile ไมผาน ดงตวอยางทมการเพมประโยคระหวาง block ทงสองน … …

System.out.println("Leaving a try block."); } System.out.pritnln("In between try and catch blocks."); catch(ArithmeticException ex) { … … ถาเรา compile เราจะได error ดงทเหนน TryAndCatchExample1.java:9: 'try' without 'catch' or 'finally' try { ^ TryAndCatchExample1.java:15: 'catch' without 'try' catch(ArithmeticException ex) { ^ 2 errors ตวอยางการใช try และ catch ท classic อกอนหนงกคอ การใช try และ catch ใน loop ดงตวอยางตอไปน //TryAndCatchExample2.java //adopted from Ivor Horton's class TryAndCatchExample2 { public static void main(String[] args) { int number = 10; for(int index = 5; index >= -1; index--) try { System.out.println("try block: index = " + index); int result = number / index; System.out.println("Leaving a try block."); } catch(ArithmeticException e) { System.out.println("Exception caught in a catch block."); System.out.println(e.getMessage()); e.printStackTrace(); } System.out.println("After a try and catch blocks."); } }

Page 197: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 192 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

กอนทจะอธบายถงการทางานของตวโปรแกรม เรามาดผลลพธทไดจากการ run try block: index = 5 Leaving a try block. try block: index = 4 Leaving a try block. try block: index = 3 Leaving a try block. try block: index = 2 Leaving a try block. try block: index = 1 Leaving a try block. try block: index = 0 Exception caught in a catch block. / by zero java.lang.ArithmeticException: / by zero at TryAndCatchExample2.main(TryAndCatchExample2.java:11) try block: index = -1 Leaving a try block. After a try and catch blocks. ประโยคใน block ของ try จะถกประมวลผลจนกวา คาของ index จะเปน 0 จงจะกระโดดไปประมวลผลประโยคทอยใน block ของ catch หลงจากนนกกลบไปประมวลผลประโยคทเหลออยใน block ของ try และประโยคทอยทายสดในโปรแกรม อกประโยคหนง จะเหนไดวาเรามทางเลอกอยสองทางในการจดการกบ error ทางแรกคอ ยตการทางาน (terminate) ของโปรแกรม หรอ code สวนนน ๆ ททาใหเกด error หรอ ทางทสอง ซงเปนทางเลอกททาใหโปรแกรม หรอ code สวนนน ๆ กลบไปรบการประมวลผลใหม (resumption) ทงสองวธเปนการตรวจสอบและดกจบ error ทดพอกน ทงนกขนอยกบลกษณะของงานททาอย ลองมาดตวอยางอกสกตวหนงในการใช class NumberFormatException ในการดกจบ error //NumFormatException.java import java.lang.Integer; class NumFormatException { public static void main(String[] args) { int inputNum, sum = 0; //reading input from argument list //only those in [0..9] for(int i = 0; i < args.length; i++) { try { inputNum = Integer.parseInt(args[i]); sum += inputNum; } //ignore input that's not a number catch(NumberFormatException e) { e.printStackTrace(System.out); } } System.out.println("Sum is " + sum); } }

เรากาหนดใหโปรแกรมของเรารบขอมลจาก command line argument ซงเปนวธการทยอมใหผใชใสขอมลตามหลงชอของโปรแกรม (ดจากผลลพธการ run) เราจะทาการหาผลรวมของตวเลขเหลานน

Page 198: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 193 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ทงหมดจนกวาผใชจะพอใจ คอ กดปม <enter> หลงจากใสขอความจนพอใจ ใน catch block เราดกจบดวย NumberFormatException ซงจะไมยอมรบขอมลนาเขาทไมใชตวเลขทเปน int และทกครงทเจอขอมลแบบนโปรแกรมจะสงรายละเอยดไปใหผใช และจะหาผลรวมของขอมลทถกตองนน ดงทแสดงไวดานลางน >java NumFormatException 1 2 3 4 p 5 6 java.lang.NumberFormatException: For input string: "p" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:426) at java.lang.Integer.parseInt(Integer.java:476) at NumFormatException.main(NumFormatException.java:12) Sum is 21 ในการสราง block สาหรบการ catch error ทเกดขนเราไมจาเปนทจะตองม catch block เพยง block เดยว เราอาจมมากกวาหนง catch block ไดแตมขอแมวา การ catch exception ตองทาจาก sub class ออกไปหา super class มฉะนนแลวการดกจบในหลาย ๆ block อาจไมเกดขน เชน try { … … } catch(Exception e) { … … } catch(ArithmeticException ex) { … .. } เนองจากวา class ArithmeticException เปน class ทเกดมาจาก class Exception ดงนน error ทเกดขนกจะถกดกจบใน catch block ทงหมด การดกจบใน catch block ทสองจงไมเกดขน เรามาลองดตวอยางการดกจบ error ในรปแบบนกนด //MultipleCatches.java class MultipleCatches { public static void main(String[] args) { //force divide by zero at index = 2 int []number = {1, 2, 0, 4}; int num = 12; //force array index out of bound at index = 4 for(int i = 0; i < number.length + 1; i++) { try { num /= number[i]; System.out.println("result = " + num); } catch(ArithmeticException e) { System.out.println("error message: " + e.getMessage()); e.printStackTrace(); } catch(ArrayIndexOutOfBoundsException e) {

Page 199: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 194 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

System.out.println("error message: " + e.getMessage()); e.printStackTrace(); } } System.out.println("After a for loop."); } } เราตองการทจะบงคบใหเกด error สองอยางคอ หารดวยศนย และเขาหา index ของ array ทไมมอยจรง โดยเรากาหนดใหขอมลท index = 2 มคาเปนศนย และให for loop ทางานเกนไปหนงครง การ run โปรแกรมตวอยางของเราทาใหเกด ผลลพธดงนคอ result = 12 result = 6 error message: / by zero java.lang.ArithmeticException: / by zero at MultipleCatches.main(MultipleCatches.java:11) result = 1 error message: 4 java.lang.ArrayIndexOutOfBoundsException: 4 at MultipleCatches.main(MultipleCatches.java:11) After a for loop. จะเหนวาโปรแกรมของเราดกจบ error ไดตามทเราตงใจไว การหารดวยศนย และการอางถง index ของ array ทไมมอยจรง ถกดกไวทงสองตว ถาเปนการจดการทเปนการพฒนาโปรแกรมจรง ๆ เราคงทาแคการดกจบไมได คงตองมกระบวนการอน ๆ ในการทาใหโปรแกรมทางานไดอยางราบรน และกระบวนการจดการกบ error ทเกดขนกตองมความซบซอนเพมขน Java ยงม block อก block หนงทเอาไว catch error ทเกดขน ทซงเปน block สดทายของการ catch ทงหมด โดยกาหนดให block นทชอวา finally Finally เปนการดกจบ error สดทายของการดกทงหมด ดงนน finally จะอยทอนไมไดนอกจาก block สดทายของ catch block ทงหมด เราจะแสดงใหด ดวยการนาเอา finally ไปใสไวเปน block สดทายในตวอยางกอนหนาน ดงน … … } catch(ArrayIndexOutOfBoundsException e) { System.out.println("error message: " + e.getMessage()); e.printStackTrace(); } finally { System.out.println("In finally block."); } … … finally block ทเราใชจะถกประมวลผลเสมอ ไมวาอะไรจะเกดขนกตามใน block อน ๆ กอนหนา ดงตวอยางของผลลพธทแสดงใหดบางสวนน …

Page 200: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 195 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

… at MultipleCatches.main(MultipleCatches.java:13) In finally block. After a for loop. โดยทวไปหนาทหลกของ finally จะเปนการเกบกวาด code ทโปรแกรมตองการประมวลผล (เชน การปด เปดไฟล)กอนออกจาก ตว method main() และกลบออกไปสระบบในทสด //ThrowsWithTry.java import java.io.*; import java.lang.Integer; class ThrowsWithTry { public static void main(String[] args) throws IOException { BufferedReader buffer; InputStreamReader isr; String input; int first, divider; //keep looping until error occur while(true) { System.out.print("Enter a number: "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); //get first number input = buffer.readLine(); first = Integer.parseInt(input); //get second number System.out.print("Enter a divider: "); input = buffer.readLine(); divider = Integer.parseInt(input); try { double result = first / divider; System.out.println("Result = " + result); } catch(ArithmeticException e) { System.out.println("Exception: " + e.getMessage()); e.printStackTrace(); } } } } โปรแกรม ThrowsWithTry.java เปนโปรแกรมทตองการแสดงการใช throws และ try – catch ควบคกน โดยตวโปรแกรมเองจะทาการอานขอมลสองตวจาก keyboard ซงกาหนดใหขอมลทงสองตวเปน int และจะทาการหาผลลพธของการหารขอมลตวแรก ดวยขอมลตวทสอง โปรแกรมจะหยดการทางานกตอเมอผใชใสขอมลทไมใชตวเลข และจะทาการฟองถาขอมลตวทสองของการหารมคาเปนศนย ผลลพธทไดจากการ run คอ Enter a number: 23 Enter a divider: 5 Result = 4.0 Enter a number: 56

Page 201: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 196 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Enter a divider: 0 Exception: / by zero java.lang.ArithmeticException: / by zero at ThrowsWithTry.main(ThrowsWithTry.java:27) Enter a number: 12 Enter a divider: 3 Result = 4.0 Enter a number: pop Exception in thread "main" java.lang.NumberFormatException: For input string: "pop" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:426) at java.lang.Integer.parseInt(Integer.java:476) at ThrowsWithTry.main(ThrowsWithTry.java:20) จากผลลพธทไดจะเหนวาโปรแกรมของเราจะฟองถามการหารดวยศนย และหยดถาขอมลไมใช int (ในตวอยางนผใชใสคาวา "pop") โปรแกรมของเราจะทางานไปเรอย ๆ ถาผใชใสขอมลทถกตองตามทโปรแกรมไดกาหนดไว แตนไมใชการตรวจสอบทดเทาไรนก ถาเราตองการทจะบอกผใชวาขอมลไมถกตอง และใหใสขอมลใหมเรากตองแกไข code ของเราใหรองรบการทาใหม ซงอาจทาไดดงน //ThrowsWithTry1.java import java.io.*; import java.lang.Integer; class ThrowsWithTry1 { public static void main(String[] args) throws IOException { BufferedReader buffer; InputStreamReader isr; String input; int first = 0, divider = 0; while(true) { System.out.print("Enter a number: "); isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); //get first number input = buffer.readLine(); first = readInt(input); //get second number only if first number is valid if(first != -1) { System.out.print("Enter a divider: "); input = buffer.readLine(); divider = readInt(input); } //perform division if both numbers are valid if(first != -1 && divider != -1) { try { double result = first / divider; System.out.println("Result = " + result); } catch(ArithmeticException e) { System.out.println("Exception: " + e.getMessage());

Page 202: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 197 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

e.printStackTrace(); } } } } //method to convert an int from a string public static int readInt(String in) throws IOException { try { int num = Integer.parseInt(in); return num; } catch(NumberFormatException e) { System.out.println("Exception caught: " + e.getMessage()); return -1; } } } เราไดเขยน method readInt() สาหรบการเปลยน string ทอานจาก buffer ใหเปน int โดยเราไดใช try และ catch ในการตรวจสอบและดกจบ error ทอาจเกดขนจากการใสขอมลผดพลาดทอาจเกดขนของผใช และเรากาหนดใหสงคา -1 กลบออกไปเพอใชเปนตวบอกให code ใน while loop รวาขอมลไมถกตอง เพอทเราจะไดไมตองอานขอมลตวทสอง ในสวนของ code ใน while loop เราไดทาการเปลยนแปลงการอาน และ การประมวลผลใหเปน //get second number only if first number is valid if(first != -1) { System.out.print("Enter a divider: "); input = buffer.readLine(); divider = readInt(input); } //perform division if both numbers are valid if(first != -1 && divider != -1) {

try { double result = first / divider; System.out.println("Result = " + result); } catch(ArithmeticException e) { System.out.println("Exception: " + e.getMessage()); e.printStackTrace(); } } โปรแกรมของเราจะทาการประมวลผลถาขอมลทงสองเปนขอมลทถกตอง ดงนนเราจงตองทาการตรวจสอบวา first และ divider มคาทถกตองหรอไมดวยการตรวจสอบกบ -1 ซงถาตรวจสอบแลวไดขอมลทถกตอง เรากจะทาการประมวลผลขอมลทงสอง ลองมาดผลลพธกน Enter a number: 23 Enter a divider: 3 Result = 7.0 Enter a number: p Exception caught: For input string: "p" Enter a number: 3 Enter a divider: p Exception caught: For input string: "p" Enter a number: 32 Enter a divider: 0

Page 203: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 198 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Exception: / by zero java.lang.ArithmeticException: / by zero at ThrowsWithTry1.main(ThrowsWithTry.java:34) Enter a number: -1 Enter a number: Exception caught: null Enter a number: จะเหนไดวาโปรแกรมของเราทางานไดอยางทไดตงใจไว คอ ตรวจสอบขอมลทงสอง พรอมทงทาการประมวลผลถาขอมลทงสองถกตอง ผอานควรสงเกตดวยวา โปรแกรมตวอยางนยงไมสมบรณเลยทเดยว ดงจะเหนไดจากการใสขอมลทเปน -1 ทาไม? พรอมกนนเรายงไมสามารถออกจากโปรแกรมได ถาไมใชคาสง <crtl> + c ในการเขยนโปรแกรมทตองรองรบการทางานทมการตรวจสอบเพอใหเกดความถกตองนน เราตองคานงถงปจจยหลายดาน ทงนกขนอยกบลกษณะของงานทเราตองเขยนโปรแกรมรองรบ โปรแกรมตวอยางของเราตองการแสดงใหเหนถงการตรวจสอบและดกจบ error และแกไขในระดบหนงเทานน ดงนนผเขยนจงไมไดแสดงถงการแกไขทงหมด เพราะขอกาหนดของงานยงไมชดเจน การสราง exception ขนมาใชเอง Java ยอมใหเราสราง exception ขนมาใชกบโปรแกรมตาง ๆ ทเราคดวานาจะเพมขอมลบางอยางใหกบผใช ถาหากม error เกดขน เชน การหารดวยศนยทเราไดเขยนขนมากอนหนาน เราอาจตองการบอกรายละเอยดใหมากกวาเดมแกผใช เราจะใชโปรแกรมการหารดวยศนยทมการเปลยนแปลงบางอยาง เปนตวอยางตอไป //TestInputValidation.java import java.io.*; import java.lang.Integer; class TestInputValidation { public static void main(String[] args) throws Exception { BufferedReader buffer; InputStreamReader isr; String input; int first, divider; while(true) { //get first number first = readInt(); //get second number only if first number is valid divider = readInt(); //perform division if both numbers are valid try { //calling method divide() int result = divide(first,divider); System.out.println("Result = " + result); } //catching user defined exception catch(ZeroDivideException e) { e.printStackTrace(System.err); } } } //method to get an int from the keyboard

Page 204: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 199 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public static int readInt() throws Exception { BufferedReader buffer; InputStreamReader isr; String input = null; int result = 0; boolean ok = false; isr = new InputStreamReader(System.in); buffer = new BufferedReader(isr); //keep looping until user enter an int while(!ok) { System.out.print("Enter a number: "); try { input = buffer.readLine(); result = Integer.parseInt(input); ok = true; } catch(NumberFormatException e) { System.out.println(e.getMessage()); e.printStackTrace(System.err); } } return result; } //method to divide first number by the second number public static int divide(int first, int second) throws ZeroDivideException { int result; try { result = first / second; } catch(ArithmeticException e) { throw new ZeroDivideException(); //throw new exception } return result; } } เราไดเปลยนโปรแกรมกอนหนานมากพอสมควรในการทจะอานขอมลใหถกตอง พรอมทงแสดงถงการเขยน exception ขนมาใชเอง เราเรมดวยการสราง method readInt() ขนมาใหม โดยกาหนดใหผใชตองใสขอมลใหถกตอง ถาไมถกเรากจะวนกลบไปถามใหมจนกวาจะได Method ตวทสองทเราสรางขนมาคอ method divide() ทรบ parameter 2 ตว ทาหนาทในการหารตวเลขตวแรกดวยตวเลขตวทสอง ภายใน method divide() นเราจะดกจบ error ทเกดขนผานทาง ArithmeticException ดวย การ throw exception ทเราไดสรางขนเอง ดวยคาสง catch(ArithmeticException e) { throw new ZeroDivideException(); //throw new exception } แตกอนทเราจะเรยกใช exception ทวานเราตองสราง code สาหรบ exception เสยกอน ซงเราไดออกแบบใหเปนการดกจบแบบงาย ๆ ดวยการสราง class ZeroDivideException จาก class Exception เพอทจะใหเราสามารถทจะไดรบการถายทอดคณสมบตจาก class Exception เรากาหนดให code ของ class ZeroDivideException มดงน //ZeroDivideException.java

Page 205: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 200 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

class ZeroDivideException extends Exception { //default constructor ZeroDivideException() { super("divide by zero"); //call super class' constructor } ZeroDivideException(String message) { super(message); } } เราไมไดทาอะไรมากไปกวาเรยกใช constructor ของ class Exception ดวยขอความทเราตองการใหปรากฏหาก error ทวานเกดขน (divide by zero) ภายในตว method main() เอง code สวนทสาคญคอ try { //calling method divide() int result = divide(first,divider); System.out.println("Result = " + result); } //catching user defined exception catch(ZeroDivideException e) { e.printStackTrace(System.err); } เราเรยก method divide() ภายใน try และถาหากการหารทเกดขนม error มนกจะถกจบใน catch block ทเราไดเรยกดวย object ทมาจาก class ZeroDivideException ทเราไดสรางขน หลงจากทลอง run ดเราไดผลลพธดงน Enter a number: 45 Enter a number: 36 Result = 1 Enter a number: 0 Enter a number: 3 Result = 0 Enter a number: pop For input string: "pop" java.lang.NumberFormatException: For input string: "pop" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:426) at java.lang.Integer.parseInt(Integer.java:476) at TestInputValidation.readInt(TestInputValidation.java:47) at TestInputValidation.main(TestInputValidation.java:16) Enter a number: 3 Enter a number: 0 ZeroDivideException: divide by zero at TestInputValidation.divide(TestInputValidation.java:64) at TestInputValidation.main(TestInputValidation.java:23) Enter a number: null (เราออกจากโปรแกรมดวยการกด <crtl> + c ณ ตาแหนงน) java.lang.NumberFormatException: null at java.lang.Integer.parseInt(Integer.java:394) at java.lang.Integer.parseInt(Integer.java:476)

Page 206: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 201 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

at TestInputValidation.readInt(TestInputValidation.java:47) at TestInputValidation.main(TestInputValidation.java:16) Enter a number: ผลลพธทไดกเปนไปตามทเราไดคาดไว คอ error ถกดกจบไวไดหมด ผอานควรสงเกตดวยวาเรายงใช loop ใน method main() ดงนนการออกจาก loop กตองใช <crtl> + c เหมอนเดม ทาใหมการดกจบ error ทเกดขนครงสดทายกอนออกจากโปรแกรม อกสวนหนงทนาสนใจในโปรแกรมของเรากคอ การสงขอความบอกถงรายละเอยดของ error ผานทาง System.err ซงเปนอกชองทางหนงท Java มใหใชสาหรบการสงขอมลทไมใชขอมลปกตออกทางหนาจอ ถงแมวาขอมลจะออกไปทเดยวกนแตชองทางการสงออก ไมเหมอนกน สาเหตทเปนเชนนกเพอใหมการแยกแยะ error ออกจากขอมลหรอผลลพธปกตของโปรแกรม เรามาดอกสกตวอยางหนง //CheckRange.java import java.lang.Integer; class CheckRange { public static void main(String[] args) { try { //getting input from argument list int first = Integer.parseInt(args[0]); int second = Integer.parseInt(args[1]); int third = Integer.parseInt(args[2]); //check if the third input is between first and second checked(first, second, third); System.out.println("Number " + third + " is in the given range"); } catch(OutOfRangeException e) { e.printStackTrace(System.err); } } //method to validate range public static void checked(int start, int stop, int num) throws OutOfRangeException { if(num < start) { String errMsg = new String(num + " < " + start); throw new OutOfRangeException(errMsg, start, stop); } if(num > stop) { String errMsg = new String(num + " > " + stop); throw new OutOfRangeException(errMsg, start, stop); } } } โปรแกรมตวอยางนรบขอมลผานทาง argument list ทเปนตวเลขสามตว โดยจะทาการตรวจสอบวาตวเลขตวทสามอยระหวางตวแรกและตวทสองหรอไม ถาไมกจะ throw exception OutOfRangeException ทไดเขยนขน ดงน //OutOfRangeException.java

Page 207: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 202 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

public class OutOfRangeException extends Exception { //default constructor OutOfRangeException() {} //constructor OutOfRangeException(String message, int p, int q) { super(message); } } จะเหนวาโดยสวนใหญแลวเราจะเรยกใช super class constructor ใหทางานใหเรา มากกวาทจะเขยน code ขนมา ซงเปนสงททาใหการออกแบบของเราไวขน เราเพยงแตเขยนถงสงทบงบอกถง error ทเกดขนวาเปนอะไรเทานนเอง จากการ run ผลลพธทเราไดคอ >java CheckRange 12 45 569 OutOfRangeException: 569 > 45 at CheckRange.checked(CheckRange.java:31) at CheckRange.main(CheckRange.java:15); E:\bc221Book\source>java CheckRange 12 45 2 OutOfRangeException: 2 < 12 at CheckRange.checked(CheckRange.java:27) at CheckRange.main(CheckRange.java:15) E:\bc221Book\source>java CheckRange 12 45 15 Number 15 is in the given range สรป ในการเขยนโปรแกรมทดนน ผเขยนจะตองคานงถง error ทอาจเกดขนในโปรแกรม ซงไดแบงออกเปนสองลกษณะใหญ คอ error ทโปรแกรมเมอรไมมทางแกไขได คอ อยนอกเหนอการควบคมของผพฒนาโปรแกรม เชน error ทเกดจากหนวยความจาไมพอเพยง สวน error อกอนหนงทผเขยนโปรแกรมตองตรวจสอบกคอ error ทเกดตอน run โปรแกรม เชน error จากการหารดวยศนย การเขาหา Index ของ array ทไมมอยจรง การปอนขอมลทไมถกกบชนดทตองการ อยางนเปนตน Exception ท Java มใหมอยมากพอสมควร และมากพอทจะเรยกใชไดเกอบทกกรณของการเขยนโปรแกรม แตถาผเขยนโปรแกรมไดพฒนาโปรแกรมทไมสามารถใช exception ท Java มใหกสามารถทจะออกแบบ exception ขนมาใชเองได ในการดก error นนผเขยนอาจสราง exception ขนมาใชในการดกจบ error เองได ทงนกขนอยกบลกษณะของงานทผเขยนโปรแกรมกาลงพฒนาอย โดยสรปแลวสงทตองควรคานงในการตรวจจบ error คอ

Exception เปนตวบงชถง error ทเกดในโปรแกรม Exception เปน object ทเกดมาจาก class Throwable เราสามารถทจะเรยกใช exception ทมาจาก Java โดยตรง หรอ สรางขนมาใชเอง ถาเราตองการทจะควบคม exception ใน method เราตองเขยน code ใน try block และไมจาเปนทจะตองม try block เพยงหนง block เทานน อาจมมากกวาหนง block ได

Code ทใชในการควบคม หรอ แกไข exception จะตองทาใน catch block ทตามหลง try block ทนทและในหนง try block เราสามารถทจะม catch block มากกวาหนงตวได

Finally เปน block ทายสดทอยใน try โดยทวไปจะใช finally block ในการเกบกวาดการทางานของโปรแกรม เชน การปดไฟล

Page 208: Beginning JAVA [Thai]

บทท 7 การตรวจสอบและดกจบ error (Exceptions) 203 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

แบบฝกหด 1. จงเขยนโปรแกรมทรบขอมลจาก keyboard เฉพาะทเปน int เทานนใหใช exception ในการดกจบ

error ทผใชอาจใสผด เชน ใสตวอกษร ใหแสดงขอความฟองทนททผใชใสผด 2. จงปรบปรงโปรแกรมทเขยนขนในขอหนง โดยเพมการตรวจสอบทไมรบตวเลขทตากวาศนย 3. จงเขยนโปรแกรมทรบขอมลจาก keyboard เปนตวเลขสามตว โดยกาหนดให ตวแรกเปนจดเรมตน

ตวทสองเปน จดจบ ของคาขององศา Celsius และตวทสามเปนตวกาหนดการเพมคา (step) ใหโปรแกรมทาการคานวณหา องศา Fahrenheit ตามขอมลทกาหนดไวในสองตวแรก และใหทาการเพมขนตามคาของขอมลตวทสาม ดงตวอยางผลลพธทแสดงใหดน

>java Temperature 0 100 10 CELSIUS FAHRENHEIT 0 32.0 10 50.0 20 68.0 30 86.0 40 104.0 50 122.0 60 140.0 70 158.0 80 176.0 90 194.0 100 212.0

ใหทาการตรวจสอบ และดกจบ error ทอาจเกดขนจากการใสขอมลทไมถกตอง เชน คาของการเพมเปนตวเลขทนอยกวาศนย (negative number) คาเรมตน มากกวาคาสดทาย และจานวนขอมลทนาเขามจานวนไมครบตามทกาหนด ตวอยางของ error ทเกดขน >java Temperature 0 100 -5 3rd arg < 0 NUMBER = -5 >java Temperature 40 20 5 Ordering Err FIRST = 40 SECOND = 20 >java Temperature 10 40 java.lang.ArrayIndexOutOfBoundsException: at Temperature.main(Temperature.java:41)

4. จงเขยนโปรแกรมทหาคาของ mn โดยกาหนดใหทง m และ n มาจาก command line argument

list ใหทาการตรวจสอบและดกจบ error ทก ๆ กรณทอาจทาใหโปรแกรมไมทางาน 5. จงปรบปรง class Account ในบททหกใหมการตรวจสอบและดกจบ error ทอาจเกดขนในการ ถอน

เงน ฝากเงน และ คดดอกเบย ถา method ใด ๆ ททาหนาทดงกลาวไมม ใหเขยนขนใหม พรอมทงเขยนโปรแกรมทดสอบ

6. จงปรบปรงโปรแกรมในขอ เจด แปด และ เกา ในบททหา ใหมการตรวจสอบและดกจบ error พรอม

ทงเขยนโปรแกรมทดสอบ

Page 209: Beginning JAVA [Thai]

ในบททแปดนเราจะพดถงการอาน และเขยนขอมลผานทาง stream หรอชองทางการสงขอมล เราจะดถงวธการ กระบวนการตาง ๆ ทเกยวของกบขอมลนาเขา และการนาขอมลออก หลงจากจบบทนแลว ผอานจะไดทราบถง

o ความหมายของ stream o Class ตาง ๆ ท Java มใหในการประมวลผลดวย stream o การสราง directory o การสราง file การเปดและปด file การอานและเขยน file o ขอแตกตางระหวาง text file และ binary file

ในการทางานทเกยวของกบไฟลใน Java นนจะตองทาผานทาง stream ซงเปนตวแทนของอปกรณทนาเขา (input) หรอสงออก (output) ขอมล เราสามารถเขยน และอานขอมลผานทาง stream ดวยวธการตาง ๆ ในรปแบบตาง ๆ กน เชน อานขอมลจาก keyboard ทละหนงตวอกษร หรอทละ 10 byte โดยทวไป ขอมลนาเขาจะมาจาก keyboard หนวยความจาสารอง (disk) หรอ อปกรณอน ๆ เชน scanner light-pen memory-card แตโดยสวนใหญแลวมกจะมาจาก keyboard และ disk ในบทนเราจะใชอปกรณทงสองทไดกลาวมา เปนชองทางหลกในการนาเขาขอมล และจะใชชองทางสงออกเพยงสองทางคอ จอ (monitor) และ เครองพมพ (printer) รปแบบพนฐานของขอมลท Java รจกมอยสองลกษณะคอ binary streams และ character streams ซงมความแตกตางกนในรปแบบของการจดเกบ ถาเราเขยนขอมลเขาส stream โดยเขยนทละ byte หรอ ทละหลาย ๆ byte เราเรยกขอมลเหลานวา binary data การเขยนจะไมมกระบวนการอนใดมายงเกยว (เชนการเปลยนขอมลใหอยในรปแบบอนกอนการจดเกบ) ขอมลจะถกสงเขาส stream ตามทปรากฏอยใน memory เชน ถา memory สวนนเกบขอมลทเปนตวเลขอย ตวเลขเหลานจะถกสงเขาส streams ตามทปรากฏใน memory ในการเกบขอมลทเปน character streams นนโดยทวไปจะทากบขอมลทเปนตวอกษร (text) เราจะใช character streams ในการอานไฟลทเปน text ตวเลขทอยในไฟลจะถกเปลยนใหอยในรปแบบท Java ไดกาหนดขน การอานตวเลขดวยการใช character streams เปนกระบวนการทยงยากมาก เพราะเราตองรวาตวอกษรทเปนตวแทนของตวเลขนนใชกตวอกษรในการเกบ เชน ถาเราสงตวเลข 17 ผานทาง character stream ตวเลขนจะถกเปลยนใหเปนคา ASCII ของ '1' และ '7' หรอ 0x310x37 (เลขฐาน 16) และสมมตวาเราเขยนเลข 727 อกตวใน stream ของเรากจะมขอมลเปน 0x310x370x370x320x37 การอานตวเลขทงสองตวออกมาจะทาไดยากมากเพราะเราไมรวาจะตองอานตวอกษรทละกตวถงจะไดขอมลทถกตองเหมอกบทไดเขยนไว เราไดทราบแลววา Java เกบขอมลในรปแบบของ Unicode ดงนนในการเขยนขอมลเขาส stream ในรปแบบของ character ขอมลจะถกเปลยน (โดยอตโนมต) ใหอยในรปแบบของการเกบ (local code) ตามทเครองนนใชอย เชนถาเครองของเราใชภาษาไทยเปนภาษาหลก รปแบบของการเกบกจะเปน code ของภาษาไทย (Java เรยกระบบนวา localization) ในการอานขอมลนน Java จะเปลยนขอมลทถกจดเกบในรปแบบของ local code ใหเปน Unicode กอน โดยสรปแลวในการเขยนและอานนน Java จะเปลยนขอมลใหเปน Unicode สวนการจดเกบนนจะจดเกบในรปแบบของภาษาทใชอยในเครอง

Page 210: Beginning JAVA [Thai]

บทท 8 Streams I/O 205 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

เราจะมาดตวอยางทเกยวของกบไฟล ในหลาย ๆ รปแบบเพอทาใหเกดความเขาใจถงวธการ และกระบวนการตาง ๆ ทเกยวของกบ input และ output เราจะเรมตนดวยการตรวจสอบขอมลตาง ๆ ทเกยวกบไฟล จากโปรแกรม FileInfo.java //FileInfo.java import java.io.*; class FileInfo { public static void main(String[] args) { //get path from command-line argument File path = new File(args[0]); //display some info. about this file if(path.exists()) { System.out.println(path + " does exist."); System.out.println("Readable : " + statusOk(path.canRead())); System.out.println("Writable : " + statusOk(path.canWrite())); System.out.println("Directory? : " + statusOk(path.isDirectory())); System.out.println("File? : " + statusOk(path.isFile())); System.out.println("Hidden? : " + statusOk(path.isHidden())); } else { System.out.println(path + " does not exist."); } } //return "Yes" or "No" public static String statusOk(boolean yes) { return yes ? "Yes" : "No"; } } โปรแกรมเรมตนดวยการสราง object path จาก class File ดวยขอมลทมาจาก command-line argument ซงอยในรปแบบ e:\bc221Book\source e:\bc221Book\source \source \bc221Book\source\FileInfo.java ตวอยางสองตวแรกอยในรปแบบทเรยกวา absolute path สวนสองตวสดทายอยในรปแบทเรยกวา relative path absolute path เปนการกาหนดทมาทไปดวยตวอกษรของ drive สวน relative path จะไมมการกาหนดตวอกษรของ drive แตการทางานทงหมดจะอยภายใน directory นน ๆ ดงตวอยางผลลพธของการ run น >java FileInfo \bc221Book \bc221Book does exist. Readable : Yes Writable : Yes

Page 211: Beginning JAVA [Thai]

บทท 8 Streams I/O 206 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Directory? : Yes File? : No Hidden? : No >java FileInfo \bc221Book\source\FileInfo.java \bc221Book\source\FileInfo.java does exist. Readable : Yes Writable : Yes Directory? : No File? : Yes Hidden? : No >java FileInfo \bc221Book\FileInfo.java \bc221Book\FileInfo.java does not exist. ผลลพธของการ run ทงสามครงใช relative path เปนตวกาหนดการคนหา directory และ file สวนผลลพธดานลางนเปนการาคนหาจาก absolute path E:\bc221Book\source>java FileInfo e:\bc221Book\source\FileInfo.java e:\bc221Book\source\FileInfo.java does exist. Readable : Yes Writable : Yes Directory? : No File? : Yes Hidden? : No เราเรยกใช method ทมอยใน class File ในการตรวจสอบขอมลของ file วาเปน file ลกษณะไหน ขอมลเฉพาะคอ อะไร คาวา file ใน Java นนเปนไดสองอยาง คอ file ทเกบขอมลทเราใช (หรอ ระบบใช) และ file ทเกบ file หรอทรยกวา directory (หรอ folder) Java ยงม method ทใชในการตรวจสอบขอมลของ file อกหลายตว เราจะลองใช method เหลานในโปรแกรมตวอยางตอไปน //FileInfo1.java import java.io.*; import java.util.Date; class FileInfo1 { public static void main(String[] args) { //explain how to use if no argument is given if(args.length < 1) { System.out.println("Usage: FileInfo1 file-name"); System.exit(1); } //display information about this file echoFileInfo(new File(args[0])); } private static void echoFileInfo(File file) { //display if file is a file or a directory if(file.isFile()) System.out.println("\n" + file + " is a file."); if(file.isDirectory()) { String []list = file.list(); System.out.println("\n" + file + " is a directory."); System.out.println("There are " + list.length + " items in this directory.");

Page 212: Beginning JAVA [Thai]

บทท 8 Streams I/O 207 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} //lastModifeid() returns amount of milliseconds the file //was last modified, e.g. 1045375241775 since //January 1, 1970, 00:00:00 GMT. We have to create a date //object from this data. long lastModified = file.lastModified(); Date dateModified = new Date(lastModified); //display information about this file System.out.println( "Absolute path: " + file.getAbsolutePath() + "\n Name: " + file.getName() + "\n Parent: " + file.getParent() + "\n Path: " + file.getPath() + "\n Length: " + file.length() + "\n Last modified: " + dateModified); } } โปรแกรม FileInfo1.java เรยกใช method 5 ตวในการแสดงขอมลของไฟลทกาหนดให (ผานทาง command-line argument) ซงเปนการเรยกใชโดยตรง และไมมความยงยากในการเรยกใช ม method เพยงตวเดยวเทานนทเราตองปรบปรงผลลพธท method ตวนสงมาให method ทวานคอ lastModified() lastModified() จะสงคาทมชนดเปน long ทเปนคาของ วนและเวลาทไฟลไดรบการเปลยนแปลงครงสดทายในรปแบบของ millisecond เชน 1045375241775 ซงเราไมสามารถบอกไดวาเปนวนทเทาไร เวลาอะไร เราตองใชคานในการสราง วนขนใหมผานทาง class Date ดงน long lastModified = file.lastModified(); Date dateModified = new Date(lastModified); หลงจากนนเรากแสดงผลออกทางหนาจอ ดงทแสดงใหดเปนตวอยางดานลางน >java FileInfo1 e:\bc221Book\source e:\bc221Book\source is a directory. There are 328 items in this directory. Absolute path: e:\bc221Book\source Name: source Parent: e:\bc221Book Path: e:\bc221Book\source Length: 0 Last modified: Wed Feb 26 07:47:48 GMT+07:00 2003 >java FileInfo1 FileInfo1.java FileInfo1.java is a file. Absolute path: E:\b221Book\source\FileInfo1.java Name: FileInfo1.java Parent: null Path: FileInfo1.java Length: 1236 Last modified: Tue Feb 25 14:06:13 GMT+07:00 2003 >java FileInfo1 Usage: FileInfo1 file-name ตวอยางตอไปเปนโปรแกรมทแสดงรายละเอยดของ directory วาประกอบไปดวยไฟล หรอ sub-directory อะไรบาง

Page 213: Beginning JAVA [Thai]

บทท 8 Streams I/O 208 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//DirListing.java //adopted from Bruce Eckel's import java.io.*; import java.util.Arrays; //extract file name from path //must implements FilenameFilter and override method accept() //to get files with given information into a list class DirFilter implements FilenameFilter { String fileName; //constructor DirFilter(String fileName) { this.fileName = fileName; } //this method is called by method list() from class File //to include a file if it contains a given info public boolean accept(File path, String name) { //get only file name String file = new File(name).getName(); //if in fact the file exists we will get the first index //of this file, which causes accept() to return true, //otherwise we will get -1 and returns false return file.indexOf(fileName) != -1; } } class DirListing { public static void main(String[] args) { //create file object with a default directory File path = new File("."); String[] fileList; //list of files with given criteria //no argument provided, get all files on this directory if(args.length == 0) fileList = path.list(); //information provided, get rid of path and extract files //with given info. else fileList = path.list(new DirFilter(args[0])); Arrays.sort(fileList); //sort the list showDir(fileList); //display the list } //display files to screen public static void showDir(String[] list) { for(int i = 0; i < list.length; i++) System.out.println(list[i]); } }

กอนทจะอธบายถงการทางานของโปรแกรม เรามาดผลลพธ (ตดทอนบางสวนออก) กนกอน >java DirListing java

Page 214: Beginning JAVA [Thai]

บทท 8 Streams I/O 209 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Access.java Account.java Add1To100.java … … AddNumbers2.java ThrowsWithTry.java ThrowsWithTry1.java Triangle.java TryAndCatchExample1.java TryAndCatchExample2.java Two.java UpperLower.java UpperLower2.java Variables.java Vowels.java ZeroDivideException.java p.java >java DirListing te BankRate.class BankRate.java ByteShort.class ByteShort.java Calculate.class Calculate.java โปรแกรม DirListing.java จะแสดงรายการของขอมลทอยใน directory นน ๆ ตามขอกาหนดทเราตงให เชนถาเราตองการแสดงไฟลทงหมดทมอยเรากใชคาสง DirListing โดยไมมการกาหนดใด ๆ แตถาตองการแสดงผลดวยขอกาหนด เชน ตองการแสดงไฟลทกตวทมคาวา "te" อยในไฟลเรากใชคาสง DirListing te เปนตน โปรแกรมของเราตองเรยกใช interface FileNameFilter เพอทาการ override method accept() ททาหนาทในการกรองขอมลสาหรบให method list() ทอยใน class File ใช โดยกาหนดให method accept() ตรวจสอบไฟลจาก path เฉพาะไฟลทถกตองตามเงอนไขทกาหนดไวแลวจงบอก method list() วาไฟลตวนควรเกบไวใน list ประโยคทแสดงผลโดยไมตองกาหนดเงอนไข ตองตรวจสอบกบ args.length ถาคานเปน 0 เราจะเกบไฟลทกตวไวใน array list ดวยการเรยกใช fileList = path.list(); แตถามการกาหนดเงอนไข เราจะสงเงอนไขนไปให method accept() เพอทาการคดเลอกไฟลทถกตองตามเงอนไข ดวยประโยค fileList = path.list(new DirFilter(args[0])); สมมตวา args[0] ของเรามคาเปน "te" (ดงตวอยาง) "te" กจะถกเกบไวเปนตวตรวจสอบวาไฟลทอยใน path มคานอยหรอไม เชนไฟลชอ Calculate.java Method list() กาหนดให parameter ทสงเขาไปเปน object จาก class FileNameFilter ดงนนเราสามารถทจะเขยน method accept() ในลกษณะใดกได ในทนเราดงเอาเฉพาะชอไฟลทไมม path รวมอยดวย ดวยการกาหนดดงน String file = new File(name).getName();

Page 215: Beginning JAVA [Thai]

บทท 8 Streams I/O 210 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

หลงจากนนเราใช method indexOf() จาก class String ในการตรวจสอบวา "te" มอยในไฟลนหรอไม ซงถามคาทไดจาก indexOf() จะเปนตาแหนงท "te" อย แตถาไมมไดคา -1 เรานาคานมาเปรยบเทยบกบ -1 เพอบอกให list() รวาควรเกบไฟลตวนหรอไม (true = เกบ false = ไมเกบ) return file.indexOf(fileName) != -1; ไฟลทกตวทเราไดจาก method list() จะถกเกบไวในตวแปร fileList เพอเอาไวใชในการแสดงผลตอไป แตกอนทเราจะแสดงผล เราทาการเรยงลาดบของไฟลใน fileList ดวยการเรยกใช method sort() ของ class Arrays โปรแกรมตวนอาจดเขาใจยากสกหนอย แตกไมยากเกนไปนก ผอานตองทาความเขาใจในเรองของการเรยกใช method list() ทมาจาก class File รวมไปถงการเขยน code ตามขอกาหนดทเราตองการใน method accept() สงทเราตองคานงถง คอ Method list() ใน class File มอยสองตว คอ ตวทไมม parameter และตวทม parameter สาหรบ method ตวทม parameter น parameter ตองเปน object จาก class FileNameFilter ดงนนเราตองสราง class ทมาจาก class นพรอมทงทาการ override method accept() ใหทางานตามทเราตองการ ผอานควรทดลอง run โปรแกรมตวนดวยเงอนไขตาง ๆ เพอใหเกดความเขาใจมากยงขน และควรทดลองเขยน code ให method accept() ใหมโดยกาหนดใหทาการตาง ๆ ทตางออกไปจากทเขยนในโปรแกรมตวอยางน เราไดพดถงการแสดงรายการของไฟลทมอยใน directory การสรางเงอนไขใหกบ list() และ accept() พอสมควรแลว ตอไปเราจะพดถงการอาน การเขยน ไฟล โดยเราจะเรมตนท Input streams Input and Output streams (ชองทางการนาขอมลเขา และ การนาขอมลออก) Java กาหนดใหมการนาขอมลเขาสโปรแกรมไดหลายทาง ซงเรากไดสมผสถงวธการมาบางพอสมควรในเรองของการนาขอมลเขาผานทางชองทางการนาเขามาตรฐาน (standard I/O) ตอไปนเราจะมาดถงการนาขอมลทมาจากไฟลเขาสโปรแกรม รปแบบของขอมลทถกจดเกบในไฟลนนถกแบงออกเปนสองลกษณะคอ

1. ขอมลทอยในรปแบบของ character เชน code ของโปรแกรมทสรางขนจาก Text editor พดงาย ๆ กคอ เราสามารถทจะอานขอมลเหลานได เราเรยกไฟลแบบนวา text file

2. ขอมลทถกจดเกบในรปแบบของ binary data เชนขอมลทถกเกบในรปแบบของ MS Word เรา

ไมสามรถทจะอานขอมลเหลานไดตองอาศยโปรแกรมในการชวยอาน เราเรยกไฟลในรปแบบนวา binary file

เราจะเรมดวยการอานขอมลจาก text file ทเกบ code ของโปรแกรมทเราไดเขยนขน //ReadingTextFile.java import java.io.*; class ReadingTextFile { //don't want to deal with error, let Java takes care of it public static void main(String[] args) throws IOException { BufferedReader in;//input buffer FileReader file; //input file String str; //string to store characters read from file file = new FileReader(args[0]); //open an input file in = new BufferedReader(file); //store contents in buffer int lineNo = 1;

Page 216: Beginning JAVA [Thai]

บทท 8 Streams I/O 211 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//keep reading from buffer until null is reached while((str = in.readLine()) != null) { System.out.println(lineNo + " " + str); lineNo++; } in.close(); //manually close the file } } เราเปดไฟลทตองการอานดวย FileReader() พรอมกบการเรยกใช BufferedReader() เพอใหการอานขอมลทาไดรวดเรวขน เราอานขอมลเขามาเกบไวใน str ทละหนงแถวจนกวาขอมลหมดจาก buffer หลงจากนนเรากสงขอมลทอานไดออกไปยงหนาจอพรอมทงเลขทบรรทด เมอสงขอมลหมดแลวเรากปดไฟลดวยการใช close() ผลลพธทเราไดจากการสงไฟล ReadingTextFile.java ไปใหโปรแกรมน คอ 1 //ReadingTextFile.java 2 3 import java.io.*; 4 5 class ReadingTextFile { 6 //don't want to deal with error, let Java takes care of it 7 public static void main(String[] args) throws IOException { 8 BufferedReader in; //input buffer 9 FileReader file; //input file 10 String str; //string to store characters read from file 11 12 file = new FileReader(args[0]); //open an input file 13 in = new BufferedReader(file); //store contents in buffer 14 15 int lineNo = 1; 16 //keep reading from buffer until null is reached 17 while((str = in.readLine()) != null) { 18 System.out.println(lineNo + " " + str); 19 lineNo++; 20 } 21 in.close(); //manually close the file 22 } 23 } เรามาดตวอยางทอานขอมลดวยการใช FileInputStream() และ read() ในการอานกนบาง //ReadTextFile.java import java.io.*; class ReadTextFile { public static void main(String[] args) throws IOException { FileInputStream in; //file input stream int ch; //store each character read try { in = new FileInputStream(args[0]); while((ch = in.read()) != -1) { System.out.print((char)ch); } in.close(); }

Page 217: Beginning JAVA [Thai]

บทท 8 Streams I/O 212 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//file not found catch(FileNotFoundException e) { System.err.println("Cannot find: " + args[0]); System.exit(1); } //no argument specified catch(ArrayIndexOutOfBoundsException e) { System.err.println("Usage: ReadTextFile file-name"); System.exit(1); } } } โปรแกรมตวนใช FileInputStream() เปนตวเปดไฟล และใช read() ในการอานขอมลทละ byte จาก FileInputStream ทาการจดเกบขอมลทอานไดไวใน ch พรอมทงสงขอมลทอานไดนออกไปทางหนาจอ จนกวาการอานจะสนสดลง โดยอานเจอ -1 หรอ EOF (End Of File) ในการสงขอมลทอานไดออกไปยงหนาจอนน เราตองทาการ cast ใหกบ ch กอนมเชนนนแลวขอมลทสงออกไปจะไมตรงกบทอานเขามา โปรแกรมของเรายงไดทาการตรวจจบ error ทอาจเกดขนสองตว คอ โปรแกรมหาไฟลไมเจอ และ ผใชไมกาหนดชอไฟลทใชเปนขอมลสาหรบการเปดอาน หลงจากทดลอง run ดวยไฟล ReadTextFile.java ผลลพธทไดคอ //ReadTextFile.java import java.io.*; class ReadTextFile { public static void main(String[] args) throws IOException { FileInputStream in; //file input stream int ch; //store each character read try { in = new FileInputStream(args[0]); while((ch = in.read()) != -1) { System.out.print((char)ch); } in.close(); } //file not found catch(FileNotFoundException e) { System.err.println("Cannot find: " + args[0]); System.exit(1); } //no argument specified catch(ArrayIndexOutOfBoundsException e) { System.err.println("Usage: ReadTextFile file-name"); System.exit(1); } } } character streams โดยทวไปเหมาะสมกบการอาน และเขยนขอมลทเปน text ดงนนหากจะเอามาใชกบขอมลอน ๆ กจะสรางความยงยากในการอานและเขยนมากพอสมควร ดงนนในการอานและเขยนขอมลทไมใช text เราจงตองใชการอานและเขยนขอมลทอยในรปแบบของ binary data แตกอนทจะพดถงเรองของ Binary file เราจะมาดกนถงความยงยากทวา ในการทางานกบ text file

Page 218: Beginning JAVA [Thai]

บทท 8 Streams I/O 213 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

โปรแกรม TextWithStreamTok.java อานขอมลทถกเกบไวในรปแบบของ text นามาประมวลผล เสรจแลวจงสงขอมลกลบไปยงหนาจอ เพอใหผอานเขาใจงายขน เราจงจดเกบขอมลอยใน format String double int เชน Notebook 12.00 30 CoffeeMug 5.00 40 PaperCutter 12.50 25 และเราจะกาหนดใหมขอมลเพยง 3 ตวเทานน ลองมาดการใช StreamTokenizer ทเราไดพดถงตอนทเราอานขอมลนาเขาจาก keyboard กอนหนาน วาจะนามาใชกบขอมลทอยในไฟลไดอยางไร ในโปรแกรมตวอยางดานลางน //TextWithStreamTok.java - Reading text data from a file import java.io.*; class TextWithStreamTok { public static void main(String[] args) throws IOException { BufferedReader in = null; //input buffer FileReader file = null; //input file StreamTokenizer stream = null; //tokens try { file = new FileReader(args[0]); //get a file from argument-list in = new BufferedReader(file); //storage buffer //create tokens stream = new StreamTokenizer(in); stream.eolIsSignificant(true); //EOL counted but ignored } catch(FileNotFoundException e) { System.err.println("Cannot find file: " + args[0]); System.exit(1); } //arrays to store data only 3 items as example e.g. //description prices unit //Coffee-Mug 12.5 30 String[] descs = new String[3]; double[] prices = new double[3]; int[] units = new int[3]; int i = 0, j = 0, k = 0; //arrays' indices boolean first = true; //make sure correct data is read try { //reading tokens into corresponding arrays //until EOF is reached while(stream.nextToken() != StreamTokenizer.TT_EOF) { //data is a string if(stream.ttype == StreamTokenizer.TT_WORD) { descs[i++] = stream.sval; } //data is a number (price or unit) if(stream.ttype == StreamTokenizer.TT_NUMBER) { //first data in line is price

Page 219: Beginning JAVA [Thai]

บทท 8 Streams I/O 214 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

if(first == true) { prices[j++] = stream.nval; first = false; } //next one is unit price else { units[k++] = (int)stream.nval; first = true; } } //ignore EOL if(stream.ttype == StreamTokenizer.TT_EOL) { /* do nothing */ } } in.close(); //close the stream } //trouble reading file catch(IOException e) { System.err.println("Error reading file."); e.printStackTrace(); System.exit(1); } //too many items for arrays catch(ArrayIndexOutOfBoundsException e) { System.err.println("Array index out of bound."); e.printStackTrace(); System.exit(1); } display(descs, prices, units); //display data } //display data to screen private static void display(String[] d, double[] p, int[] u) { double total = 0.00; for(int i = 0; i < d.length; i++) { total = p[i] * u[i]; System.out.print(d[i] + "\t" + p[i]); System.out.println("\t" + u[i] + "\t" + total); } } } การทางานหลก ๆ ของโปรแกรมกคอ การอานขอมลทถกจดเกบใน format ทไดกลาวไว สงสาคญทเราตองคานงถงคอ ตาแหนงและชนดของขอมลทเราตองอาน กอนอนเราตองกาหนดชองทางนาเขาขอมล ดงน file = new FileReader(args[0]); //get a file from argument-list in = new BufferedReader(file); //storage buffer //create tokens stream = new StreamTokenizer(in); stream.eolIsSignificant(true); //EOL counted but ignored หลงจากนนเรากตรวจสอบ token ทเราอานจาก stream วาเปนตวเลขหรอวาเปน string while(stream.nextToken() != StreamTokenizer.TT_EOF) { //data is a string

Page 220: Beginning JAVA [Thai]

บทท 8 Streams I/O 215 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

if(stream.ttype == StreamTokenizer.TT_WORD) { descs[i++] = stream.sval; } //data is a number (price or unit) if(stream.ttype == StreamTokenizer.TT_NUMBER) { //first data in line is price if(first == true) { prices[j++] = stream.nval; first = false; } //next one is unit price else { units[k++] = (int)stream.nval; first = true; } } //ignore EOL if(stream.ttype == StreamTokenizer.TT_EOL) { /* do nothing */ } } เราจะเกบขอมลทเปน string ไวใน descs[] ขอมลทเปน double ไวใน prices[] และขอมลทเปน int ไวใน units[] สงทเราตองคานงกคอ ลาดบของขอมลทเปนตวเลข เรารวาตวเลขกลมแรกทอานไดคอ prices และขอมลถดไปคอ units ดงนนเราตองใชตวแปร first เปนตวกาหนดทเกบขอมลวา ทอานไดครงแรกควรไปอยท prices[] และทอานไดถดมาควรไปอยท units[] และเมอเราอานจนหมดแลวเรากสง arrays ทงสามตวไปให display() ทาการประมวลผล และแสดงผลตอไป ผลลพธทเราได จากการ run คอ >java TextWithStreamTok data.dat Notebook 12.0 30 360.0 CoffeeMug 5.0 40 200.0 PaperCutter 12.5 25 312.5 ขอมลทเกบไวในไฟล data.dat จะตองมชองวางระหวางขอมลแตละตว เชน Notebook 12.0 30 CoffeeMug 5.0 40 PaperCutter 12.5 25 หรอจะใหอยในบรรทดเดยวกนกได เชน Notebook 12.0 30 CoffeeMug 5.0 40 PaperCutter 12.5 25 ทงนเพราะ nextToken() จะอานขอมลทอยถดจากชองวางไปจนกวาจะเจอชองวางอกครงหนง จะเหนไดวาเราตองคอยระวงการอานขอมล เพราะถาลาดบของการอานขอมลผด โปรแกรมของเรากจะเกดความผดพลาด และทสาคญอกอยางหนงคอ ขนตอนทยงยากของการกาหนดลาดบของขอมล การอานขอมล (ลองนกถงการอาน ถาเรามขอมลทเปนตวเลขอยมากกวาสองตว และมขอมลทเปน string อยระหวางขอมลเหลาน) ดงนนเราจงไมนยมใช text file ในการเกบขอมลทเปน primitive type เราควรใช text file ในการทางานกบขอมลทเปน text เทานน ตวอยางตอไปเปนการใช StreamTokenizer นบจานวนของคาทมอยในไฟล เพอทจะแสดงใหเหนวาถาขอมลเปน text ทงหมดการทางานจะไมมปญหาเทาไร //WordCount.java - Using StreamTokenizer to count word

Page 221: Beginning JAVA [Thai]

บทท 8 Streams I/O 216 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

import java.io.*; class WordCount { public static void main(String[] args) throws IOException { //exit if there's no file specified if(args.length < 1) { System.out.println("Usage: WordCount file-name."); System.exit(1); } FileReader inFile = null; //file stream StreamTokenizer stream = null; //tokens stream int count = 0; //number of words in the file try { inFile = new FileReader(args[0]); stream = new StreamTokenizer(inFile); count = wordCount(stream); System.out.println(count + " words counted in " + args[0]); } catch(FileNotFoundException e) { System.err.println("Cannot find: " + args[0]); e.printStackTrace(); System.exit(1); } finally { //close the file if(inFile != null) { try { inFile.close(); } catch(IOException e) { /* do nothing */ } } }

} //method to count word in the stream private static int wordCount(StreamTokenizer s) throws IOException { int count = 0; try { while(s.nextToken() != StreamTokenizer.TT_EOF) { //count only word if(s.ttype == StreamTokenizer.TT_WORD) count++; } } catch(IOException e) { System.err.println("Error reading stream: " + s); e.printStackTrace(); System.exit(1); } return count; } }

Page 222: Beginning JAVA [Thai]

บทท 8 Streams I/O 217 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

โปรแกรม WordCount.java ทาการนบจานวนของคาทปรากฏอยในไฟลทมาจาก command-line argument โดยเรยกใช StreamTokenizer เปนตวตรวจสอบวา ขอมลทมอยในไฟลเปน string หรอไม ถาเปนกจะนบ โดยไมสนใจถงรปแบบของ string นน ๆ เชน "s13" กนบเปน string โปรแกรม WordCount.java ของเราตวนใช object จาก FileReader เปนตวกาหนดชองทางผานไปยง StreamTokenizer โดยตรง ซงตางจากตวอยางกอนหนาน ทเราใช BufferedReader เปนทเกบขอมล การใช FileReader โดยตรงจะทาใหเสยเวลาในการประมวลผลมากถาไฟลมขนาดใหญ เพราะฉะนนถาผอานตองการความเรวในการประมวลผล กตองใช BufferedReader เปนตวเกบขอมลทตองการประมวลผล เราไดทดลอง run โปรแกรมดวยไฟลของ Windows Xp vbe6.dll ซงมขนาดเทากบ 2,498,560 bytes ผลลพธทไดกอนและหลงการใช BufferedReader คอ >java WordCount vbe6.dll Start: Fri Feb 28 10:08:52 GMT+07:00 2003 279829 words counted in vbe6.dll Stop: Fri Feb 28 10:08:54 GMT+07:00 2003 >java WordCount vbe6.dll Start: Fri Feb 28 10:10:35 GMT+07:00 2003 279829 words counted in vbe6.dll Stop: Fri Feb 28 10:10:36 GMT+07:00 2003 จะเหนวาการประมวลผลดวยการใช BufferedReader ใชเวลานอยกวาการใช FileReader โดยตรง (ดขนประมาณ 1 วนาท) เราใชการวดหาเวลาอยางงาย ๆ ดวยการใช Date เปนตวบอกถงความแตกตางกอนและหลงการอานขอมลในไฟล โดยเปลยนแปลง code บางสวนดงน … BufferedReader buf = null; //buffer holding data

… try { System.out.println("Start: " + new Date()); inFile = new FileReader(args[0]); buf = new BufferedReader(inFile); stream = new StreamTokenizer(buf); … … … finally { //close the file if(inFile != null) { try { inFile.close(); } catch(IOException e) { /* do nothing */ } } //close stream if(buf != null) { try { buf.close(); System.out.println("Stop: " + new Date()); } catch(IOException e) { /* do nothing */ } } … …

Page 223: Beginning JAVA [Thai]

บทท 8 Streams I/O 218 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

อกสงหนงทเราไดพดถงกอนหนาน แตไมเคยไดใชเลยกคอ finally เพอแสดงใหดถงประโยชนของ finally เราจงใช finally เปนตวปดไฟลในโปรแกรมใหเรา ผอานควรใช finally เปนตวปดไฟลเสมอ (โปรแกรมตวอยางในบทนหลาย ๆ ตว อาจไมใช finally เปนตวปดไฟล แตนนไมไดหมายความวา ผอานจะใชไมได) ถาผอานตองการทจะจบเวลาการทางานของโปรแกรม หรอสวนของโปรแกรม Java ม method อกตวหนงทผอานสามารถเรยกใชไดนนกคอ method currentTimeMillis() ดงตวอยางการใชทแสดงไวดานลางน //ElapsedTime.java class ElapsedTime { public static void main(String[] args) { long startTime, stopTime; //get starting time startTime = System.currentTimeMillis(); //do some looping for(int i = 0; i < 100000; i++) for(int j = 0; j < 100000; j++) ; //get ending time stopTime = System.currentTimeMillis(); //calculate elapsed time double elapsedTime = (double)(stopTime - startTime) / 1000.0; System.out.print("Elapsed time: "); System.out.println(elapsedTime + " seconds."); } } ผลลพธทไดจากการ run คอ Elapsed time: 85.093 seconds. โปรแกรม ElapsedTime.java เรยกใช currentTimeMillis() กอนและหลงจากการใช loop หลงจากนนกหาเวลาทใชไปดวยการนาเอาเวลาเรมตนไปลบออกจากเวลาทไดหลงจากการใช loop เราสามารถทจะทาใหการทางานกบขอมลทเปน text ไดงายขนถาเรากาหนดใหม ตวแบงขอมล (delimiter) ระหวางขอมลแตละตวทอยในไฟล ซงตวแบงทวานจะเปนตวอกษรใด ๆ กไดทไมมสวนเกยวของกบขอมลทอยในไฟล เชน เราอาจใชเครองหมาย "|" เปนตวแบงขอมลในไฟลตวอยางทไดพดถงกอนหนาน ลองมาดตวอยางการใชตวแบงทวานกน //TokenWithDelimiter.java - Using '|' as delimiter in a text file import java.io.*; import java.util.StringTokenizer; import java.lang.Integer; class TokenWithDelimiter { public static void main(String[] args) throws IOException { //data to write to file String[] items = {"Notebook", "Coffee Mug", "Paper cutter"}; double[] prices = {12.0D, 5.0D, 12.5D};

Page 224: Beginning JAVA [Thai]

บทท 8 Streams I/O 219 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

int[] units = {30, 40, 25}; //check to see if a file is provided if(args.length < 1) { System.err.println("Usage: TokenWithDelimeter file-name."); System.exit(1); } writeToFile(args[0], items, prices, units); processData(args[0]); } //writing data in arrays to a given file private static void writeToFile(String fileName, String[] items, double[] prices, int[] units) throws IOException { File dataFile = null; FileWriter fWriter = null; BufferedWriter buffer = null; PrintWriter out = null; try { dataFile = new File(fileName); fWriter = new FileWriter(dataFile); buffer = new BufferedWriter(fWriter); out = new PrintWriter(buffer); //printing data to file with '|' in between for(int i = 0; i < items.length; i++) { out.print(items[i]); out.print('|'); out.print(prices[i]); out.print('|'); out.println(units[i]); } } catch(IOException e) { System.err.println("Error writing to file"); e.printStackTrace(); System.exit(1); } finally { if(out != null) out.close(); } } //reading data from a given file & display to screen private static void processData(String fileName) throws IOException { String item; //item read double price; //price read int unit; //unit read File dataFile = null; FileReader fReader = null; BufferedReader buffer = null; String input = null; try {

Page 225: Beginning JAVA [Thai]

บทท 8 Streams I/O 220 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

dataFile = new File(fileName); fReader = new FileReader(dataFile); buffer = new BufferedReader(fReader); input = buffer.readLine(); //read first line of data //keep reading until there's no more lines to read while(input != null) { //get token from input-line - skip '|' StringTokenizer token = new StringTokenizer(input, "|"); item = token.nextToken(); price = Double.parseDouble(token.nextToken()); unit = Integer.parseInt(token.nextToken()); //display to screen System.out.print(item + "\t" + price + "\t" + unit); System.out.println("\t" + price * unit); input = buffer.readLine(); } } catch(IOException e) { System.err.println("Error reading file"); e.printStackTrace(); System.exit(1); } finally { if(buffer != null) buffer.close(); } } } เราใชเครองหมาย '|' ในการแบงขอมลทอยในไฟล พรอมทงใช class StringTokenizer เปนตวดงขอมลทอานมาจากไฟล หลงจากทเราเขยนขอมลทอยใน arrays ทงสามตวไปเกบไวในไฟลดวยการใช print() และ println() ผอานควรสงเกตถงการเขยนขอมลในแตละครงวา เราเขยน '|' ตามหลงเสมอ ยกเวนการเขยนขอมลตวสดทาย dataFile = new File(fileName); fWriter = new FileWriter(dataFile); buffer = new BufferedWriter(fWriter); out = new PrintWriter(buffer); //printing data to file with '|' in between for(int i = 0; i < items.length; i++) { out.print(items[i]); out.print('|'); out.print(prices[i]); out.print('|'); out.println(units[i]); } หลงจากนนเรากอานขอมลกลบออกมาดวย readLine() เราทาการดงขอมลแตละตวทถกแบงดวย '|' ดวยการใช nextToken() แตกอนทเราจะทาการดงขอมลทกครงในแตละบรรทด เราจะตองกาหนดเงอนไขให token ของเราเสยกอน ดวยการใช StringTokenizer token = new StringTokenizer(input, "|"); เพอทจะบงคบใหการดงขอมลนนเกดขนระหวางเครองหมาย '|' ขอมลตวแรกทเราดงออกมาเปน String เราจงไมตองแปลงขอมลตวน แตขอมลอกสองตวทเราดงออกเปน double และ int ทถกเกบใหเปน

Page 226: Beginning JAVA [Thai]

บทท 8 Streams I/O 221 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

String ในการเขยน ดงนนเราจงตองแปลงขอมลทงสองตวน หลงจากทเราไดขอมลทงสามตวแลวเรากแสดงผลออกไปยงหนาจอ dataFile = new File(fileName); fReader = new FileReader(dataFile); buffer = new BufferedReader(fReader); input = buffer.readLine(); //read first line of data //keep reading until there's no more lines to read while(input != null) { //get token from input-line - skip '|' StringTokenizer token = new StringTokenizer(input, "|"); item = token.nextToken(); price = Double.parseDouble(token.nextToken()); unit = Integer.parseInt(token.nextToken()); //display to screen System.out.print(item + "\t" + price + "\t" + unit); System.out.println("\t" + price * unit); input = buffer.readLine(); } ในการเขยนไฟลของเราครงนเราใช PrintWriter เปนตวชวย ซงภายใน class PrintWriter นเราสามารถทจะเรยกใช print() และ println() ได ทาใหการเขยนขอมลสงไปยงไฟลของเราเหมอนกบการเขยนทเราไดทามากอนหนานตอนทเราสงขอมลไปยงหนาจอ แตเราจะตองใช PrintWriter รวมกบ FileWriter เพอใหการเขยนไปยงไฟลทาได และ BufferedWriter เพอใหทาไดอยางมประสทธภาพ (การใช buffer จะชวยใหการทางานกบขอมลไวขน) ผลลพธทไดจากการ run >java TokenWithDelimiter tokens.dat Notebook 12.0 30 360.0 Coffee Mug 5.0 40 200.0 Paper cutter 12.5 25 312.5 Binary file ในการเขยน binary data เขาสไฟลนนเราจะตองคานงถงวธการในการทจะเขยนขอมล เพราะในการเขยนขอมลเขาสไฟลนน มผลตอการอานขอมลกลบออกมา ลาดบของขอมลทเขยนเขาสไฟล จะตองอานกลบออกมาดวยขนตอนเดยวกน ในการเขยนขอมลทเปน binary data นน เราสามารถทจะเลอกใช method หลาย ๆ ตวท Java มใหเปนตวชวยในการเขยน เชน Method Throws ความหมาย writeBoolean(boolean) IOException เขยนคาของ boolean จานวน 1 byte writeShort(int) IOException เขยนคาของ short จานวน 2 byte writeInt(int) IOException เขยนคาของ int จานวน 4 byte writeLong(long) IOException เขยนคาของ long จานวน 8 byte writeFloat(float) IOException เขยนคาของ float จานวน 4 byte writeDouble(double) IOException เขยนคาของ double จานวน 8 byte writeChar(int) IOException เขยนคาของ char จานวน 2 byte writeChars(String) IOException เขยน String จานวน 2 byte ตอ 1 ตวอกษร writeUTF(String) IOException เขยน String จานวน 1 byte ตอตวอกษร บวกอก

2 byte สาหรบคาของความยาวของ String สาหรบการอานนน เราจะใช method น

Page 227: Beginning JAVA [Thai]

บทท 8 Streams I/O 222 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Method Throws ความหมาย readBoolean() EOFException อาน 1 byte สงคา boolean กลบ readShort() EOFException อาน 2 byte สงคา Short กลบ readInt() EOFException อาน 4 byte สงคา int กลบ readLong() EOFException อาน 8 byte สงคา long กลบ readFloat(0 EOFException อาน 4 byte สงคา float กลบ readDouble() EOFException อาน 8 byte สงคา double กลบ readChar() EOFException อาน 2 byte สงคา char กลบ readUTF() EOFException อาน String UTF skipBytes(int) EOFException ไมอานขอมลจานวนเทากบ byte ทกาหนด

ตวอยางตอไปจะเปนตวอยางการเขยนขอมลเขาสไฟลในรปแบบของ binary data หลงจากนนจะอานกลบออกมา เราจะเรมตนดวยการสราง record จานวน 3 ตว สรางไฟลสาหรบเกบ record เหลาน อาน record ออกมาทละตว ประมวล พรอมทงแสดงผลไปยงหนาจอ Record คอกลมขอมลทประกอบไปดวยขอมลตาง ๆ ซงอาจเปนขอมลชนดเดยวกนหรอขอมลตางชนดกนกได ใน Java เราสราง record ดวยการใช class เปนตวสราง เราจะกาหนดให record ของเราม ขอมลอย 3 field เหมอนกบตวอยางกอนหนาน คอ

1. description 2. price 3. unit

เรามาดโปรแกรมตวอยางกนดกวา //DataFile.java - Sequential Access file import java.io.*; class DataFile { public static void main(String[] args) throws IOException { FileOutputStream fout; //file output stream DataOutputStream dout; //data output stream FileInputStream fin; //file input stream DataInputStream din; //data input stream //setting up data to be written to a file String[] desc = {"Coffee Mug", "Bookmark", "Note book"}; double[] prices = {5.00, 2.00, 10.00}; int[] unit = {12, 50, 30}; //variables storing data read from file String description; double price, total = 0.00; int unitPrice; //open file for writing try { fout = new FileOutputStream(args[0]); dout = new DataOutputStream(fout); for(int i = 0; i < desc.length; i++) { dout.writeUTF(desc[i]); dout.writeDouble(prices[i]); dout.writeInt(unit[i]); } dout.close();

Page 228: Beginning JAVA [Thai]

บทท 8 Streams I/O 223 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

} catch(FileNotFoundException e) { System.err.println("Cannot open " + args[0]); return; } catch(ArrayIndexOutOfBoundsException e) { System.err.println("Usage: DataFile file-name."); return; } //open file for input try { fin = new FileInputStream(args[0]); din = new DataInputStream(fin); System.out.println("Description\tPrice\tUnit\tTotal"); while(true) { description = din.readUTF(); price = din.readDouble(); unitPrice = din.readInt(); total = price * unitPrice; display(description, price, unitPrice, total); } } catch(EOFException e) { //use this exception to stop the while loop //and exit the program System.exit(1); } catch(IOException e) { System.err.println("Error reading file: " + e.toString()); System.exit(1); } } //display a record to screen public static void display(String d, double p, int u, double t) { System.out.println(d+"\t"+p+"\t"+u+"\t"+t); } } โปรแกรมของเราใช DataOutputStream และ DataInputStream เปนตวสงขอมลไปเกบไวทไฟล และเราใช for loop เปนตวกาหนดจานวนครงของการเขยน fout = new FileOutputStream(args[0]); dout = new DataOutputStream(fout); for(int i = 0; i < desc.length; i++) {

dout.writeUTF(desc[i]); dout.writeDouble(prices[i]); dout.writeInt(unit[i]); } หลงจากนนเรากอานขอมลออกมาจากไฟล ตามลาดบ ถาเราลองเปดดไฟลทเกบขอมลทเราสรางขน เราจะไมสามารถอานได เพราะขอมลเหลานถกเกบอยในรปแบบของ binary data ในการอานขอมลออกมาจากไฟลนนเราใช while loop ในการอานดวยการกาหนดใหเปน infinite loop โดยเราจะใช error ทเกดขนเปนตวยตการทางานของ loop เนองจากวาเรารวาในการอานขอมลออกจากไฟลนน ในทสดเรากจะอานเจอเครองหมายทบงบอกถงจดจบของไฟล (EOF) ซงอาจเปนการเขยน code ทไมคอยจะสวยเทาไร แตกทาใหการทางานของโปรแกรมเปนไปตามทเราตองการ

Page 229: Beginning JAVA [Thai]

บทท 8 Streams I/O 224 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

fin = new FileInputStream(args[0]); din = new DataInputStream(fin); System.out.println("Description\tPrice\tUnit\tTotal"); while(true) { description = din.readUTF(); price = din.readDouble(); unitPrice = din.readInt(); total = price * unitPrice; display(description, price, unitPrice, total); } ผลลพธทไดจากการ run คอ >java DataFile data.dat Description Price Unit Total Coffee Mug 5.0 12 60.0 Bookmark 2.0 50 100.0 Note book 10.0 30 300.0 จากผลลพธทไดจะเหนวาการจดเรยงของขอมลทสงไปยงหนาจอ ยงดไมเรยบรอยและสวยงามเทาไร ถาตองการใหการแสดงผลอยในรปแบบทสวยงาม เราจะตองสราง class ขนมาใชเองดวยการ extends class ทเราสรางขนจาก class PrintWritter พรอมกบทาการสราง method output() ททาการแสดงผลขอมลดวยการจดเรยงทางขวา และทาการ override method print() และ println() เราจะสราง class FormatWriter ดงทแสดงใหดในโปรแกรมตวอยางทไดดดแปลงมาจากโปรแกรม DataFile.java //DataFile.java - Sequential Access file //-(modified for formatted output) import java.io.*; //for pretty printing (formatted - right justified) class FormatWriter extends PrintWriter { private int width = 10; //default constructor FormatWriter(Writer output) { super(output); } //constructor with specified width FormatWriter(Writer out, int width) { super(out); this.width = width; } //set prefer output style private void output(String str) { //calculate spaces int blanks = width - str.length(); //fill with blanks before actual data for(int i = 0; i < blanks; i++) super.print(' '); //print data super.print(str); }

Page 230: Beginning JAVA [Thai]

บทท 8 Streams I/O 225 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//our print() and println() methods with different types of data public void print(String str) { output(str); } public void println(String str) { output(str); super.println(); } public void print(double value) { output(String.valueOf(value)); } public void print(int value) { output(String.valueOf(value)); } public void println(double value) { this.print(value); super.println(); } } class DataFile { public static void main(String[] args) throws IOException { FileOutputStream fout; //file output stream DataOutputStream dout; //data output stream FileInputStream fin; //file input stream DataInputStream din; //data input stream //setting up data to be written to a file String[] desc = {"Coffee Mug", "Bookmark", "Note book"}; double[] prices = {5.00, 2.00, 10.00}; int[] unit = {12, 50, 30}; double[] total = new double[3]; //open file for writing try { fout = new FileOutputStream(args[0]); dout = new DataOutputStream(fout); for(int i = 0; i < desc.length; i++) { dout.writeUTF(desc[i]); dout.writeDouble(prices[i]); dout.writeInt(unit[i]); } dout.close(); } catch(FileNotFoundException e) { System.err.println("Cannot open " + args[0]); return; } catch(ArrayIndexOutOfBoundsException e) { System.err.println("Usage: DataFile file-name."); return; } //open file for input //reuse variables desc, prices, and unit //calculate total fro each data item

Page 231: Beginning JAVA [Thai]

บทท 8 Streams I/O 226 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

try { fin = new FileInputStream(args[0]); din = new DataInputStream(fin); boolean endOfFile = false; //EOF marker int index = 0; //array index while(!endOfFile) { try { //store data in arrays before printing desc[index] = din.readUTF(); prices[index] = din.readDouble(); unit[index] = din.readInt(); total[index] = prices[index] * unit[index]; index++; } catch(EOFException e) { endOfFile = true; //stop while loop din.close(); //close the file } } //display data - right justified display(desc, prices, unit, total); } catch(IOException e) { System.err.println("Error reading file: " + e.toString()); System.exit(1); } } //display a record to screen private static void display(String[] d, double[] p, int[] u, double[] t) { //create object from FileWriter with width of 12 FormatWriter out = new FormatWriter( new BufferedWriter( new FileWriter(FileDescriptor.out)), 12); //display header out.print("Description"); out.print("Prices"); out.print("Unit"); out.println("Total"); //display contents of arrays for(int i = 0; i < d.length; i++) { out.print(d[i]); out.print(p[i]); out.print(u[i]); out.println(t[i]); } out.close(); //close the stream } } เราสราง class FormatWriter ขนมาใหมจาก class PrintWriter พรอมทงกาหนดใหม constructor 2 โดยทตวแรกเปน default constructor ทมหนาทเรยก constructor ของ class PrintWriter สาหรบการกาหนดชองทางผานออกของขอมล สวนตวทสองเรากาหนดใหมความกวางของเนอทของขอมลทตองการแสดง FormatWriter(Writer out, int width) { super(out);

Page 232: Beginning JAVA [Thai]

บทท 8 Streams I/O 227 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

this.width = width; } เราจะใช width ในการกาหนดจานวนของชองวางทเราตองการแสดงกอนการแสดงขอมลจรง เชน ถาเรากาหนดให width มคาเปน 10 และขอมลทตองการแสดงมคาเปน 2 ตวอกษรเรากจะทาการเขยนชองวางจานวนเทากบ 8 ตว เสรจแลวจงเขยนขอมลตามชองวางเหลาน เราทาไดดวยการเขยน method output() ใหทาการคานวณหาจานวนชองวางทวา เมอไดแลวจงสงไปยงหนาจอดวยการเรยก print() ของ class PrintWriter หลงจากนนจงสงขอมลจรงออกไป Method output() จะถกเรยกใชใน print() และ println() ทเราเขยนขนมารองรบขอมลตางชนดกน ซงในทนเรามขอมลเพยงสามชนด คอ string double และ int การเขยน print() และ println() กไมยากดงน public void print(int value) { output(String.valueOf(value)); } public void println(double value) { this.print(value); super.println(); } เราเพยงแตเรยก output() ดวยคาทตองการแสดงผล แตเราจะตองเปลยนคานใหอยในรปแบบของ string กอนทจะสงคานไปให output() เราเปลยน display() ของเราใหมดวยการรบ parameter ทเปน array แทนทจะเปนขอมลเดยว ๆ เหมอนททากอนหนาน พรอมทงประกาศตวแปรจาก class FormatWriter ทเราเขยนขน ดงน private static void display(String[] d, double[] p,

int[] u, double[] t) { //create object from FileWriter with width of 12 FormatWriter out = new FormatWriter( new BufferedWriter( new FileWriter(FileDescriptor.out)), 12); //display header out.print("Description"); out.print("Prices"); out.print("Unit"); out.println("Total"); //display contents of arrays for(int i = 0; i < d.length; i++) { out.print(d[i]); out.print(p[i]); out.print(u[i]); out.println(t[i]); } out.close(); //close the stream } เพอใหการสงขอมลออกทาง standard output เปนไปได เราตองสราง object จากสมาชกทชอ out ของ class FileDescriptor (สมาชกของ FileDescriptor มอยสามตวคอ in out และ err ซงหมายถง ชองทางของ input output และ error ตามลาดบ) หลงจากนนเรากสง object ตวนไปให BufferedWriter เพอสราง buffer สาหรบรองรบขอมลทจะเกดขน และ buffer ตวนจะเปน parameter ตวแรกทถกสงไปให constructor ของ FormatWriter และ 12 (ซงเปน width) จะถกสงไปเปน parameter ตวทสอง ทาให object out ของเราสามารถใชชองทางผานออกได หลงจากนนเรากแสดงขอมลดวยการเรยกใช print() และ println() ผาน object ตวน

Page 233: Beginning JAVA [Thai]

บทท 8 Streams I/O 228 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

ในตว main() ของเรา เราเปลยนแปลง code ใหทาการอานขอมลมาเกบไวใน array สาหรบการสงไปแสดงผลใน display() … … boolean endOfFile = false; //EOF marker int index = 0; //array index while(!endOfFile) { try { //store data in arrays before printing desc[index] = din.readUTF(); prices[index] = din.readDouble(); unit[index] = din.readInt(); total[index] = prices[index] * unit[index]; index++; } catch(EOFException e) { endOfFile = true; //stop while loop din.close(); //close the file } } //display data - right justified display(desc, prices, unit, total); … … เรายงใช EOF error เปนตวยตการทางานของ loop เหมอนเดม เพยงแตแทนทจะใชคา -1 เรากเลอกทจะใชตวแปร boolean เปนตวกาหนดการทางานของ loop แทน ผลลพธทไดจากการ run คอ >java DataFile data.dat Description Prices Unit Total Coffee Mug 5.0 12.0 60.0 Bookmark 2.0 50.0 100.0 Note book 10.0 30.0 300.0 เรายงสามารถทจะทาการแสดงผลทอยในรปแบบทเราตองการ ไดอกหลายรปแบบ ซงกตองขนอยกบผเขยนโปรแกรมวาตองการใหผลลพธออกมาในลกษณะไหน ผอานคงตองใชเวลาพอสมควรในการศกษาและทดลองเขยน code ททาใหการแสดงผลมความสวยงามมากขน ตวอยางตอไปนจะเปนการแสดงถงความแตกตางในการใช writeUTF() กบการใช writeChars() //WriteCharsAndWriteUTF.java - Differences between the to methods import java.io.*; class WriteCharsAndWriteUTF { public static void main(String[] args) throws IOException { File f = new File(args[0]); DataOutputStream out = new DataOutputStream( new BufferedOutputStream( new FileOutputStream(f))); out.writeUTF("If it does not work, blame the computer."); int utfSize = out.size();

Page 234: Beginning JAVA [Thai]

บทท 8 Streams I/O 229 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

out.writeChars("If it does not work, blame the computer."); int charsSize = out.size() - utfSize; out.close(); System.out.println("writeUTF() writes " + utfSize + " bytes."); System.out.println("writeChars writes " + charsSize + " bytes."); } } ผลลพธทไดจากการ run คอ >java WriteCharsAndWriteUTF difs.dat writeUTF() writes 42 bytes. writeChars writes 80 bytes. โปรแกรมของเราเขยน string จานวน 40 ตวอกษรไปยงไฟลดวยการใช writeUTF() และ writeChars() จากผลของการ run จะเหนวา writeUTF() ใชเพยงแค 1 byte ตอตวอกษรบวกกบอก 2 byte สาหรบเกบความยาวของ string สวน writeChars() ใช 2 byte ตอตวอกษร การสรางและใช Random-access file ตวอยางกอนหนานเราเขาหาขอมลในไฟลแบบ กอน-หลง หรอทเรยกวา sequential access ซงเปนวธการทคอนขางทจะใชเวลามาก ถาขอมลมอยเปนจานวนมาก มวธการอกวธหนงททาใหการเขาหา หรอคนหาขอมลทาไดรวดเรว นนกคอการเขาหาแบบทไมตองเขาหาตามลาดบ กอน-หลง หรอทเรยกวา Random-access คาวา random-access ในทนหมายความวาขอมลทถกดงออก หรอ นาเขาไมมสวนเกยวของกบขอมลทถกดงออก หรอ นาเขากอนหนาน เชน ในการคนหาเบอรโทรศพทของใครสกคนผานทาง operator ผคนหา ณ เวลาปจจบนไมมความเกยวของหรอความสมพนธใด ๆ กบการคนหาทผานมากอนหนา ในการจดการกบขอมลของ random-access file นนจะใชตวชตาแหนง (logical pointer) เปนตวกาหนดตาแหนงของการนาขอมล เขา-ออก ซงการกาหนดตาแหนงจะคานวณจากจดเรมตนของไฟล (ไมใชตาแหนงทเกบจรงในหนวยความจาสารอง) เราเรยกระยะทางจากจดเรมตนนวา offset Java กาหนดการเขาหาตาแหนงเหลานดวยการใชคาสง seek เพราะฉะนนในการเขาหาขอมล ถาเรารขนาดของขอมลทตายตว (fixed length record) เรากสามารถเขาหาขอมล ณ ตาแหนง p ดวย p * length เราจะเรมตนดวยการสราง record ตวอยาง โดยกาหนดให record ของเราประกอบดวย ชอ (first name) นามสกล (last name) ปทเกด (year of birth) เงนเดอน (salary) เราจะกาหนดให record เกดจาก class ทมสมาชกดงทกลาวขางตน พรอมกบ method ตาง ๆ ทเกยวของกบการทางานกบ record นน ๆ //RandomAccessFileDemo.java import java.io.RandomAccessFile; import java.io.*; class RandomAccessFileDemo { public static void main(String[] args) throws IOException { //data to be written to a file

Page 235: Beginning JAVA [Thai]

บทท 8 Streams I/O 230 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

String[] names = {"John", "Paul", "Stephen", "Hendrix"}; String[] lasts = {"Kawakami", "Collins", "Anderson", "McCoy"}; int[] years = {1965, 1978, 1985, 1972}; double[] pays = {2400.0, 500.0, 5000.0, 9500.0}; //use to randomly select the position in a file //to write to/read from e.g. random[0] is at the second //position, random[2] is at the frist position etc. int []random = {2, 3, 0, 1}; //writing to a file RandomAccessFile f = new RandomAccessFile("emp.dat", "rw"); try { for(int i = 0; i < 4; i++) { Employee emp = new Employee(names[i], lasts[i], years[i], pays[i]); emp.write(f, random[i]); } } catch(IOException e) { System.err.println("Error writing file"); e.printStackTrace(); System.exit(1); } finally { if(f != null) { f.close(); } } //reading from a file RandomAccessFile fin = null; try { fin = new RandomAccessFile("emp.dat", "r"); Employee em = new Employee(); System.out.println("Number of records = " + em.size(fin) + "\n"); for(int i = 0; i < 4; i++) { em.read(fin, random[i]); System.out.print("Record #" + (i+1) + ": "); em.show(); } } catch(IOException e) { System.err.println("Error reading file"); e.printStackTrace(); System.exit(1); } finally { if(fin != null) fin.close(); } } } โปรแกรมตวอยางของเราใช array 4 ตวเปนตวเกบ record ทตองการเขยนไปยงไฟล และเพอเปนการแสดงใหเหนถงการเขาหาไฟลในรปแบบของความเปน random เราจงใช array random เปนตวกาหนดถงตาแหนงของ record ทเราตองการจะเขยน ซงเราไดกาหนดให

Page 236: Beginning JAVA [Thai]

บทท 8 Streams I/O 231 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Record ตวแรกเขยนในตาแหนงท 2 (random[0]) Record ตวทสองเขยนในตาแหนงท 3 (random[1]) Record ตวทสามเขยนในตาแหนงท 0 (random[2]) Record ตวทสดทายเขยนในตาแหนงท 1 (random[3]) เราเกบขอมลเหลานดวยการสราง object จาก class Employee ซงเปน class ททาหนาทหลกในการเขยน และอาน record ไปยง และออกจากไฟล ตามลาดบ ซงม code ดงน //Employee.java - Simple record for random-access file import java.io.*; import java.io.RandomAccessFile; import java.lang.String; class Employee { private String firstName; //15 characters (30 bytes) private String lastName; //15 characters (30 bytes) private int year; //4 bytes private double salary; //8 bytes private static final int RECORD_SIZE = 72; //default constructor Employee() { firstName = ""; lastName = ""; year = 0; salary = 0.0D; } //setting up fields Employee(String firstName, String lastName, int year, double salary) { this.firstName = firstName; this.lastName = lastName; this.year = year; this.salary = salary; } //write a record to a file with a given position public void write(RandomAccessFile file, int position) throws IOException { try { //locate a position file.seek((long)(position * RECORD_SIZE)); //write equal-length strings writeString(file, firstName, 15); writeString(file, lastName, 15); //write int and double file.writeInt(year); file.writeDouble(salary); } catch(IOException e) { System.err.println("Error writing file"); e.printStackTrace(); System.exit(1); } }

Page 237: Beginning JAVA [Thai]

บทท 8 Streams I/O 232 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//reading a record from a file with a given position public void read(RandomAccessFile file, int position) throws IOException { try { //locate position to read file.seek((long)(position * RECORD_SIZE)); //reading strings firstName = readString(file, 15); lastName = readString(file, 15); //reading int and double year = file.readInt(); salary = file.readDouble(); } catch(IOException e) { System.err.println("Error reading file"); e.printStackTrace(); System.exit(1); } } //helper method to write a string with specified length public void writeString(DataOutput out, String s, int len) throws IOException { for(int i = 0; i < len; i++) { if(i < s.length()) out.writeChar(s.charAt(i)); else out.writeChar(0); } } //helper method to read a string public String readString(DataInput in, int len) throws IOException { String s = ""; int i = 0; while(i < len) { char c = in.readChar(); if(c != 0) s += c; i++; } return s; } //number of records in file public int size(RandomAccessFile file) throws IOException{ int size = 0; try { size = (int)file.length() / RECORD_SIZE; } catch(IOException e) { System.err.println("Error reading file."); System.exit(1); } return size; }

Page 238: Beginning JAVA [Thai]

บทท 8 Streams I/O 233 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//display a record to screen public void show() { System.out.print(firstName + " "); System.out.print(lastName + " "); System.out.print(year + " "); System.out.println(salary); } } method หลก ๆ ทอยใน class Employee คอ write(RandomAccessFile, position) read(RandomAccessFile, position) writeString(DataOutptu, String, length) readString(DataInput, length) size(RandomAccessFile) เนองจากวาเราตองรขนาดของ record ของเราวามความยาวเทาไร เราจงจะสามารถทจะเลอน logical pointer ของเราไปยงตาแหนงตาง ๆ ทเราตองการได ดงนนเราจงตองกาหนดขนาดของ record ภายในโปรแกรมของเราเพอใหการทางานสะดวกขน ทงนการกาหนดขนาดกตองขนอยกบการเลอกใชวธการเขยนของเราวาใช method ตวไหนเปนตวเขยน ถาเราใช writeUTF() เรากตองกาหนดขนาดแบบหนง แตถาเราใช writeChars() เรากตองกาหนดขนาดอกแบบหนง (ดความแตกตางของการใชจากตาราง) สาหรบโปรแกรมทเราเขยนขน เรากาหนดใหขนาดของ record เปน 72 byte กเพราะวาเราใช writeChar() เปนตวเขยน ดงนน ทงชอและนามสกลใช 30 byte สวน year และ salary ใช 4 และ 8 byte ตามลาดบ หนาทของ write() คอ การนาขอมลจาก field ตาง ๆ ของ Employee object เขาสไฟลในตาแหนงทไดกาหนดไว ดวยการใช seek() เปนตวกาหนดตาแหนง file.seek((long)(position * RECORD_SIZE)); เราคณ position ดวย RECORD_SIZE กเพอทจะหาตาแหนงไดถตอง เนองจากวาเรากาหนดให field 2 ตวแรกมความยาวเทากบ 15 ตวอกษร (30 byte) หลงจากนนเรากเขยน field ทงสองไปยงไฟลดวยการเรยกใช writeString() ซงทาหนาทในการเขยนจานวน byte ทไดกาหนดไว และจะเขยนคา 0 ในตาแหนงทวางอย ถาความยาวของ field ทเขยนมนอยกวา 15 ตวอกษร //write equal-length strings writeString(file, firstName, 15); writeString(file, lastName, 15); เมอเราเขยน field ทงสองเสรจเรากเขยน อกสอง filed ทเหลอดวย writeInt() และ writeDouble() โดยไมตองทาอะไรพเศษ //write int and double file.writeInt(year); file.writeDouble(salary); code ของ writeString() กไมยากอะไร เราเขยนขอมลทละตวไปยงไฟลจนกวาจะหมดขอมลทอยใน string ถาความยาวของ string ทเราเขยนมนอยกวาความยาวทกาหนดไว เรากเขยนคา 0 ลง ณ ตาแหนงนน public void writeString(DataOutput out, String s, int len) throws IOException { for(int i = 0; i < len; i++) { if(i < s.length()) out.writeChar(s.charAt(i)); else

Page 239: Beginning JAVA [Thai]

บทท 8 Streams I/O 234 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

out.writeChar(0); } } ในการอาน filed กลบออกมากเหมอนกนหลงจากทใช seek() หาตาแหนงไดแลว เรากเรยกใช readString() ในการอานสอง field แรก และใช readInt() กบ readDouble() ในการอานอกสอง field ทเหลอ Code ของ readString() กงาย ๆ เราทาการอานทกตว แตจะเกบไวเฉพาะตวทไมใช 0 เพราะ 0 เปนคาทเราใชแทนตาแหนงทวางในการเขยน string เขาสไฟล public String readString(DataInput in, int len) throws IOException { String s = ""; int i = 0; while(i < len) { char c = in.readChar(); if(c != 0) s += c; i++; } return s; } เราใช readChar() ในการอานขอมลแตละตว และเราจะตรวจสอบวาคาทอานไดเปน 0 หรอไม ถาไมเรากเชอมคานเขาส string s พรอมกบเลอนไปอานขอมลตวตอไป ทาการอานและเชอมจนกวาจะหมดขอมล สาหรบการหาจานวนของ record ทมอยในไฟลนนเราหาไดดวยการใช ขนาดของไฟลหารดวยขนาดของ record ทเราไดกาหนดไว public int size(RandomAccessFile file) throws IOException{ int size = 0; try { size = (int)file.length() / RECORD_SIZE; } catch(IOException e) { System.err.println("Error reading file."); System.exit(1); } return size; } เราใช readChar() และ writeChar() ในการเขยนและอานขอมล ดงนนเราตองคานงถงจานวนของ byte ทเราตองใชสาหรบ record แตละตววาถกตองตามทไดกาหนดหรอไม สงทตองคานงถงในเรองของการใช random access file กคอ field แตละ field ควรเปน field ทมขนาดตายตว เพราะจะทาใหการคนหาตาแหนงทาไดอยางถกตอง ผลลพธทเราไดจากการ run คอ Number of records = 4 Record #1: John Kawakami 1965 2400.0 Record #2: Paul Collins 1978 500.0 Record #3: Stephen Anderson 1985 5000.0 Record #4: Hendrix McCoy 1972 9500.0 เรามาลองดตวอยางการปรบปรงขอมล (update) ทอยในไฟลกน

Page 240: Beginning JAVA [Thai]

บทท 8 Streams I/O 235 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

การ update ขอมลกคลาย ๆ กบการเขยนขอมลเขาสไฟล เราตองหาตาแหนงของ record ทตองการ update ใหเจอ ซงเมอเจอแลวการเปลยนแปลงขอมลกสามารถทาได เราเลอกทจะเปลยนแปลง record ของเราทก field เพอเปนการแสดงถงวธการในการ update แตในทางปฏบตจรง คงไมมใครทาแบบน คาสงหลก ๆ ในการ update คอ f.seek((long)(recNum – 1) * em.recSize()); em.write(f, recNum – 1); record ของเราถกเกบในตาแหนงทนอยกวาทเปนจรงอยหนงคา ดงนนการใช seek() เราจงตองหกออกหนงคา เราไดเขยน method ขนใหมอกหลายตวเพอชวยใหการกาหนด และ การดงขอมลออกจาก record ทาไดโดยไมมปญหา method ทเพมขนใน class Employee คอ public void setFirstName(String name) { firstName = name; } public void setLastName(String name) { lastName = name; } public void setSalary(double pay) { salary = pay; } public int recSize() { return RECORD_SIZE; } public void setYear(int y) { year = y; } สาหรบกระบวนการหลก ๆ ทเกยวของกบการ update ขอมลกไมมอะไรมาก หลงจากทรบขอมลใหมมาจาก keyboard แลว พรอมกบหาตาแหนงทตองการ update เจอเรากทาการเขยนขอมลใหมทบลงทเดม … System.out.print("Enter record number: "); buffer = new BufferedReader(new InputStreamReader(System.in)); str = buffer.readLine(); recNum = Integer.parseInt(str); System.out.print("Enter first name: "); emp.setFirstName(buffer.readLine()); System.out.print("Enter last name: "); emp.setLastName(buffer.readLine()); System.out.print("Enter year of birth: "); emp.setYear(Integer.parseInt(buffer.readLine())); System.out.print("Enter salary: "); emp.setSalary(Double.parseDouble(buffer.readLine())); และ code สาหรบการเขยนทบทเราไดพดกอนหนาน … f.seek((long)(recNum – 1) * em.recSize()); em.write(f, recNum – 1); ผลลพธของการ run >java Update temp.dat

Page 241: Beginning JAVA [Thai]

บทท 8 Streams I/O 236 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

Enter record number: 1 Enter first name: My name Enter last name: Is changing Enter year of birth: 1965 Enter salary: 2500 Record #1: My name Is changing 1965 2500.0 Record #2: Hendrix McCoy 1972 9500.0 Record #3: John Kawakami 1965 2400.0 Record #4: John Kowalski 1990 5400.0 >java Update temp.dat Enter record number: 3 Enter first name: Jennie Enter last name: Saiudom Enter year of birth: 1995 Enter salary: 500 Record #1: My name Is changing 1965 2500.0 Record #2: Hendrix McCoy 1972 9500.0 Record #3: Jennie Saiudom 1995 500.0 Record #4: John Kowalski 1990 5400.0 โปรแกรมตวอยางน update ทก field ทมอยใน record ดวยการกาหนดขอมลทเขามาใหมใหกบ object จาก class Employee เสรจแลวกเขยน object ใหมนลงในไฟล ซงการกระทาแบบนเราไมสามารถทจะ update บาง field ทมอยได เราตอง update ทงหมด สาหรบการ update เฉพาะ field ทตองการนน จะทงไวใหเปนแบบฝกหดทายบทตอไป ตวโปรแกรมทงหมด มดงนคอ //Update.java - Updating Random-access file import java.io.RandomAccessFile; import java.io.*; import java.lang.Integer; class Update { public static void main(String[] args) throws IOException { RandomAccessFile f = null; Employee em = new Employee(); if(args.length < 1) { System.err.println("Usage: Update file-name"); System.exit(1); } try { f = new RandomAccessFile(args[0], "rw"); int recNum = getNewData(f, em); //get new data updateData(f, recNum, em); //update record showData(f, args[0]); //display records } catch(IOException e) { System.err.println("Error processing file"); e.printStackTrace(); System.exit(1); } }

Page 242: Beginning JAVA [Thai]

บทท 8 Streams I/O 237 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

//get new data from keyboard private static int getNewData(RandomAccessFile f, Employee emp) throws IOException { BufferedReader buffer = null; InputStreamReader iStream = null; String str = ""; int recNum = 0; try { System.out.print("Enter record number: "); buffer = new BufferedReader( new InputStreamReader(System.in)); str = buffer.readLine(); recNum = Integer.parseInt(str); System.out.print("Enter first name: "); emp.setFirstName(buffer.readLine()); System.out.print("Enter last name: "); emp.setLastName(buffer.readLine()); System.out.print("Enter year of birth: "); emp.setYear(Integer.parseInt(buffer.readLine())); System.out.print("Enter salary: "); emp.setSalary(Double.parseDouble(buffer.readLine())); } catch(IOException e) { System.err.println("Error readin file"); e.printStackTrace(); System.exit(1); } return recNum; //record number } //update record private static void updateData(RandomAccessFile f, int recNum, Employee em) throws IOException { try { //locate record f.seek((long)(recNum – 1) * em.recSize()); //write the whole record em.write(f, recNum – 1); } catch(IOException e) { System.err.println("Error writing file"); e.printStackTrace(); System.exit(1); } finally { if(f != null) f.close(); } } //display all records in this file private static void showData(RandomAccessFile f, String fName) throws IOException { try { f = new RandomAccessFile(fName, "r"); Employee em = new Employee();

Page 243: Beginning JAVA [Thai]

บทท 8 Streams I/O 238 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

int num = em.size(f); for(int i = 0; i < 4; i++) { em.read(f, i); System.out.print("Record #" + (i+1) + ":"); em.show(); } } catch(IOException e) { System.err.println("Error reading file"); e.printStackTrace(); System.exit(1); } finally { if(f != null) f.close(); } } } สรป เราไดแสดงตวอยางของการทางานกบ text file และ binary file การอาน การเขยน รวมไปถงกระบวนการตาง ๆ ทเกยวของกบไฟล โดยสรปแลวเราไดพดถง

การตรวจสอบขอมลทเกยวของกบไฟลดวย File และ method ตาง ๆ เชน ifFile() canRead() เปนตน

การใช FileReader FileWriter FileInputStream FileOutputStream การใช DataOutputStream BufferedOutputStream การใช StreamTokenizer และ StringTokenizer การสรางและใชงาน text file การใช delimiter ในการอานขอมลจาก text file การสรางและใชงาน binary file การสรางและใชงาน Random-access file การ update ขอมลใน random-access file

แบบฝกหด 1. จงเขยนโปรแกรมททาหนาทแสดงขอมลเกยวกบไฟลทกตวทมอยใน directory นน ๆ เชน ถาเจอ

ไฟลใหแสดงถง ขนาด วนทสราง ถาเจอ directory ใหแสดงถงจานวนไฟลทมอยใน directory นน พรอมกบวนท directory นถกสรางขน

2. จงเขยนโปรแกรมท copy ขอมลจากไฟลหนงไปยงอกไฟลหนงผานทาง command-line 3. จงเขยนโปรแกรมทสรางขอมลชนด int ดวยการสมจานวนเทากบ 100 ตว หลงจากนนใหนาขอมล

ทงหมดไปเกบไวใน text file โดยกาหนดใหจานวนของขอมลตอแถวเทากบ 10 ตว 4. จงเขยนโปรแกรมทอานขอมลจากไฟลทเขยนขนในขอ 3 เสรจแลวใหคานวณหาผลรวมของขอมลใน

แตละแถว หลงจากนนใหเขยนขอมลในแตละแถวรวมทงผลรวมทหาไดลงในไฟลตวเดม (ขอมลในแตละแถวจะมจานวนเทากบ 11 ตวโดยทตวสดทายในแถวเปนผลรวมของขอมลในแถวนน)

5. จงปรบปรงโปรแกรมทเขยนขนในขอ 4 โดยใหมการคานวณหาคาเฉลยของขอมลทกตวในแนวตง

(column) นาผลลพธทไดพรอมทงขอมลในแตละแถวไปเกบไวในไฟลตวใหม 6. จงเขยนโปรแกรมทอานขอมลในรปแบบทกาหนดใหดานลางน หลงจากนนใหแสดงขอมลทอานได

ไปยงหนาจอ โดยไมตองแสดง delimiter ทใช ใหกาหนดจานวนของขอมลทมอยในไฟลจานวนเทากบ 10 แถว

Page 244: Beginning JAVA [Thai]

บทท 8 Streams I/O 239 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลยฟารอสเทอรน

John Longman+25.0+30.50+48.00 Peter Wang+35.00+50.00+98.00 … … Mike Kawakami+90.00+80.00+85.00

7. จงเขยนโปรแกรมทสราง binary file จาก class Student ทกาหนดใหน โดยทาการอานขอมลเบองตนมาจาก keyboard ซงมขอมลดงน

ชอตน เปน String จานวน 15 ตวอกษร นามสกล เปน String จานวน 15 ตวอกษร เกรด เปน array ทเกบ double เชน 85.0 90.5 ทงนจานวนของเกรดทมอยจะมกตวกได เสรจแลวใหทาการอานขอมลกลบออกมาจากไฟล พรอมทงคานวณหาเกรดเฉลยของขอมล (นกศกษา) ทกตว เมอไดเกรดเฉลยแลวใหแสดงผลออกทางหนาจอ

class Student { String firstName; String lastName; double[] grades; }

8. จงเขยนโปรแกรมทสราง random-access file จากโครงสรางของ Student ทมอยในขอ 7 โดยให

user เปนผกาหนดตาแหนงของ record ทตองการเขยนเอง ใหเขยน method ทแสดงขอมลของ record (ทกาหนดมาจาก keyboard) ไปยงหนาจอ

9. จงปรบปรงโปรแกรม Update ในบทนใหมการ update ไดเฉพาะ field ทเปน salary เทานน 10. จงปรบปรงโปรแกรมในขอ 6 ดวยการเพม method ในการคานวณหาผลรวมของขอมลในแตละแถว

หลงจากนนใหนาขอมลทงหมดไปเกบไวในไฟลตวใหม โดยใหผลรวมทหาไดเปนขอมลตวสดทายในแถวนน

Page 245: Beginning JAVA [Thai]

ตารางตาง ๆ 240 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

ตารางตาง ๆ ตารางท 1 Unicode characters – 128 ตวแรก dec hex char Dec hex char dec hex char dec hex char 0 0000 <NUL> 33 0021 ! 66 0042 B 99 0063 c 1 0001 <SOH> 34 0022 " 67 0043 C 100 0064 d 2 0002 <STX> 35 0023 # 68 0044 D 101 0065 e 3 0003 <ETX> 36 0024 $ 69 0045 E 102 0066 f 4 0004 <EOT> 37 0025 % 70 0046 F 103 0067 g 5 0005 <ENQ> 38 0026 & 71 0047 G 104 0068 h 6 0006 <ACK> 39 0027 ' 72 0048 H 105 0069 i 7 0007 <BEL> 40 0028 ( 73 0049 I 106 006A j 8 0008 <BS> 41 0029 ) 74 004A J 107 006B k 9 0009 <HT> 42 002A * 75 004B K 108 006C l 10 000A <LF> 43 002B + 76 004C L 109 006D m 11 000B <VT> 44 002C ' 77 004D M 110 006E n 12 000C <FF> 45 002D - 78 004E N 111 006F o 13 000D <CR> 46 002E . 79 004F O 112 0070 p 14 000E <SO> 47 002F / 80 0050 P 113 0071 q 15 000F <SI> 48 0030 0 81 0051 Q 114 0072 r 16 0010 <DLE> 49 0031 1 82 0052 R 115 0073 s 17 0011 <DC1> 50 0032 2 83 0053 S 116 0074 t 18 0012 <DC2> 51 0033 3 84 0054 T 117 0075 u 19 0013 <DC3> 52 0034 4 85 0055 U 118 0076 v 20 0014 <DC4> 53 0035 5 86 0056 V 119 0077 w 21 0015 <NAK> 54 0036 6 87 0057 W 120 0078 x 22 0016 <SYN> 55 0037 7 88 0058 X 121 0079 y 23 0017 <ETB> 56 0038 8 89 0059 Y 122 007A z 24 0018 <CAN> 57 0039 9 90 005A Z 123 007B { 25 0019 <EM> 58 003A : 91 005B [ 124 007C | 26 001A <SUB> 59 003B ; 92 005C \ 125 007D } 27 001B <ESC> 60 003C < 93 005D ] 126 007E ~ 28 001C <FS> 61 003D = 94 005E ^ 127 007F <DEL>29 001D <GS> 62 003E > 95 005F _ 128 0080 30 001E <RS> 63 003F ? 96 0060 31 001F <US> 64 0040 @ 97 0061 a 32 0020 blank 65 0041 A 98 0062 b

ตารางท 2 Constants ทใชบอย ๆ ในโปรแกรม ชอ ความหมาย Math.E คาของ e (natural logarithm) Math.PI คาของ PI (3.145) Float/Double.NEGATIVE_INFINITY infinity ทเปนลบ Float/Double.POSITIVE_INFINITY infinity ทเปนบวก Float/Double.NaN ไมใชตวเลข Byte/Short/Integer/Long/Float/Double.MAXIMUM_VALUE คาสงสด Byte/Short/Integer/Long/Float/Double.MINIMUM_VALUE คาตาสด System.in ทางเขาขอมล (keyboard) System.out ทางออกขอมล (จอ) System.err ทางออกของ error (จอ)

Page 246: Beginning JAVA [Thai]

ตารางตาง ๆ 241 เรมตนกบ Java

ภาควชาคอมพวเตอรธรกจ วทยาลย ฟารอสเทอรน

ตารางท 3 Numeric Types ชนด bit คาเบองตน คาตาสด คาสงสด byte 8 0 -128 127 short 16 0 -32768 32767 int 32 0 -2147483648 2147483647 long 64 0 -9223372036854775808 9223372036854775807 float 32 0.0f 1.40129846432481707e-45f 3.40282346638528860e+38f double 64 0.0d 4.94065645841246544e-324 1.79769313486231570e+308

ตารางท 4 Escape Sequences Escape Sequence ความหมาย \b back space \t tab \n LF (ขนบรรทดใหม) \f FF (ขนหนาใหม) \r CR (กลบไปยงจดเรมตน) \" double quote \' single quote \\ back slash \uxxxx Unicode จาก \u ตามดวยเลขฐาน 16 สตว \xxx เลขฐานแปด เชน \101

ตารางท 5 Format Syntax สาหรบตวเลข form คา ผลลพธ ความหมาย 0000 314 0314 0 –ใชแทน digit ###0 314 314 # - ใชแทน digit ##0.0# 3.10 3.1 . - จดทศนยม #,##0 3000 3,000 , - ใชแบงกลมตวเลข ##0.00% 3.1415 314.15% % - คณตวเลขดวย 100 เพอแสดง % \u00A4##0 314 $314 \u00A4 – แสดงสกลเงนตาม locale ของประเทศ