نمونه کد جاوا – نمونه کدهای کاربردی برای برنامه نویسان جاوا
جاوا یکی از محبوبترین زبانهای برنامهنویسی است و در حوزه وباپلیکیشن، اپلیکیشنهای ویندوزی، موبایل، شبکه، کالاهای مصرفی الکترونیک، دستگاههای گیرنده دیجیتال و تقریباً همه جا حضور دارد. جاوا اینک روی بیش از 3 میلیارد دستگاه اجرا میشود. بر اساس گزارش اوراکل هم اینک بیش از 5 میلیارد جاوا کارت در حال استفاده هستند. بیش از 9 میلیون توسعهدهنده به زبان جاوا کدنویسی میکنند و محبوبیت زیادی میان توسعهدهندگان دارد و به یکی از رایجترین پلتفرمهای توسعه تبدیل شده است. در این مطلب به بررسی انواع مختلفی از نمونه کد جاوا و الگوریتمهای کاربردی این زبان برنامهنویسی میپردازیم.
تاریخچه جاوا
جاوا از سوی شرکت «سان مایکروسیستمز» (Sun Microsystems) در سال 1991 توسعه یافت و متعاقباً از سوی شرکت «اوراکل» (Oracle) خریداری شد. این پلتفرم توسط «جیمز گاسلنیگ» (James Gosling) و «پاتریک ناتون» (Patrick Naughton) توسعه یافته است. جاوا یک زبان ساده برنامهنویسی است که موجب شده نوشتن، کامپایل کردن و دیباگ برنامهها آسان شود. با استفاده از جاوا میتوان کدهای با قابلیت استفاده مجدد و برنامههای ماژولار ساخت.
جاوا مبتنی بر کلاس و در واقع یک زبان شیءگرا است و طوری طراحی شده که تا حد امکان وابستگیهای پیادهسازی کمی داشته باشد. جاوا زبان برنامهنویسی چندمنظوره است و توسعهدهندگان با بهرهگیری از آن میتوانند یک بار کد بنویسند و آن را هر کجا اجرا کند. برنامههای جاوا کامپایل شده و روی همه پلتفرمهایی که از جاوا پشتیبانی کنند، اجرا میشوند. اپلیکیشنهای جاوا به «بایت کد» (Byte Code) کامپایل میشوند که میتواند روی هر ماشین مجازی جاوا اجرا شود. ساختار جاوا شبیه زبانهای ++c/c است.
در 13 نوامبر سال 2006 شرکت سان اغلب کدهای ماشین مجازی جاوا را به صورت متن-باز و رایگان عرضه کرد. در 9 می 2007 این شرکت این فرایند را تکمیل کرده و همه کد JVM را تحت شرایط توزیع متن-باز عرضه کرد.
اصطلاحات جاوا
برای این که شروع به یادگیری جاوا بکنید، قبلاً باید با برخی اصطلاحاتی که در این پلتفرم رواج دارند، آشنا شوید.
- ماشین مجازی جاوا (Java Virtual Machine | JVM): هر برنامه جاوا سه فاز دارد. این برنامه ابتدا نوشته میشود، سپس کامپایل میشود و در نهایت اجرا خواهد شد. مرحله نوشتن برنامه از سوی توسعهدهندگان جاوا انجام مییابد. فرایند کامپایل کد از سوی کامپایلر JAVAC اجرا میشود که کامپایلر اصلی جاوا است و شامل کیت توسعه جاوا (JDK) است. این کامپایلر برنامه جاوا را دریافت کرده و بایت کد را به عنوان خروجی تولید میکند.
در مرحله اجرای یک برنامه جاوا، JVM بایت کد تولید شده از سوی کامپایلر را اجرا میکند. بدین ترتیب متوجه میشویم که وظیفه ماشین مجازی جاوا، اجرای بایت کد تولید شده از سوی کامپایلر است. هر سیستم عامل یک JVM متفاوت دارد، اما خروجی تولید شده پس از اجرای بایت کد روی همه سیستمهای عامل مختلف، یکسان است. به همین دلیل است که جاوا یک زبان مستقل از پلتفرم محسوب میشود. - بایت کد (Bytecode): چنان که توضیح دادیم کامپایلر JAVAC سورس کد جاوا را به بایت کد کامپایل میکند، به طوری که JVM بتواند آن را اجرا کند. این بایت کد به صورت فایل class. ذخیره میشوند. برای مشاهده بایت کد باید از دیاسمبلرهایی مانند javap استفاده کنید.
- کیت توسعه جاوا (Java Development Kit | JDK): کیت توسعه جاوا چنان که از نامش برمیآید یک کیت توسعه کامل است که همه چیز از کامپایلر تا «محیط زمان اجرای جاوا» (JRE)، دیباگرهای جاوا، مستندات جاوا و غیره را شامل میشود. برای این که یک برنامه جاوا اجرا شود باید JDK را رویی رایانه نصب کنیم تا امکان نوشتن، کامپایل و اجرای برنامههای جاوا را بیابیم.
- محیط زمان اجرای جاوا (Java Runtime Environment | JRE): JRE زیرمجموعه JDK است که در بخش قبل توضیح دادیم. با نصب JRE روی رایانه میتوانیم یک برنامه جاوا را اجرا کنیم، اما نمیتوانیم آن را کامپایل کنیم. JRE شامل یک مرورگر، JVM، پشتیبانی از اپلت و پلاگینها است. بنابراین برای اجرای برنامه جاوا به JRE نیاز داریم.
- گاربج کلکتور (Garbage Collector): برنامهنویسان در محیط جاوا امکان حذف اشیا را ندارند. JVM برای حذف اشیا و به دست آوردن مجدد حافظه از ابزاری به نام Garbage Collector بهره میگیرد. این ابزار اشیایی که ارجاعی به آنها وجود ندارد را حذف میکند. بدین ترتیب جاوا با بر عهده گرفتن وظیفه مدیریت حافظه، موجب شده که کار برنامهنویسان آسانتر شود. با این حال برنامهنویسها باید در مورد شیوه کدنویسی خود مراقبتهای به عمل آورند و در مواردی که به شیئی نیاز ندارند آن را ارجاع زدایی کنند تا از سوی Garbage Collector حذف شود، زیرا این ابزار نمیتواند اشیایی که هنوز ارجاعی در حافظه دارند را جمع کند.
- مسیر کلاس (ClassPath): ClassPath در واقع یک مسیر فایل است که محیط زمان اجرای جاوا و کامپایلر جاوا در آن به دنبال بارگذاری فایلهای class. میگردند. به طور پیشفرض JDK کتابخانههای زیادی دارد. اگر میخواهید کتابخانههای اکسترنال را نیز بگنجانید، باید آنها را به ClassPath اضافه کنید.
ویژگیهای اصلی زبان جاوا
در این بخش برخی قابلیتها و ویژگیهای عمده زبان برنامهنویسی جاوا را اجمالاً مرور میکنیم.
- جاوا مستقل از پلتفرم است: کامپایلر جاوا سورس کد را به بایت کد تبدیل میکند و در ادامه JVM این بایت کد تولید شده از سوی کامپایلر را اجرا خواهد کرد. این بایت کد میتواند روی هر پلتفرمی چه ویندوز، لینوکس، مکاواس و یا غیره اجرا شود. بنابراین اگر کامپایلر برنامهای را روی ویندوز کامپایل کند، میتوانیم آن را روی لینوکس اجرا کنیم و یا به طور عکس عمل نماییم. هر سیستم عامل یک JVM متفاوت دارد، اما خروجی تولید شده از سوی همه سیستمهای عامل پس از اجرای بایت کد یکسان خواهد بود. از این رو جاوا را یک زبان مستقل از پلتفرم مینامیم.
- جاوا زبان شیءگرا است: زبان جاوا به عنوان یک زبان شیءگرایی واجد خصوصیات زیر است:
- انتزاع (Abstraction)
- کپسولهسازی (Encapsulation)
- وراثت (Inheritance)
- چندریختی (Polymorphism)
- جاوا ساده است: جاوا یکی از زبانهای ساده است، زیرا قابلیتهای پیچیدهای مانند اشارهگر، اورلود عملگر، وراثت چندگانه، تخصیص صریح حافظه ندارد.
- جاوا پایدار است: زبان جاوا دارای ثبات و پایداری است، زیرا طوری توسعه یافته که تلاش زیادی برای بررسی خطاها در نخستین مراحل کار انجام دهد. به همین جهت است که کامپایلر جاوا میتواند حتی آن خطاهایی را که شناساییشان در زبانهای دیگر برنامهنویسی آسان نیست هم شناسایی کند. قابلیتهای اصلی جاوا که موجب ثبات آن شده گاربج کلکتور، مدیریت استثنا و تخصیص حافظه است.
- جاوا امن است: ما در جاوا اشارهگر نداریم و از این رو نمیتوانیم به آرایهها در خارج از دامنهشان دسترسی پیدا کنیم، یعنی در صورتی که چنین تلاشی بکنیم، استثنای ArrayIndexOutOfBoundsException مشاهده میشود. به همین دلیل است که امکان سوءاستفاده از چند نقص امنیتی رایج مانند stack corruption یا سرریز بافر در جاوا وجود ندارد.
- جاوا توزیع یافته است: امکان ساخت اپلیکیشنهای توزیع یافته با استفاده از زبان برنامهنویسی جاوا وجود دارد. احضار متد ریموت و Enterprise Java Beans برای ایجاد اپلیکیشنهای توزیع یافته در جاوا است. برنامههای جاوا میتوانند به آسانی روی یک یا چند سیستم توزیع یابند و از طریق اتصال اینترنتی با همدیگر ارتباط بگیرند.
- جاوا چندنخی است: جاوا از «چندنخی» (Multithreading) پشتیبانی میکند. این یک قابلیت جاوا است که امکان اجرای موازی دو یا چند بخش از برنامه را برای بیشینه بهرهگیری از پردازنده فراهم میسازد.
- جاوا پرتابل است: چنان که میدانیم کد جاوا که روی یک ماشین نوشته میشود، میتواند روی دستگاههای دیگر هم اجرا شود. قابلیت مستقل از پلتفرم جاوا به این معنی است که بایت کد مستقل از پلتفرم میتواند روی هر پلتفرمی اجرا شود.
لازم است قبل از ادامه دادن این مطلب یادآور شویم که پیش از این در مجله فرادرس مقالهای با عنوان «زبان برنامه نویسی جاوا (Java) — از صفر تا صد» به انتشار رسیده است که به صورت مفصل و با جزئیات کامل به زبان برنامهنویسی جاوا پرداخته و آن را به کاملترین شکل ممکن معرفی کرده است. پس اگر مشتاق هستید در مورد این زبان بیشتر یاد بگیرید، توصیه میکنیم این مطلب را حتماً مطالعه کنید.
نکات، ترفندها و نمونه کد جاوا
در این بخش از مقاله نمونه کد جاوا به معرفی برخی نکات و ترفندهای مهم که در مراحل ابتدایی یادگیری این زبان باید رعایت کنید میپردازیم.
به جای Null کالکشن خالی بازگردانید
اگر برنامهای یک کالکشن بازگرداند که هیچ مقداری ندارد، باید مطمئن شوید که یک کالکشن خالی و نه Null بازگشت مییابد. به این ترتیب دیگر لازم نیست مقدار زیادی کدهای if…else روی عناصر Null اجرا کنید.
از رشتهها با دقت استفاده کنید
اگر دو رشته با استفاده از عملگر (+) در یک حلقه for به هم الحاق شوند، یک هر بار «شیء رشته» (String Object) جدید ایجاد میشود. این کار موجب هدر رفتن حافظه و کاهش عملکرد زمانی میشود. همچنین در زمان وهلهسازی از شیء رشته، نباید از سازندهها استفاده کنید و باید این وهلهسازی به صورت مستقیم انجام یابد. به مثال زیر توجه کنید:
از ایجاد اشیای غیرضروری اجتناب کنید
یکی از پرهزینهترین انواع عملیات از نظر مصرف حافظه در جاوا عملیات ایجاد شیء است. از این رو توصیه شده که شیءها تنها در صورت لزوم ساخته یا وهلهسازی شوند. در کد زیر نمونهای از این موضوع را مشاهده میکنید:
مسئله دشوار انتخاب Array یا ArrayList
در اغلب اوقات توسعهدهندگان در مورد انتخاب یکی از ساختمانهای داده Array و ArrayList دچار تردید میشوند. هر دوی این موارد نقاط ضعف و قوت خاص خود را دارند. انتخاب یکی از این دو در عمل به الزامات شما بستگی دارد.
آرایهها دارای اندازه ثابتی هستند، اما لیستآرایهها اندازه متغیری دارند. از آنجا که اندازه آرایه ثابت است حافظهی آن در زمان اعلان متغیر از نوع array تخصیص مییابد. از این رو آرایهها عملکرد بسیار سریعی دارند. از سوی دیگر، اگر اندازه دادهها را از پیش ندانیم، در این صورت قرار دادن دادههای بیش از ظرفیت آرایه موجب بروز استثنای ArrayOutOfBoundException میشود و درج موارد کمتر هم موجب هدر رفتن حافظه خواهد شد.
- حذف و اضافه کردن عناصر به ArrayList آسانتر از Array است.
- آرایه میتواند چندبعدی باشد، اما ArrayList تنها یک بعد میتوان داشته باشد.
گاهی اوقات Finally پس از Try اجرا نمیشود
قطعه کد زیر را در نظر بگیرد:
با بررسی این قطعه کد شاید فکر کنید که println درون بلوک finally 5 بار اجرا میشود، اما اگر برنامه را اجرا کنید، متوجه خواهید شد که بلوک finally تنها چهار بار اجرا میشود. در اجرای پنجم تابع exit فراخوانی میشود و در نتیجه finally هرگز برای بار پنجم فراخوانی نخواهد شد. دلیل این مسئله آن است که System.exit اجرای همه نخهای در حال اجرا از جمله نخ کنونی را متوقف میکند. حتی بلوک finally پس از try نیز در صورت اجرای exit اجرا نخواهد شد.
هنگامی که System.exit فراخوانی میشود، JVM وظایف پاکسازی پیش از خاموشی را اجرا میکند. بدین ترتیب ابتدا همه قلابهای shutdown که با استفاده از قلاب Runtime.addShutdownHook ثبت شدهاند را اجرا میکند. این حالت مفیدی است زیرا منابع بیرونی به JVM را آزادسازی میکند.
دلیل دیگر این موضوع با Finalizer-ها مرتبط است که یا System.runFinalizersOnExit و یا Runtime.runFinalizersOnExit هستند. استفاده از Finalizer-ها مدتهای زیادی است که منسوخ شده است. Finalizer-ها تنها میتوانند روی اشیای زنده در زمانی که از سوی نخهای دیگر دستکاری میشوند اجرا گردند. به این ترتیب نتایج غیر قابل پیشبینی و یا حتی بنبست رخ میدهد.
بررسی فرد بودن
خطوط کد زیر را بررسی کرده و بگویید آیا این کد میتواند فرد بودن یک عدد را با دقت پیشبینی کند؟
این خطوط کد صحیح به نظر میرسند، اما در یکچهارم موارد نتایج نادرستی بازگشت میدهند. اگر یک عدد فرد منفی را در نظر بگیریم، باقیمانده تقسیم بر 2 عدد 1 نخواهد بود. بنابراین نتیجه بازگشتی نادرست خواهد بود که نتیجه اشتباهی است. برای اصلاح این مشکل، کد را به صورت زیر بازنویسی میکنیم:
با استفاده از کد فوق نه تنها مشکل اعداد منفی حل میشود، بلکه کد به مقدار زیادی بهینهتر نیز شده است. از آنجا که عملیات حسابی و منطقی بسیار سریعتر از ضرب و تقسیم هستند، نتایج در قطعه کد فوق با سرعت بسیار بالاتری اجرا میشوند.
اختلاف بین گیومه تکی و دوبل
به کد زیر توجه کنید:
در این کد به نظر میرسد که باید مقدار HaHa بازگشت یابد، اما در عوض مقدار Ha169 بازگشت خواهد یافت. دلیل این مسئله آن است که در صورت استفاده از گیومههای دوبل، کاراکترها مانند رشته تصور میشوند، اما زمانی که از گیومه تکی استفاده کنیم، عملوندهای با ارزش char از طریق فرایندی به نام «تبدیل اولیه عریضسازی» (widening primitive conversion) به مقادیر int تبدیل میشوند. پس از تبدیل عدد صحیح، اعداد مورد نظر اضافه شده و مقدار 169 بازگشت مییابد.
اجتناب از نشت حافظه با ترفندهای ساده
نشت حافظه در اغلب موارد موجب کاهش عملکرد نرمافزار میشود. از آنجا که جاوا اقدام به مدیریت خودکار حافظه میکند، توسعهدهندگان کنترل زیادی روی آن ندارند. اما با این حال برخی رویههای استاندارد وجود دارند که میتوانند برای حفاظت در برابر نشت حافظه مورد استفاده قرار گیرند.
- همیشه وقتی کوئری دیتابیس پایان یافت، اتصال پایگاه داده را آزاد کنید.
- همواره تلاش کنید بلوک Finally را مورد استفاده قرار دهید.
- وهلههای ذخیره شده در جدولهای استاتیک را همواره آزاد کنید.
جلوگیری از بروز بنبست در جاوا
«بنبستها» (Deadlocks) به دلایل مختلفی رخ میدهند. هیچ دستورالعمل واحدی برای جلوگیری از بنبست وجود ندارد. به طور معمول بنبستها زمانی رخ میدهند که اشیای همگامسازیشده منتظر یک قفل روی منبعی باشند که از سوی شیء همگامسازیشده دیگری قفل شده است.
برنامه زیر را اجرا کنید تا به طور عملی با یک بنبست آشنا شوید. این بنبست به این دلیل رخ میدهد که هر دو نخ منظر منبعی هستند که توسط نخ دیگری اشغال شده است. هر دوی این نخها در حالت انتظار میمانند و هیچ کدام آزاد نمیشوند.
خروجی برنامه فوق چنین است:
===== Addition Thread: 13 Subtraction Thread: 7 Holding First Lock... Holding Second Lock... Addition Thread: Waiting for AddLock... Subtraction Thread: Waiting for SubLock...
اما اگر ترتیب فراخوانی نخها تغییر یابد، مشکل بنبست حل میشود:
خروجی برنامه فوق چنین است:
===== Addition Thread: 13 Holding First Lock... Addition Thread: Waiting for AddLock... Threads: Holding Add and Sub Locks... Subtraction Thread: 7 Holding Second Lock... Subtraction Thread: Waiting for SubLock... Threads: Holding Add and Sub Locks...
رزرو حافظه برای جاوا
برخی اپلیکیشنهای جاوا ممکن است پردازشهای سنگینی داشته باشند و یا از حافظه زیادی استفاده کنند. این اپلیکیشنها به طور کلی به کندی اجرا میشوند، زیرا نیاز به RAM زیادی دارند. برای بهبود عملکرد این اپلیکیشنها اقدام به رزرو کردن حافظه برای جاوا میکنیم. بنابراین برای نمونه اگر یک وبسرور تامکت داشته باشیم که 10 گیگابایت رم داشته باشد، اگر بخواهیم این مقدار RAM را به جاوا تخصیص بدهیم، از دستور زیر روی سرور استفاده میکنیم:
export JAVA_OPTS="$JAVA_OPTS -Xms5000m -Xmx6000m -XX:PermSize=1024m -XX:MaxPermSize=2048m"
پارامترهای دستور فوق چنین هستند:
- Xms - کمینه استخر تخصیص حافظه (Minimum memory allocation pool)
- Xmx - بیشینه استخر تخصیص حافظه (Maximum memory allocation pool)
- XX:PermSize - اندازه اولیه تخصیص یافته در طی راهاندازی اولیه JVM
- XX:MaxPermSize – بیشینه اندازه قابل تخصیص در طی راهاندازی اولیه JVM
زمانبندی عملیات مختلف در جاوا
دو روش استاندارد برای زمانبندی انواع عملیات در جاوا وجود دارد که یکی با استفاده از ()System.currentTimeMillis و دیگری با ()System.nanoTime انجام مییابد. اکنون سؤال این است که باید از کدام یک از این دو استفاده کنیم و هر کدام در چه شرایطی بهتر عمل میکنند. از لحاظ نظری هر دوی این متدها کار یکسانی را اجرا میکنند، اما تفاوتهایی دارند که به صورت زیر است:
- System.currentTimeMillis چیزی بین یکهزارم تا پانزدههزارم ثانیه (بسته به سیستم) طول میکشد، اما ()System.nanoTime حدود یکمیلیونیم ثانیه (1000 نانو) طول خواهد کشید.
- System.currentTimeMillis چند چرخه ساعت برای عملیات Read میگیرد، اما ()System.nanoTime به بیش از 100 چرخه ساعت نیاز دارد.
- System.currentTimeMillis زمان مطلق (Epoch Time) را نمایش میدهد، اما ()System.nanoTime لزوماً هیچ نقطه مرجع زمانی ندارد.
انتخاب میان Float و Double
نوع داده | بایتهای مورد استفاده | ارقام معنیدار (دهدهی) |
Float | 4 | 7 |
Double | 8 | 15 |
در حوزه نرمافزار، جایی که دقت اعداد حائز اهمیت باشد، نوع داده Double معمولاً نسبت به Float ترجیح دارد، زیرا اغلب پردازندهها به زمان تقریباً یکسانی برای پردازش نوعهای Float و Double نیاز دارند. از سوی دیگر نوع Double دقت بیشتری را در زمان پردازشی یکسان در اختیار ما قرار میدهد.
محاسبه توان
جاوا برای محاسبه توان (^) از عملگر XOR بهره میگیرد. در واقع جاوا برای محاسبه توان یک عدد دو گزینه دارد که یکی ضرب و دیگری متد pow است.
ضرب
متد pow
متد pow برای محاسبه مواردی استفاده میشود که ضرب ممکن نیست:
متد Math.pow باید تنها در مواردی که ضروری است، استفاده شود. برای نمونه از آن برای محاسبه توان یک مقدار کسری استفاده میکنیم. دلیل این امر آن است که متد ()Math.pow به طور معمول حدود 300 تا 600 بار سریعتر از ضرب است.
مدیریت استثنای اشارهگر تهی
«استثناهای اشارهگر تهی» (Null Pointer Exceptions) در جاوا بسیار رایج هستند. این استثنا زمانی رخ میدهد که تلاش کنیم یک متد را روی یک مرجع شیء تهی فراخوانی کنیم. به مثال زیر توجه کنید.
در مثال فوق، اگر یک NullPointerException دریافت شود، در این صورت یا school و یا ()listStudents مقدار null داشتهاند. بنابراین هماره بهتر است که مقادیر Null را در اولین فرصت ممکن بررسی کنیم:
Encode در JSON
JSON اختصاری برای عبارت «نمادگذاری شیء جاوا اسکریپت» (JavaScript Object Notation) است و برای ذخیره و تبادل دادهها مورد استفاده قرار میگیرد. JSON یک جایگزین با کاربری آسان برای فرمت داده XML محسوب میشود. این فرمت داده به جهت مشخصات خود و همچنین سبک بودنش این روزها در اینترنت محبوبیت زیادی کسب کرده است. یک ساختمان داده نرمال را میتوان به JSON انکود کرد و به سادگی روی وب به اشتراک گذاشت. پیش از شروع به کدنویسی باید یک JSON parser را نصب کنیم. در مثالهای زیر ما از json.simple (+) استفاده کردهایم. در ادامه مثال سادهای از انکودینگ JSON را مشاهده میکنید:
خروجی کد فوق چنین است:
{"Novel Name":"Godaan","Novel Details": ["Language: Hindi","Year of Publication: 1936","Publisher: Lokmanya Press"],"Author":"Munshi Premchand"}
دیکد از JSON
برای دیکد کردن JSON باید از اسکیمای آن اطلاع داشته باشیم. جزییات کار را در مثال زیر میبینید:
فایل jsonDemoFile.json
خروجی آن چنین است:
The id is: 1 The type is: donut The name is: Cake The PPU is: 0.55 Batters: ID 1001 type Regular ID 1002 type Chocolate ID 1003 type Blueberry ID 1004 type Devil's Food Topping: ID 5001 type None ID 5002 type Glazed ID 5005 type Sugar ID 5007 type Powdered Sugar ID 5006 type Chocolate with Sprinkles ID 5003 type Chocolate ID 5004 type Maple
جستجوی ساده رشته
جاوا یک متد کتابخانه به نام ()indexOf دارد که برای کار با شیء String کاربرد دارد و موقعیت اندیس یک رشته مطلوب را داخل این شیء بازگشت میدهد. اگر رشته مورد نظر پیدا نشود، مقدار 1- بازگشت مییابد.
فهرستبندی محتوای یک دایرکتوری
به منظور فهرست کردن محتوای یک دایرکتوری، میتوانید از برنامه زیر استفاده کنید. این برنامه صرفاً نامهای همه زیردایرکتوریها و فایلهای درون یک پوشه را داخل یک آرایه دریافت کرده و سپس این آرایه را به صورت ترتیبی پیمایش میکند تا همه محتوایش را لیست کند:
برنامه ساده IO
جاوا برای خواندن از یک فایل و نوشتن داخل آن دو کلاس FileInputStream و FileOutputStream را ارائه کرده است. سازنده FileInputStream یک آرگومان filepath برای فایل ورودی میگیرد و استریم File Input را تولید میکند. به طور مشابه سازنده FileOutputStream آرگومان filepath مربوط به فایل خروجی را دریافت کرده و استریم File Output را ایجاد میکند. پس از این که مدیریت فایل پایان یافت، حتماً باید این استریمها را Close کنید.
اجرای یک فرمان Shell از جاوا
جاوا یک کلاس Runtime برای اجرای فرمانهای Shell ارائه کرده است. از آنجا که اینها فرمانهای اکسترنال هستند، مدیریت استثنا اهمیت بسیار زیادی دارد. در مثال زیر این کاربرد را با طرح یک مثال معرفی کردهایم. در این نمونه کد تلاش میکنیم تا یک فایل PDF را با استفاده از دستور Shell باز کنیم.
استفاده از Regex
در جدول زیر خلاصهای از سازههای «عبارت منظم» (Regular Expression) در جاوا را مشاهده میکنید.
کاراکترها | ||
x | کاراکتر x | مثال |
\\ | کاراکتر بکاسلش | - |
\0n | کاراکتر با مقدار هشتهشتی 0n | (0 <= n <= 7) |
\0nn | کاراکتر با مقدار هشتهشتی 0nn | (0 <= n <= 7) |
\0mnn | کاراکتر با مقدار هشتهشتی 0mnn | (0 <= m <= 3, 0 <= n <= 7) |
\xhh | کاراکتر با مقدار هگزادسیمال 0xhh | - |
\uhhhh | کاراکتر با مقدار هگزادسیمال 0xhhhh | - |
\x{h…h} | کاراکتر با مقدار هگزادسیمال 0xh…h | - |
\t | کاراکتر tab | (‘\u0009’) |
\n | کاراکتر خط جدید | (‘\u000A’) |
\r | کاراکتر بازگشت کارتریج | (‘\u000D’) |
\f | کاراکتر form-feed | (‘\u000C’) |
\a | کاراکتر alert (bell) | (‘\u0007’) |
\e | کاراکتر escape | (‘\u001B’) |
\cx | کاراکتر کنترل مرتبط با x | - |
دستههای کاراکتری | |
[abc] | a یا b یا c (کلاس ساده) |
[^abc] | هر کاراکتری به جز a یا b یا c (منفی) |
[a-zA-Z] | a تا z یا A تا Z، شمولی (بازه) |
[a-d[m-p]] | a تا d، یا m تا p به صورت [a-dm-p] (اتحادی) |
[a-z&&[def]] | d یا e یا f (تقاطع) |
[a-z&&[^bc]] | a تا z به جز b و c یعنی [ad-z] (تفریق) |
[a-z&&[^m-p]] | a تا z و نه m تا p یعنی [a-lq-z] (تفریق) |
دستههای از پیش تعریف شده کاراکتر | ||
. | هر کاراکتری را شامل میشود و ممکن است با کاراکتر انتهای خط تطبیق یابد یا نیابد | - |
\d | یک کاراکتر رقمی | [0-9] |
\D | یک کاراکتر غیر رقمی | [^0-9] |
\s | کاراکتر فاصله | [ \t\n\x0B\f\r] |
\S | کاراکتر غیر فاصله | [^\s] |
\w | کاراکتر کلمه | [a-zA-Z_0-9] |
\W | کاراکتر غیر کلمه | [^\w] |
تطبیقدهنده کران | |
^ | ابتدای خط |
$ | انتهای خط |
\b | کران کلمه |
\B | کران غیر کلمه |
\A | ابتدای ورودی |
\G | انتهای تطبیق قبلی |
\Z | انتهای ورودی را مشخص میکند اما در صورت وجود خاتمهدهنده تنهایی مشخص میشود. |
\z | انتهای ورودی |
نمونهای از Java Swing
با کمک Java Swing میتوان رابطهای گرافیکی کاربر ایجاد کرد. جاوا کتابخانه javax را عرضه کرده است که حاوی swing است. آن رابط کاربری گرافیکی که از Java Swing استفاده بکند، باید بسط دادن JFrame آغاز شود. در این حالت باکسها به نحوی اضافه میشوند که میتوانند شامل کامپوننتهای GUI از قبیل دکمه، دکمه رادیویی، کادر متنی و غیره باشند. این کادرها بر مبنای Container تنظیم میشوند.
پخش صدا با جاوا
پخش صدا یکی از کاربردهای متداول در جاوا است که به طور خاص در بازیها اهمیت زیادی دارد. در دموی زیر شیوه پخش یک فایل صوتی را با استفاده از کد جاوا نشان دادهایم:
اکسپورت PDF
اکسپورت کردن یک جدول PDF الزام رایجی در برنامههای جاوا محسوب میشود. این کار با استفاده از itextpdf به سادگی هر چه تمام انجام مییابد.
ارسال ایمیل از کد جاوا
ارسال ایمیل از جاوا کار آسانی است. کافی است Java Mail Jar را نصب کنیم و مسیر آن را برابر با classpath برنامه تعیین کنیم.
مشخصههای اصلی در کد تعیین میشوند و بهتر است از روشی که در کد زیر استفاده شده برای ارسال ایمیل استفاده کنیم:
اندازهگیری زمان
اپلیکیشنهای زیادی نیازمند اندازهگیری کاملاً دقیق زمان هستند. به این منظور جاوا برخی متدهای استاتیک را در کلاس System به شرح زیر عرضه کرده است:
currentTimeMillis(): این متد زمان جاری را بر حسب میلیثانیههای سپری شده از Epoch Time و در فرمت Long بازگشت میدهد.
()nanoTime: این متد، مقدار جاری دقیقترین تایمر سیستم موجود را بر حسب نانوثانیه و در فرمت Long بازگشت میدهد. متد ()nanoTime به منظور اندازهگیری بازههای زمانی نسبی به جای زمانبندی مطلق مورد استفاده قرار میگیرد.
تغییر مقیاس تصویر
برای تغییر ابعاد تصاویر میتوان از usingAffineTransform استفاده کرد. قبل از هر چیز باید Image Buffer از روی تصویر ورودی ایجاد شود و سپس تصویر مقیاسبندیشده رندر میشود:
به دست آوردن مختصات محل قرارگیری ماوس
با پیادهسازی اینترفیس MouseMotionListener در جاوا میتوان رویدادها ماوس را پیگیری کرد. هنگامی که ماوس وارد منطقه خاصی شود، رویداد MouseMoved تحریک میشود و مختصات حرکت را میتوان به دست آورد. در مثال زیر این کارکرد را نشان دادهایم:
FileOutputStream در برابر FileWriter
نوشتن فایل در جاوا به طور عمده به دو روش با استفاده از FileOutputStream و FileWriter انجام مییابد. گاهی اوقات توسعهدهندگان در زمینه انتخاب یکی از این دو دچار تردید میشوند. در مثال زیر به انتخاب یکی از این دو روش کمک میکنیم. و توضیح میدهیم که کدام یک برای چه شرایطی مناسبتر است. ابتدا به بررسی بخش پیادهسازی میپردازیم.
استفاده از FileOutputStream
استفاده از FileWriter
FileOutputStream به منظور نوشتن استریمهایی از بایتهای خام مانند دادههای تصویر استفاده میشود. برای نوشتن استریمهای کاراکتری باید از FileWriter استفاده شود. با توجه به توضیح فوق کاملاً روشن میشود که برای نوع دادههای تصویری باید از FileOutputStream استفاده شود، در حالی که برای نوع داده متنی بهتر است FileWriter مورد استفاده قرار گیرد.
پیشنهادهای متفرقه
در این بخش برخی پیشنهادی عمومی را ارائه کردهایم که در زمان کدنویسی به زبان جاوا برای شما مفید واقع خواهند شد.
از کالکشنها استفاده کنید
جاوا به طور پیشفرض چند دست از کالکشنها دارد. برای مثال میتوان به Vector، Stack، Hashtable، Array و غیره اشاره کرد. عموماً توصیه میشود که توسعهدهندگان در حد امکان از کالکشنها بهره بگیرند. دلایل این توصیه به شرح زیر هستند:
- استفاده از کالکشنها موجب میشود که کد قابلیت استفاده مجدد را یافته و «قابل مبادله» (interoperable) شود.
- کالکشنها موجب ساختار یافتن کد میشوند و به این ترتیب درک و نگهداری کد آسان میشود.
- کلاسهای کالکشن پیشفرض جاوا به طور کامل تست شدهاند و از این رو با بهرهگیری از آنها کیفیت کد افزایش مییابد.
قاعده 10-50-500
در پکیجهای بزرگ نرمافزاری، موضوع نگهداری کد بسیار چالشبرانگیز میشود. توسعهدهندگانی که به تازگی وارد پروژههای پشتیبانی از چنین کدهایی شدهاند در اغلب موارد از وجود کد Monolithic و کد اسپاگتی شکایت دارند. یک قاعده ساده برای جلوگیری از بروز این حالت و نوشتن کد تمیز و قابل نگهداری وجود دارد که به نام قاعده 10-50-500 شناخته میشود.
- 10: هیچ پکیجی نمیتواند بیش از 10 کلاس داشته باشد.
- 50: هیچ متدی نمیتواند بیش از 50 خط کد داشته باشد.
- 500: هیچ کلاسی نمیتواند بیش از 500 خط کد داشته باشد.
اصول طراحی کلاس SOLID
SOLID یک اختصار برای اصول طراحی است که از سوی «رابرت مارتین» (Robert Martin) پیشنهاد شده است. توضیح این اصول به شرح جدول زیر است.
قاعده | توضیح |
اصل مسئولیت منفرد (Single responsibility principle) | یک کلاس باید تنها و تنها یک وظیفه/مسئولیت داشته باشد. اگر کلاسی بیش از یک کار را اجرا میکند، موجب بروز سردرگمی خواهد شد. |
اصل باز/بسته (Open/closed principle) | توسعهدهندگان باید روی بسط موجودیتهای نرمافزاری و نه تغییر دادن آنها تمرکز کنند. |
اصل جایگزینی لیسکف (Liskov substitution principle) | باید امکان جایگزینی کلاس مشتقشده با کلاس مبنا وجود داشته باشد. |
اصل تفکیک اینترفیس (Interface segregation principle) | این اصل مشابه اصل مسئولیت منفرد است، اما روی اینترفیسها کاربرد دارد. هر اینترفیس باید مسئول یک وظیفه خاص باشد. توسعهدهندگان نباید متدهایی که اینترفیس نیاز ندارد را پیادهسازی کنند. |
اصل وارونهسازی وابستگی (Dependency inversion principle ) | شما باید به انتزاعها و نه مبانی وابسته باشید. معنی این حرف آن است که هر ماژول باید با استفاده از یک لایه انتزاع از ماژول دیگر جدا شود که مسیر ارتباطی آنها را تشکیل میدهد. |
کاربرد الگوهای طراحی
«الگوهای طراحی» (Design Patterns) به توسعهدهندگان کمک میکنند تا بهترین اصول طراحی نرمافزار را در پروژههای خود به کار بگیرند. همچنین پلتفرم مشترکی برای همکاری توسعهدهندگان سراسر دنیا فراهم میسازند. با استفاده از الگوهای طراحی میتوانید مطمئن باشید که مجموعه اصطلاحهای استانداردی وجود دارد که توسعهدهندگان مختلف با بهرهگیری از آن میتوانند با یکدیگر همکاری کرده و راحتتر با هم ارتباط برقرار کنند.
ایدههای خود را مستند کنید
هرگز بدون فراهم ساختن پیشنیازها دست به کدنویسی نزنید. ابتدا باید استراتژی تهیه کرده و اقدام به آمادهسازی، مستندسازی و بررسی و مرور کنید تا بتوانید اقدام به پیادهسازی نمایید. قبل از هر چیز الزامات خود را لیست کنید یک سند طراحی آماده کنید. سپس فرضیات صحیحی تهیه نمایید و با ارائه مستندات برای «مرور همکاران» (Peer Review) از درستی آنها مطمئن شوید.
از Equals به جای == استفاده کنید.
عملگر == مرجعهای شیء را مقایسه میکند و با استفاده از آن میتوانیم متوجه شویم آیا دو عملوند به شیء یکسانی اشاره میکنند یا نه. اما عملگر عمل مقایسه واقعی دو رشته را اجرا میکند.
از اعداد اعشاری احتراز کنید
اعداد اعشاری تنها باید در مواردی که کاملاً ضروری باشد، مورد استفاده قرار گیرند. برای نمونه استفاده از اعداد اعشاری برای نمایش مبالغ کمتر از واحد میتواند دردسرساز باشد. در این موارد بهتر است از BigDecimal استفاده شود. اعداد اعشاری در اندازهگیریها مفید هستند.
الگوریتمها و برنامههای کاربردی جاوا
در بخش قبلی این راهنما به طور عمده با نکات و ترفندهای کاربردی جاوا آشنا شدیم. در این بخش از مقاله میخواهیم برخی الگوریتمها و برنامههای مهمی که به عنوان یک برنامهنویس جاوا باید با آنها آشنا باشید را ارائه کنیم. در بخش نخست با برنامههای ابتدایی جاوا آشنا میشویم و در ادامه برخی برنامههای پیشرفته جاوا را نیز معرفی خواهیم کرد.
برنامههای کاربردی ساده جاوا
در ابتدا برخی الگوریتمها و نمونه کد جاوا را با هم مرور میکنیم که برای اجرای برخی وظایف ساده و مقدماتی به شما کمک میکنند.
برنامه جاوا برای اجرای عملیات ابتدایی ماشین حساب
هنگامی که به یک ماشین حساب فکر میکنیم، عملیاتی مانند جمع، تفریق، ضرب و تقسیم به ذهن متبادر میشود. در ادامه این موارد عملیات ابتدایی را به کمک برنامه زیر پیادهسازی میکنیم.
هنگامی که برنامه فوق را اجرا کنیم، یک خروجی مانند زیر مشاهده میکنیم:
Enter two numbers: 20 98 Enter an operator (+, -, *, /): / 20.0 / 98.0 = 0.2
برنامه جاوا برای یافتن فاکتوریل یک عدد
فاکتوریل یک عدد، حاصلضرب همه اعداد مثبت کمتر یا برابر با آن عدد است. فاکتوریل یک عدد n به صورت!n نمایش مییابد. در ادامه یک برنامه به روش بازگشتی برای پیدا کردن فاکتوریل عدد ورودی مینویسیم.
با اجرای برنامه فوق، فاکتوریل عدد به صورت زیر به دست میآید:
Enter the number: 12 Factorial of entered number is: 47900160
برنامه جاوا برای محاسبه سری فیبوناچی تا n عدد
سری فیبوناچی یک سری است که در آن عنصر بعدی مجموعه دو عنصر قبلی باشد. برای نمونه عناصر نخست این سری به صورت 0 1 1 2 3 5 8 13… است. در ادامه برنامهای مینویسیم که سریهای فیبوناچی را محاسبه کند:
خروجی کد فوق به صورت زیر است:
Upto 100: 0 + 1 + 1 + 2 + 3 + 5 + 8 + 13 + 21 + 34 + 55 + 89 +
برنامه یافتن پالیندروم بودن یا نبودن یک رشته
«پالیندروم» (Palindrome) عدد، رشته یا دنبالهای است که پس از معکوس شدن هم دقیقاً همانند حالا اولش باشد. برای نمونه کلمه «درد» را اگر از آخر به اول بنویسید، همچنان «درد» خواهد بود.
هنگامی که کد فوق را اجرا کنیم، بررسی میکند آیا رشته مفروض یک پالیندروم است یا نه:
Enter your Statement: RACECAR RACECAR is palindrome = true Enter your Statement: MyPackage MyPackage is palindrome = false
برنامه محاسبه جایگشت و ترکیب دو عدد
جایگشت و ترکیب دو مجموعه، به چیدمان متفاوت تعداد مفروضی از عناصر آن دو مجموعه گفته میشود که یک به یک، یا به یکباره انتخاب شوند. پیادهسازی آن چنین است:
با اجرای کد فوق، یک خروجی مانند زیر به دست میآید:
Enter Value of n: 5 Enter Value of r: 3 NCR = 10 NPR = 60
برنامه پرینت الگوی الفبایی (A) و الماس
در این مثال از حلقه برای پرینت الگوهای مختلف در جاوا استفاده میکنیم. ما دو الگوی متفاوت را پیادهسازی میکنیم که یکی الگوی الفبایی و دیگری الگوی شکل الماس است. پیادهسازی الگوی الفبایی حرف َ A چنین است:
خروجی کد فوق چنین است:
برنامه پرینت الگوی الماس نیز در جاوا به صورت زیر است:
خروجی برنامه فوق مانند زیر است:
Enter the number of rows: 5 * *** ***** ******* ********* ******* ***** *** *
برنامه معکوسسازی حروف موجود در یک رشته
این برنامه جاوا ترتیب حروف موجود در یک رشته متنی را که کاربر وارد کرده است، معکوس میسازد. برای نمونه عبارت Hello People به صورت olleH elpoeP تبدیل میشود. کد جاوا چنین است:
خروجی برنامه فوق مانند زیر است:
Welcome To MyPackage emocleW oT akerudE
برنامهای برای بررسی خصوصیت بازتاب آینهای در یک آرایه
یک آرایه زمانی دارای خصوصیت «بازتاب آینهای» (Mirror–Inverse) گفته میشود که معکوس آن برابر با خودش باشد. اکنون برنامهای مینویسیم که وجود خصوصیت بازتاب آینهای را در یک آرایه بررسی کند:
خروجی این کد چنین است: No
بنابراین آرایه ورودی دارای خصوصیت بازتاب آینهای نبوده است. اما اگر از آرایه {3,4,2,0,1} استفاده کنیم، خروجی yes چاپ میشود، زیرا آرایه خصوصیت مورد نظر را دارد.
برنامههای کاربردی پیشرفته جاوا
در این بخش برخی برنامههای جاوا را بررسی میکنیم که شاید کمی فراتر از سطح مبتدی باشند و برای افرادی که در سطح متوسط و یا حتی پیشرفته یادگیری جاوا هستند، مفید خواهند بود.
برنامه پیادهسازی الگوریتم جستجوی دودویی
جستجوی دودویی (Binary Search) یک الگوریتم جستجو است که موقعیت مقدار هدف را درون یک آرایه مرتبشده پیدا میکند. جستجوی دودویی مقدار مورد نظر را با عنصر میانه آرایه مقایسه میکند. پیادهسازی آن در جاوا به صورت زیر است:
با اجرای کد فوق، عنصر موجود در یک ایندکس خاص را جستجو میکند. خروجی کد فوق چنین است:
Element found at index 4
برنامه پیادهسازی الگوریتم HeapSort
مرتبسازی هیپ یک تکنیک مرتبسازی مبتنی بر مقایسه است که روی ساختمان داده Heap اجرا میشود. این الگوریتم مشابه مرتبسازی انتخابی است که در آن بزرگترین عنصر پیدا شده و سپس در انتهای لیست قرار میگیرد. در ادامه همین فرایند برای بقیه عناصر تکرار میشود. کد برنامه مرتبسازی هیپ در جاوا به صورت زیر است:
خروجی کد فوق چنین است:
5,6,7,11,12,13
برنامه حذف عناصر از یک لیستآرایه
ArrayList یک پیادهسازی از اینترفیس لیست است که در آن عناصر میتوانند به صورت دینامیک به لیست حذف یا اضافه شوند. همچنین اندازه لیست در صورت نیاز به افزون عناصر بیشتر از مقدار اولیه، به طور دینامیک افزایش مییابد. در برنامه زیر ابتدا برخی عناصر را دریک ArrayList درج میکنیم و سپس عناصر را بر اساس مشخصاتی از لیست حذف خواهیم کرد:
خروجی کد فوق چنین است:
Initial List: [C, C++, Java, Kotlin, Python, Perl, Ruby] After remove(5): [C, C++, Java, Kotlin, Python, Ruby] After remove("Kotlin"): [C, C++, Java, Python, Ruby] After removeAll(scriptingLanguages): [C, C++, Java] After Removing all elements that start with "C": [Java] After clear(): []
برنامه پیادهسازی HashMap در جاوا
HashMap یک Map بر اساس کلاس کالکشن است که برای ذخیرهسازی جفتهای «کلید-مقدار» مورد استفاده قرار میگیرد. این ساختمان داده به صورت <HashMap<Key, Value یا <HashMap<K, V نشان داده میشود. این کلاس هیچ تضمینی در مورد ترتیب Map ارائه نمیکند. در واقع HashMap کاملاً مشابه کلاس Hashtable است و تنها تفاوت در این است که همگامسازی نشده است و امکان درج مقادیر Null (کلیدهای Null و مقادیر Null) را دارد. در کد زیر شیوه پیادهسازی منطق HashMap را در جاوا مشاهده میکنید:
خروجی کد فوق چنین است:
map is empty Size of map is:- 3 {abc=10, xyz=20, mno=30} value for key "abc" is:- 10 map is empty
برنامه پرینت گرههای حاضر در لیست پیوندی حلقوی
برنامهای که در این بخش مینویسیم از اصل «FIFO» پیروی میکند در این برنامه منظور از گرهْ عنصر لیست است که دو بخش به صورت Data و Next دارد. بخش Data نشاندهنده دادههای ذخیره شده درون گره و بخش Next نیز یک اشارهگر به گره بعدی است. کد پیادهسازی این برنامه به صورت زیر است:
با اجرای این برنامه، یک خروجی مانند زیر به دست میآید:
Nodes of the circular linked list: 1 2 3 4
برنامه اتصال به یک پایگاه داده SQL
JDBC یک API استاندارد جاوا برای اتصالپذیری وابسته به پایگاه داده بین زبان برنامهنویسی جاوا و طیف گستردهای از دیتابیسها است. این اینترفیس برنامه کاربردی امکان انکود کردن گزارههای درخواست دسترسی را به «زبان کوئری ساختیافته» (Structured Query Language | SQL) فراهم ساخته است. در ادامه این گزارهها به برنامهای که دیتابیس را مدیریت میکند، ارسال خواهند شد. JDBC به طور عمده به منظور اجرای وظایف باز کردن یک اتصال به دیتابیس، ایجاد یک دیتابیس SQL، اجرای کوئریهای SQL، و همچنین دریافت خروجی استفاده میشود.
در کد نمونه زیر یک پایگاه داده ایجاد کرده و پس از برقراری اتصال با آن اقدام به اجرای کوئری میکنیم.
با اجرای کد فوق، یک اتصال با دیتابیس برقرار میشود و دادههای موجود در پایگاه داده بازگشت مییابد:
Connecting to database... Creating statement... ID: 100, Age: 18, First: Zara, Last: Ali ID: 101, Age: 25, First: Mahnaz, Last: Fatma ID: 102, Age: 30, First: Zaid, Last: Khan ID: 103, Age: 28, First: Sumit, Last: Mittal Goodbye!
برنامه یافتن ترانهاده یک ماتریس
ترانهاده یک ماتریس از طریق تعویض ردیفها با ستونها و ستونها با ردیفهای ماتریس به دست میآید. به بیان دیگر ترانهاده ماتریس A[][] i از طریق تعویض A[i][j] با A[j][i]. به دست میآید.
با اجرای کد فوق، خروجی زیر به دست میآید:
Result matrix is 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
سخن پایانی
به این ترتیب به پایان این مقاله با موضوع معرفی نمونه کد جاوا میرسیم. جاوا یکی از محبوبترین زبانهای برنامهنویسی است که از زمان معرفی شدن، همواره جزء یکی از سه زبان محبوب توسعهدهندگان بوده است.
در این مقاله تلاش کردیم با ارائه انواع نمونه کد جاوا شما را چه در ابتدای مسیر یادگیری این زبان باشید و چه در زمینه یادگیری جاوا به سطح متوسطی رسیده باشید، کمک کنیم. همچنین نمونه کدها و الگوریتمهای معرفی شده در بخش انتهایی این راهنما احتمالاً حتی برای توسعهدهندگان حرفهای و باتجربه نیز به عنوان یک یادآوری سریع و عملی، مفید واقع خواهند شد.
من C# کار کردم شنیده بودم شبیه جاواست ولی نمیدانستم تا این حد شبیه هم هستند.