نمونه کد جاوا — نمونه کدهای کاربردی برای برنامه نویسان جاوا

۵۹۱۶ بازدید
آخرین به‌روزرسانی: ۵ شهریور ۱۴۰۲
زمان مطالعه: ۳۷ دقیقه
نمونه کد جاوا

جاوا یکی از محبوب‌ترین زبان‌های برنامه‌نویسی است و در حوزه وب‌اپلیکیشن، اپلیکیشن‌های ویندوزی، موبایل، شبکه، کالاهای مصرفی الکترونیک، دستگاه‌های گیرنده دیجیتال و تقریباً همه جا حضور دارد. جاوا اینک روی بیش از 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 اجرا کنید.

public class getLocationName {
    return (null==cityName ? "": cityName);
}

از رشته‌ها با دقت استفاده کنید

اگر دو رشته با استفاده از عملگر (+) در یک حلقه for به هم الحاق شوند، یک هر بار «شیء رشته» (String Object) جدید ایجاد می‌شود. این کار موجب هدر رفتن حافظه و کاهش عملکرد زمانی می‌شود. همچنین در زمان وهله‌سازی از شیء رشته، نباید از سازنده‌ها استفاده کنید و باید این وهله‌سازی به صورت مستقیم انجام یابد. به مثال زیر توجه کنید:

//Slower Instantiation
String bad = new String("Yet another string object");
      
//Faster Instantiation
String good = "Yet another string object"

از ایجاد اشیای غیرضروری اجتناب کنید

یکی از پرهزینه‌ترین انواع عملیات از نظر مصرف حافظه در جاوا عملیات ایجاد شیء است. از این رو توصیه شده که شیء‌ها تنها در صورت لزوم ساخته یا وهله‌سازی شوند. در کد زیر نمونه‌ای از این موضوع را مشاهده می‌کنید:

import java.util.ArrayList;
import java.util.List;
 
public class Employees {
 
    private List Employees;
 
    public List getEmployees() {
 
        //initialize only when required
        if(null == Employees) {
            Employees = new ArrayList();
        }
        return Employees;
    }
}

مسئله دشوار انتخاب Array یا ArrayList

در اغلب اوقات توسعه‌دهندگان در مورد انتخاب یکی از ساختمان‌های داده Array و ArrayList دچار تردید می‌شوند. هر دوی این موارد نقاط ضعف و قوت خاص خود را دارند. انتخاب یکی از این دو در عمل به الزامات شما بستگی دارد.

import java.util.ArrayList;
 
public class arrayVsArrayList {
 
    public static void main(String[] args) {
        int[] myArray = new int[6];
        myArray[7]= 10; // ArraysOutOfBoundException
 
        //Declaration of ArrayList. Add and Remove of elements is easy.
        ArrayList<Integer> myArrayList = new ArrayList<>();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.add(4);
        myArrayList.add(5);
        myArrayList.remove(0);
         
        for(int i = 0; i < myArrayList.size(); i++) {
        System.out.println("Element: " + myArrayList.get(i));
        }
         
        //Multi-dimensional Array 
        int[][][] multiArray = new int [3][3][3]; 
    }
}

آرایه‌‌ها دارای اندازه ثابتی هستند، اما لیست‌آرایه‌ها اندازه متغیری دارند. از آنجا که اندازه آرایه ثابت است حافظه‌ی آن در زمان اعلان متغیر از نوع array تخصیص می‌یابد. از این رو آرایه‌ها عملکرد بسیار سریعی دارند. از سوی دیگر، اگر اندازه داده‌ها را از پیش ندانیم، در این صورت قرار دادن داده‌های بیش از ظرفیت آرایه موجب بروز استثنای ArrayOutOfBoundException می‌شود و درج موارد کمتر هم موجب هدر رفتن حافظه خواهد شد.

  • حذف و اضافه کردن عناصر به ArrayList آسان‌تر از Array است.
  • آرایه می‌تواند چندبعدی باشد، اما ArrayList تنها یک بعد می‌توان داشته باشد.

گاهی اوقات Finally پس از Try اجرا نمی‌شود

قطعه کد زیر را در نظر بگیرد:

public class shutDownHooksDemo {
    public static void main(String[] args) {
        for(int i=0;i<5;i++)
        {
            try {
                if(i==4) {
                    System.out.println("Inside Try Block.Exiting without executing Finally block.");
                    System.exit(0);
                }
            }
            finally {
                System.out.println("Inside Finally Block.");
            }
        }
    }
}

با بررسی این قطعه کد شاید فکر کنید که 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-ها تنها می‌توانند روی اشیای زنده در زمانی که از سوی نخ‌های دیگر دست‌کاری می‌شوند اجرا گردند. به این ترتیب نتایج غیر قابل پیش‌بینی و یا حتی بن‌بست رخ می‌دهد.

public class shutDownHooksDemo {
 
    public static void main(String[] args) {
            for(int i=0;i<5;i++)
            {
                    final int final_i = i;
                    try {
                            Runtime.getRuntime().addShutdownHook(
                                            new Thread() {
                                            public void run() {
                                            if(final_i==4) {
                                            System.out.println("Inside Try Block.Exiting without executing Finally block.");
                                            System.exit(0);
                                            }
                                            }
                                            });
                    }
                    finally {
                            System.out.println("Inside Finally Block.");
                    }
 
            }
    }
}

بررسی فرد بودن

خطوط کد زیر را بررسی کرده و بگویید آیا این کد می‌تواند فرد بودن یک عدد را با دقت پیش‌بینی کند؟

public boolean oddOrNot(int num) {
    return num % 2 == 1;
}

این خطوط کد صحیح به نظر می‌رسند، اما در یک‌چهارم موارد نتایج نادرستی بازگشت می‌دهند. اگر یک عدد فرد منفی را در نظر بگیریم، باقیمانده تقسیم بر 2 عدد 1 نخواهد بود. بنابراین نتیجه بازگشتی نادرست خواهد بود که نتیجه اشتباهی است. برای اصلاح این مشکل، کد را به صورت زیر بازنویسی می‌کنیم:

public boolean oddOrNot(int num) {
    return (num & 1) != 0;
}

با استفاده از کد فوق نه تنها مشکل اعداد منفی حل می‌شود، بلکه کد به مقدار زیادی بهینه‌تر نیز شده است. از آنجا که عملیات حسابی و منطقی بسیار سریع‌تر از ضرب و تقسیم هستند، نتایج در قطعه کد فوق با سرعت بسیار بالاتری اجرا می‌شوند.

اختلاف بین گیومه تکی و دوبل

به کد زیر توجه کنید:

public class Haha {
    public static void main(String args[]) {
    System.out.print("H" + "a");
    System.out.print('H' + 'a');
    }
}

در این کد به نظر می‌رسد که باید مقدار HaHa بازگشت یابد، اما در عوض مقدار Ha169 بازگشت خواهد یافت. دلیل این مسئله آن است که در صورت استفاده از گیومه‌های دوبل، کاراکترها مانند رشته تصور می‌شوند، اما زمانی که از گیومه تکی استفاده کنیم، عملوندهای با ارزش char از طریق فرایندی به نام «تبدیل اولیه عریض‌سازی» (widening primitive conversion) به مقادیر int تبدیل می‌شوند. پس از تبدیل عدد صحیح، اعداد مورد نظر اضافه شده و مقدار 169 بازگشت می‌یابد.

اجتناب از نشت حافظه با ترفندهای ساده

نشت حافظه در اغلب موارد موجب کاهش عملکرد نرم‌افزار می‌شود. از آنجا که جاوا اقدام به مدیریت خودکار حافظه می‌کند، توسعه‌دهندگان کنترل زیادی روی آن ندارند. اما با این حال برخی رویه‌های استاندارد وجود دارند که می‌توانند برای حفاظت در برابر نشت حافظه مورد استفاده قرار گیرند.

  1. همیشه وقتی کوئری دیتابیس پایان یافت، اتصال پایگاه داده را آزاد کنید.
  2. همواره تلاش کنید بلوک Finally را مورد استفاده قرار دهید.
  3. وهله‌های ذخیره شده در جدول‌های استاتیک را همواره آزاد کنید.

جلوگیری از بروز بن‌بست در جاوا

«بن‌بست‌ها» (Deadlocks) به دلایل مختلفی رخ می‌دهند. هیچ دستورالعمل واحدی برای جلوگیری از بن‌بست وجود ندارد. به طور معمول بن‌بست‌ها زمانی رخ می‌دهند که اشیای همگام‌سازی‌شده منتظر یک قفل روی منبعی باشند که از سوی شیء همگام‌سازی‌شده دیگری قفل شده است.

برنامه زیر را اجرا کنید تا به طور عملی با یک بن‌بست آشنا شوید. این بن‌بست به این دلیل رخ می‌دهد که هر دو نخ منظر منبعی هستند که توسط نخ دیگری اشغال شده است. هر دوی این نخ‌ها در حالت انتظار می‌مانند و هیچ کدام آزاد نمی‌شوند.

public class DeadlockDemo {
   public static Object addLock = new Object();
   public static Object subLock = new Object();
 
   public static void main(String args[]) {
 
      MyAdditionThread add = new MyAdditionThread();
      MySubtractionThread sub = new MySubtractionThread();
      add.start();
      sub.start();
   }
private static class MyAdditionThread extends Thread {
      public void run() {
         synchronized (addLock) {
        int a = 10, b = 3;
        int c = a + b;
            System.out.println("Addition Thread: " + c);
            System.out.println("Holding First Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Addition Thread: Waiting for AddLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
   private static class MySubtractionThread extends Thread {
      public void run() {
         synchronized (subLock) {
        int a = 10, b = 3;
        int c = a - b;
            System.out.println("Subtraction Thread: " + c);
            System.out.println("Holding Second Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Subtraction  Thread: Waiting for SubLock...");
            synchronized (addLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
}

خروجی برنامه فوق چنین است:

=====
Addition Thread: 13
Subtraction Thread: 7
Holding First Lock...
Holding Second Lock...
Addition Thread: Waiting for AddLock...
Subtraction Thread: Waiting for SubLock...

اما اگر ترتیب فراخوانی نخ‌ها تغییر یابد، مشکل بن‌بست حل می‌شود:

public class DeadlockSolutionDemo {
   public static Object addLock = new Object();
   public static Object subLock = new Object();
 
   public static void main(String args[]) {
 
      MyAdditionThread add = new MyAdditionThread();
      MySubtractionThread sub = new MySubtractionThread();
      add.start();
      sub.start();
   }
 
 
private static class MyAdditionThread extends Thread {
      public void run() {
         synchronized (addLock) {
        int a = 10, b = 3;
        int c = a + b;
            System.out.println("Addition Thread: " + c);
            System.out.println("Holding First Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Addition Thread: Waiting for AddLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
    
   private static class MySubtractionThread extends Thread {
      public void run() {
         synchronized (addLock) {
        int a = 10, b = 3;
        int c = a - b;
            System.out.println("Subtraction Thread: " + c);
            System.out.println("Holding Second Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Subtraction  Thread: Waiting for SubLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
}

خروجی برنامه فوق چنین است:

=====
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 است.

ضرب

double square = double a * double a;                            // Optimized
double cube = double a * double a * double a;                   // Non-optimized
double cube = double a * double square;                         // Optimized
double quad = double a * double a * double a * double a;            // Non-optimized
double quad = double square * double square;                    // Optimized

متد pow

متد pow برای محاسبه مواردی استفاده می‌شود که ضرب ممکن نیست:

double cube = Math.pow(base, exponent);

متد Math.pow باید تنها در مواردی که ضروری است، استفاده شود. برای نمونه از آن برای محاسبه توان یک مقدار کسری استفاده می‌کنیم. دلیل این امر آن است که متد ()Math.pow به طور معمول حدود 300 تا 600 بار سریع‌تر از ضرب است.

مدیریت استثنای اشاره‌گر تهی

«استثناهای اشاره‌گر تهی» (Null Pointer Exceptions) در جاوا بسیار رایج هستند. این استثنا زمانی رخ می‌دهد که تلاش کنیم یک متد را روی یک مرجع شیء تهی فراخوانی کنیم. به مثال زیر توجه کنید.

int noOfStudents = school.listStudents().count;

در مثال فوق، اگر یک NullPointerException دریافت شود، در این صورت یا school و یا ()listStudents مقدار null داشته‌اند. بنابراین هماره بهتر است که مقادیر Null را در اولین فرصت ممکن بررسی کنیم:

private int getListOfStudents(File[] files) {
      if (files == null)
        throw new NullPointerException("File list cannot be null");
    }

Encode در JSON

JSON اختصاری برای عبارت «نمادگذاری شیء جاوا اسکریپت» (JavaScript Object Notation) است و برای ذخیره و تبادل داده‌ها مورد استفاده قرار می‌گیرد. JSON یک جایگزین با کاربری آسان برای فرمت داده XML محسوب می‌شود. این فرمت داده به جهت مشخصات خود و همچنین سبک بودنش این روزها در اینترنت محبوبیت زیادی کسب کرده است. یک ساختمان داده نرمال را می‌توان به JSON انکود کرد و به سادگی روی وب به اشتراک گذاشت. پیش از شروع به کدنویسی باید یک JSON parser را نصب کنیم. در مثال‌های زیر ما از json.simple (+) استفاده کرده‌ایم. در ادامه مثال ساده‌ای از انکودینگ JSON را مشاهده می‌کنید:

import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
 
public class JsonEncodeDemo {
     
    public static void main(String[] args) {
         
        JSONObject obj = new JSONObject();
        obj.put("Novel Name", "Godaan");
        obj.put("Author", "Munshi Premchand");
  
        JSONArray novelDetails = new JSONArray();
        novelDetails.add("Language: Hindi");
        novelDetails.add("Year of Publication: 1936");
        novelDetails.add("Publisher: Lokmanya Press");
         
        obj.put("Novel Details", novelDetails);
         
        System.out.print(obj);
    }
}

خروجی کد فوق چنین است:

{"Novel Name":"Godaan","Novel Details": ["Language: Hindi","Year of Publication: 1936","Publisher: Lokmanya Press"],"Author":"Munshi Premchand"}

دیکد از JSON

برای دیکد کردن JSON باید از اسکیمای آن اطلاع داشته باشیم. جزییات کار را در مثال زیر می‌بینید:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
 
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
 
public class JsonParseTest {
 
    private static final String filePath = "//home//user//Documents//jsonDemoFile.json";
     
    public static void main(String[] args) {
 
        try {
            // read the json file
            FileReader reader = new FileReader(filePath);
            JSONParser jsonParser = new JSONParser();
            JSONObject jsonObject = (JSONObject)jsonParser.parse(reader);
             
            // get a number from the JSON object
            Long id =  (Long) jsonObject.get("id");
            System.out.println("The id is: " + id);         
 
            // get a String from the JSON object
            String  type = (String) jsonObject.get("type");
            System.out.println("The type is: " + type);
 
            // get a String from the JSON object
            String  name = (String) jsonObject.get("name");
            System.out.println("The name is: " + name);
 
            // get a number from the JSON object
            Double ppu =  (Double) jsonObject.get("ppu");
            System.out.println("The PPU is: " + ppu);
             
            // get an array from the JSON object
            System.out.println("Batters:");
            JSONArray batterArray= (JSONArray) jsonObject.get("batters");
            Iterator i = batterArray.iterator();
            // take each value from the json array separately
            while (i.hasNext()) {
                JSONObject innerObj = (JSONObject) i.next();
                System.out.println("ID "+ innerObj.get("id") + 
                        " type " + innerObj.get("type"));
            }
 
            // get an array from the JSON object
            System.out.println("Topping:");
            JSONArray toppingArray= (JSONArray) jsonObject.get("topping");
            Iterator j = toppingArray.iterator();
            // take each value from the json array separately
            while (j.hasNext()) {
                JSONObject innerObj = (JSONObject) j.next();
                System.out.println("ID "+ innerObj.get("id") + 
                        " type " + innerObj.get("type"));
            }
             
 
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ParseException ex) {
            ex.printStackTrace();
        } catch (NullPointerException ex) {
            ex.printStackTrace();
        }
 
    }
 
}

فایل jsonDemoFile.json

{
    "id": 0001,
    "type": "donut",
    "name": "Cake",
    "ppu": 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" }
        ]
}

خروجی آن چنین است:

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- بازگشت می‌یابد.

public class StringSearch {
 
    public static void main(String[] args) {
        String myString = "I am a String!";
         
        if(myString.indexOf("String") == -1) {
            System.out.println("String not Found!");
        }
        else {
            System.out.println("String found at: " + myString.indexOf("String"));
        }
    }
}

فهرست‌بندی محتوای یک دایرکتوری

به منظور فهرست کردن محتوای یک دایرکتوری، می‌توانید از برنامه زیر استفاده کنید. این برنامه صرفاً نام‌های همه زیردایرکتوری‌ها و فایل‌های درون یک پوشه را داخل یک آرایه دریافت کرده و سپس این آرایه را به صورت ترتیبی پیمایش می‌کند تا همه محتوایش را لیست کند:

import java.io.*;
 
public class ListContents {
    public static void main(String[] args) {
        File file = new File("//home//user//Documents/");
        String[] files = file.list();
 
        System.out.println("Listing contents of " + file.getPath());
        for(int i=0 ; i < files.length ; i++)
        {
            System.out.println(files[i]);
        }
    }
}

برنامه ساده IO

جاوا برای خواندن از یک فایل و نوشتن داخل آن دو کلاس FileInputStream و FileOutputStream را ارائه کرده است. سازنده FileInputStream یک آرگومان filepath برای فایل ورودی می‌گیرد و استریم File Input را تولید می‌کند. به طور مشابه سازنده FileOutputStream آرگومان filepath مربوط به فایل خروجی را دریافت کرده و استریم File Output را ایجاد می‌کند. پس از این که مدیریت فایل پایان یافت، حتماً باید این استریم‌ها را Close کنید.

import java.io.*;
 
public class myIODemo {
    public static void main(String args[]) throws IOException {
        FileInputStream in = null;
        FileOutputStream out = null;
         
        try {
            in = new FileInputStream("//home//user//Documents//InputFile.txt");
            out = new FileOutputStream("//home//user//Documents//OutputFile.txt");
             
            int c;
            while((c = in.read()) != -1) {
                out.write(c);
            }
        } finally {
            if(in != null) {
                in.close();
            }
            if(out != null) {
                out.close();
            }
        }
    }
}

اجرای یک فرمان Shell از جاوا

جاوا یک کلاس Runtime برای اجرای فرمان‌های Shell ارائه کرده است. از آنجا که این‌ها فرمان‌های اکسترنال هستند، مدیریت استثنا اهمیت بسیار زیادی دارد. در مثال زیر این کاربرد را با طرح یک مثال معرفی کرده‌ایم. در این نمونه کد تلاش می‌کنیم تا یک فایل PDF را با استفاده از دستور Shell باز کنیم.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
 
public class ShellCommandExec {
 
    public static void main(String[] args) {
        String gnomeOpenCommand = "gnome-open //home//user//Documents//MyDoc.pdf";
 
        try {
            Runtime rt = Runtime.getRuntime();
            Process processObj = rt.exec(gnomeOpenCommand);
 
            InputStream stdin = processObj.getErrorStream();
            InputStreamReader isr = new InputStreamReader(stdin);
            BufferedReader br = new BufferedReader(isr);
 
            String myoutput = "";
 
            while ((myoutput=br.readLine()) != null) {
                myoutput = myoutput+"\n";
            }
            System.out.println(myoutput);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

استفاده از 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 انتهای ورودی
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class RegexMatches
{
    private static String pattern =  "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    private static Pattern mypattern = Pattern.compile(pattern);
     
    public static void main( String args[] ){
 
        String valEmail1 = "testemail@domain.com";
        String invalEmail1 = "....@domain.com";
        String invalEmail2 = ".$$%%@domain.com";
        String valEmail2 = "test.email@domain.com";
 
        System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail1));
        System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail1));
        System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail2));
        System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail2));
 
    }
     
    public static boolean validateEMailID(String emailID) {
        Matcher mtch = mypattern.matcher(emailID);
        if(mtch.matches()){
            return true;
        }
        return false;
    }   
}

نمونه‌ای از Java Swing

با کمک Java Swing می‌توان رابط‌های گرافیکی کاربر ایجاد کرد. جاوا کتابخانه javax را عرضه کرده است که حاوی swing است. آن رابط کاربری گرافیکی که از Java Swing استفاده بکند، باید بسط دادن JFrame آغاز شود. در این حالت باکس‌ها به نحوی اضافه می‌شوند که می‌توانند شامل کامپوننت‌های GUI از قبیل دکمه، دکمه رادیویی، کادر متنی و غیره باشند. این کادرها بر مبنای Container تنظیم می‌شوند.

import java.awt.*; 
import javax.swing.*;  
 
public class SwingsDemo extends JFrame 
{ 
    public SwingsDemo() 
    {
        String path = "//home//user//Documents//images";
        Container contentPane = getContentPane(); 
        contentPane.setLayout(new FlowLayout());   
         
        Box myHorizontalBox = Box. createHorizontalBox();  
        Box myVerticleBox = Box. createVerticalBox();   
         
        myHorizontalBox.add(new JButton("My Button 1")); 
        myHorizontalBox.add(new JButton("My Button 2")); 
        myHorizontalBox.add(new JButton("My Button 3"));   
 
        myVerticleBox.add(new JButton(new ImageIcon(path + "//Image1.jpg"))); 
        myVerticleBox.add(new JButton(new ImageIcon(path + "//Image2.jpg"))); 
        myVerticleBox.add(new JButton(new ImageIcon(path + "//Image3.jpg")));   
         
        contentPane.add(myHorizontalBox); 
        contentPane.add(myVerticleBox);   
         
        pack(); 
        setVisible(true);
    } 
     
    public static void main(String args[]) { 
        new SwingsDemo(); 
    }  
}

پخش صدا با جاوا

پخش صدا یکی از کاربردهای متداول در جاوا است که به طور خاص در بازی‌ها اهمیت زیادی دارد. در دموی زیر شیوه پخش یک فایل صوتی را با استفاده از کد جاوا نشان داده‌ایم:

import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
 
// To play sound using Clip, the process need to be alive.
// Hence, we use a Swing application.
public class playSoundDemo extends JFrame {
 
   // Constructor
   public playSoundDemo() {
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setTitle("Play Sound Demo");
      this.setSize(300, 200);
      this.setVisible(true);
 
      try {
         URL url = this.getClass().getResource("MyAudio.wav");
         AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
         Clip clip = AudioSystem.getClip();
         clip.open(audioIn);
         clip.start();
      } catch (UnsupportedAudioFileException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (LineUnavailableException e) {
         e.printStackTrace();
      }
   }
 
   public static void main(String[] args) {
      new playSoundDemo();
   }
}

اکسپورت PDF

اکسپورت کردن یک جدول PDF الزام رایجی در برنامه‌های جاوا محسوب می‌شود. این کار با استفاده از itextpdf به سادگی هر چه تمام انجام می‌یابد.

import java.io.FileOutputStream;
import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
 
public class DrawPdf {
 
      public static void main(String[] args) throws Exception {
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream("Employee.pdf"));
        document.open();
         
        Paragraph para = new Paragraph("Employee Table");
        para.setSpacingAfter(20);
        document.add(para);
         
        PdfPTable table = new PdfPTable(3);
        PdfPCell cell = new PdfPCell(new Paragraph("First Name"));
 
        table.addCell(cell);
        table.addCell("Last Name");
        table.addCell("Gender");
        table.addCell("Ram");
        table.addCell("Kumar");
        table.addCell("Male");
        table.addCell("Lakshmi");
        table.addCell("Devi");
        table.addCell("Female");
 
        document.add(table);
         
        document.close();
      }
    }

ارسال ایمیل از کد جاوا

ارسال ایمیل از جاوا کار آسانی است. کافی است Java Mail Jar را نصب کنیم و مسیر آن را برابر با classpath برنامه تعیین کنیم.

مشخصه‌های اصلی در کد تعیین می‌شوند و بهتر است از روشی که در کد زیر استفاده شده برای ارسال ایمیل استفاده کنیم:

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
 
public class SendEmail
{
    public static void main(String [] args)
    {    
        String to = "recipient@gmail.com";
        String from = "sender@gmail.com";
        String host = "localhost";
 
        Properties properties = System.getProperties();
        properties.setProperty("mail.smtp.host", host);
        Session session = Session.getDefaultInstance(properties);
 
        try{
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
 
            message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
 
            message.setSubject("My Email Subject");
            message.setText("My Message Body");
            Transport.send(message);
            System.out.println("Sent successfully!");
        }
        catch (MessagingException ex) {
            ex.printStackTrace();
        }
    }
}

اندازه‌گیری زمان

اپلیکیشن‌های زیادی نیازمند اندازه‌گیری کاملاً دقیق زمان هستند. به این منظور جاوا برخی متد‌های استاتیک را در کلاس System به شرح زیر عرضه کرده است:

currentTimeMillis()‎: این متد زمان جاری را بر حسب میلی‌ثانیه‌های سپری شده از Epoch Time و در فرمت Long بازگشت می‌‌دهد.

long startTime = System.currentTimeMillis();
long estimatedTime = System.currentTimeMillis() - startTime;

()nanoTime: این متد، مقدار جاری دقیق‌ترین تایمر سیستم موجود را بر حسب نانوثانیه و در فرمت Long بازگشت می‌دهد. متد ()nanoTime به منظور اندازه‌گیری بازه‌های زمانی نسبی به جای زمان‌بندی مطلق مورد استفاده قرار می‌گیرد.

long startTime = System.nanoTime();
long estimatedTime = System.nanoTime() - startTime;

تغییر مقیاس تصویر

برای تغییر ابعاد تصاویر می‌توان از usingAffineTransform استفاده کرد. قبل از هر چیز باید Image Buffer از روی تصویر ورودی ایجاد شود و سپس تصویر مقیاس‌بندی‌شده رندر می‌شود:

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
 
public class RescaleImage {
  public static void main(String[] args) throws Exception {
    BufferedImage imgSource = ImageIO.read(new File("images//Image3.jpg"));
    BufferedImage imgDestination = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = imgDestination.createGraphics();
    AffineTransform affinetransformation = AffineTransform.getScaleInstance(2, 2);
    g.drawRenderedImage(imgSource, affinetransformation);
    ImageIO.write(imgDestination, "JPG", new File("outImage.jpg"));
  }
}

به دست آوردن مختصات محل قرارگیری ماوس

با پیاده‌سازی اینترفیس MouseMotionListener در جاوا می‌توان رویدادها ماوس را پیگیری کرد. هنگامی که ماوس وارد منطقه خاصی شود، رویداد MouseMoved تحریک می‌شود و مختصات حرکت را می‌توان به دست آورد. در مثال زیر این کارکرد را نشان داده‌ایم:

import java.awt.event.*;
import javax.swing.*;
 
public class MouseCaptureDemo extends JFrame implements MouseMotionListener
{
    public JLabel mouseHoverStatus;
 
    public static void main(String args[]) 
    {
        new MouseCaptureDemo();
    }
 
    MouseCaptureDemo() 
    {
        setSize(500, 500);
        setTitle("Frame displaying Coordinates of Mouse Motion");
 
        mouseHoverStatus = new JLabel("No Mouse Hover Detected.", JLabel.CENTER);
        add(mouseHoverStatus);
        addMouseMotionListener(this);
        setVisible(true);
    }
 
    public void mouseMoved(MouseEvent e) 
    {
        mouseHoverStatus.setText("Mouse Cursor Coordinates => X:"+e.getX()+" | Y:"+e.getY());
    }
 
    public void mouseDragged(MouseEvent e) 
    {}
}

FileOutputStream در برابر FileWriter

نوشتن فایل در جاوا به طور عمده به دو روش با استفاده از FileOutputStream و FileWriter انجام می‌یابد. گاهی اوقات توسعه‌دهندگان در زمینه انتخاب یکی از این دو دچار تردید می‌شوند. در مثال زیر به انتخاب یکی از این دو روش کمک می‌کنیم. و توضیح می‌دهیم که کدام یک برای چه شرایطی مناسب‌تر است. ابتدا به بررسی بخش پیاده‌سازی می‌پردازیم.

استفاده از FileOutputStream

File foutput = new File(file_location_string);
FileOutputStream fos = new FileOutputStream(foutput);
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(fos));
output.write("Buffered Content");

استفاده از FileWriter

FileWriter fstream = new FileWriter(file_location_string);
BufferedWriter output = new BufferedWriter(fstream);
output.write("Buffered Content");

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 استفاده شود. اعداد اعشاری در اندازه‌گیری‌ها مفید هستند.

نمونه کد جاوا

الگوریتم‌ها و برنامه‌های کاربردی جاوا

در بخش قبلی این راهنما به طور عمده با نکات و ترفندهای کاربردی جاوا آشنا شدیم. در این بخش از مقاله می‌خواهیم برخی الگوریتم‌ها و برنامه‌های مهمی که به عنوان یک برنامه‌نویس جاوا باید با آن‌ها آشنا باشید را ارائه کنیم. در بخش نخست با برنامه‌های ابتدایی جاوا آشنا می‌شویم و در ادامه برخی برنامه‌های پیشرفته جاوا را نیز معرفی خواهیم کرد.

برنامه‌های کاربردی ساده جاوا

در ابتدا برخی الگوریتم‌ها و نمونه کد جاوا را با هم مرور می‌کنیم که برای اجرای برخی وظایف ساده و مقدماتی به شما کمک می‌کنند.

برنامه جاوا برای اجرای عملیات ابتدایی ماشین حساب

هنگامی که به یک ماشین حساب فکر می‌کنیم، عملیاتی مانند جمع، تفریق، ضرب و تقسیم به ذهن متبادر می‌شود. در ادامه این موارد عملیات ابتدایی را به کمک برنامه زیر پیاده‌سازی می‌کنیم.

package MyPackage;
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("Enter two numbers: ");
// nextDouble() reads the next double from the keyboard
double first = reader.nextDouble();
double second = reader.nextDouble();
System.out.print("Enter an operator (+, -, *, /): ");
char operator = reader.next().charAt(0);
double result;
//switch case for each of the operations
switch(operator)
{
case '+':
result = first + second;
break;
case '-':
result = first - second;
break;
case '*':
result = first * second;
break;
case '/':
result = first / second;
break;
// operator doesn't match any case constant (+, -, *, /)
 
 
default:
System.out.printf("Error! operator is not correct");
return;
}
//printing the result of the operations
System.out.printf("%.1f %c %.1f = %.1f", first, operator, second, result);
}
}

هنگامی که برنامه فوق را اجرا کنیم، یک خروجی مانند زیر مشاهده می‌کنیم:

Enter two numbers: 20 98
Enter an operator (+, -, *, /): /
20.0 / 98.0 = 0.2

برنامه جاوا برای یافتن فاکتوریل یک عدد

فاکتوریل یک عدد، حاصل‌ضرب همه اعداد مثبت کمتر یا برابر با آن عدد است. فاکتوریل یک عدد n به صورت!n نمایش می‌یابد. در ادامه یک برنامه به روش بازگشتی برای پیدا کردن فاکتوریل عدد ورودی می‌نویسیم.

package MyPackage;
import java.util.Scanner;
public class Factorial {
public static void main(String args[]){
//Scanner object for capturing the user input
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the number:");
//Stored the entered value in variable
int num = scanner.nextInt();
//Called the user defined function fact
int factorial = fact(num);
System.out.println("Factorial of entered number is: "+factorial);
}
static int fact(int n)
{
int output;
if(n==1){
return 1;
}
//Recursion: Function calling itself!!
output = fact(n-1)* n;
return output;
}
}

با اجرای برنامه فوق، فاکتوریل عدد به صورت زیر به دست می‌آید:

Enter the number:
12
Factorial of entered number is: 47900160

برنامه جاوا برای محاسبه سری فیبوناچی تا n عدد

سری فیبوناچی یک سری است که در آن عنصر بعدی مجموعه دو عنصر قبلی باشد. برای نمونه عناصر نخست این سری به صورت 0 1 1 2 3 5 8 13… است. در ادامه برنامه‌ای می‌نویسیم که سری‌های فیبوناچی را محاسبه کند:

package MyPackage;
public class Fibonacci {
public static void main(String[] args) {
//initializing the constants
int n = 100, t1 = 0, t2 = 1;
System.out.print("Upto " + n + ": ");
//while loop to calculate fibonacci series upto n numbers
while (t1<= n)
{
System.out.print(t1 + " + ");
int sum = t1 + t2;
t1 = t2;
t2 = sum;
}
}
}

خروجی کد فوق به صورت زیر است:

Upto 100: 0 + 1 + 1 + 2 + 3 + 5 + 8 + 13 + 21 + 34 + 55 + 89 +

برنامه یافتن پالیندروم بودن یا نبودن یک رشته

«پالیندروم» (Palindrome) عدد، رشته یا دنباله‌ای است که پس از معکوس شدن هم دقیقاً همانند حالا اولش باشد. برای نمونه کلمه «درد» را اگر از آخر به اول بنویسید، همچنان «درد» خواهد بود.

package MyPackage;
import java.util.Scanner;
public class Palindrome {
static void checkPalindrome(String input) {
//Assuming result to be true
boolean res = true;
int length = input.length();
//dividing the length of the string by 2 and comparing it.
for(int i=0; i<= length/2; i++) {
if(input.charAt(i) != input.charAt(length-i-1)) {
res = false;
break;
}
}
System.out.println(input + " is palindrome = "+res);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter your Statement: ");
String str = sc.nextLine();
//function call
checkPalindrome(str);
}
}

هنگامی که کد فوق را اجرا کنیم، بررسی می‌کند آیا رشته مفروض یک پالیندروم است یا نه:

Enter your Statement: RACECAR
RACECAR is palindrome = true

Enter your Statement: MyPackage
MyPackage is palindrome = false

برنامه محاسبه جایگشت و ترکیب دو عدد

جایگشت و ترکیب دو مجموعه، به چیدمان متفاوت تعداد مفروضی از عناصر آن دو مجموعه گفته می‌شود که یک به یک، یا به یک‌باره انتخاب شوند. پیاده‌سازی آن چنین است:

package MyPackage;
import java.util.Scanner;
public class nprandncr {
//calculating a factorial of a number
public static int fact(int num)
{
int fact=1, i;
for(i=1; i<=num; i++)
{
fact = fact*i;
}
return fact;
}
public static void main(String args[])
{
int n, r;
Scanner scan = new Scanner(System.in);
System.out.print("Enter Value of n : ");
n = scan.nextInt();
System.out.print("Enter Value of r : ");
r = scan.nextInt();
// NCR and NPR of a number
System.out.print("NCR = " +(fact(n)/(fact(n-r)*fact(r))));
System.out.print("nNPR = " +(fact(n)/(fact(n-r))));
}
}

با اجرای کد فوق، یک خروجی مانند زیر به دست می‌آید:

Enter Value of n: 5
Enter Value of r: 3
NCR = 10
NPR = 60

برنامه پرینت الگوی الفبایی (A) و الماس

در این مثال از حلقه برای پرینت الگوهای مختلف در جاوا استفاده می‌کنیم. ما دو الگوی متفاوت را پیاده‌سازی می‌کنیم که یکی الگوی الفبایی و دیگری الگوی شکل الماس است. پیاده‌سازی الگوی الفبایی حرف ‌َ A چنین است:

package MyPackage;
import java.util.Scanner;
public class PatternA {
// Java program to print alphabet A pattern
void display(int n)
{
// Outer for loop for number of lines
for (int i = 0; i<=n; i++) {
// Inner for loop for logic execution
for (int j = 0; j<= n / 2; j++) {
// prints two column lines
if ((j == 0 || j == n / 2) && i != 0 ||
// print first line of alphabet
i == 0  && j != n / 2 ||
// prints middle line
i == n / 2)
System.out.print("*");
else
System.out.print(" ");
}
System.out.println();
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
PatternA a = new PatternA();
a.display(7);
}
}

خروجی کد فوق چنین است:

برنامه پرینت الگوی الماس نیز در جاوا به صورت زیر است:

package MyPackage;
import java.util.Scanner;
public class DiamondPattern
{
public static void main(String args[])
{
int n, i, j, space = 1;
System.out.print("Enter the number of rows: ");
Scanner s = new Scanner(System.in);
n = s.nextInt();
space = n - 1;
for (j = 1; j<= n; j++)
{
for (i = 1; i<= space; i++)
{
System.out.print(" ");
}
space--;
for (i = 1; i <= 2 * j - 1; i++)
{
System.out.print("*");
}
System.out.println("");
}
space = 1;
for (j = 1; j<= n - 1; j++)
{
for (i = 1; i<= space; i++)
{
System.out.print(" ");
}
space++;
for (i = 1; i<= 2 * (n - j) - 1; i++)
{
System.out.print("*");
}
System.out.println("");
}
}
}

خروجی برنامه فوق مانند زیر است:

Enter the number of rows: 5

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

برنامه معکوس‌سازی حروف موجود در یک رشته

این برنامه جاوا ترتیب حروف موجود در یک رشته متنی را که کاربر وارد کرده است، معکوس می‌سازد. برای نمونه عبارت Hello People به صورت olleH elpoeP تبدیل می‌شود. کد جاوا چنین است:

package MyPackage;
public class stringreverse {
public static void main(String[] args) {
// TODO Auto-generated method stub
String str = "Welcome To MyPackage";
String[] strArray = str.split(" ");
for (String temp: strArray){
System.out.println(temp);
}
for(int i=0; i<3; i++){ char[] s1 = strArray[i].toCharArray(); for (int j = s1.length-1; j>=0; j--)
{System.out.print(s1[j]);}
System.out.print(" ");
}
}
}

خروجی برنامه فوق مانند زیر است:

Welcome
To
MyPackage
emocleW oT akerudE

برنامه‌ای برای بررسی خصوصیت بازتاب آینه‌ای در یک آرایه

یک آرایه زمانی دارای خصوصیت «بازتاب آینه‌ای» (Mirror–Inverse) گفته می‌شود که معکوس آن برابر با خودش باشد. اکنون برنامه‌ای می‌نویسیم که وجود خصوصیت بازتاب آینه‌ای را در یک آرایه بررسی کند:

package MyPackage;
//Java implementation of the approach
public class MirrorInverse {
// Function that returns true if
// the array is mirror-inverse
static boolean isMirrorInverse(int arr[])
{
for (int i = 0; i<arr.length; i++) {
// If condition fails for any element
if (arr[arr[i]] != i)
return false;
}
// Given array is mirror-inverse
return true;
}
 
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 0 };
if (isMirrorInverse(arr))
System.out.println("Yes");
else
System.out.println("No");
}
}

خروجی این کد چنین است: No

بنابراین آرایه ورودی دارای خصوصیت بازتاب آینه‌ای نبوده است. اما اگر از آرایه {3,4,2,0,1} استفاده کنیم، خروجی yes چاپ می‌شود، زیرا آرایه خصوصیت مورد نظر را دارد.

نمونه کد جاوا

برنامه‌های کاربردی پیشرفته جاوا

در این بخش برخی برنامه‌های جاوا را بررسی می‌کنیم که شاید کمی فراتر از سطح مبتدی باشند و برای افرادی که در سطح متوسط و یا حتی پیشرفته یادگیری جاوا هستند، مفید خواهند بود.

برنامه پیاده‌سازی الگوریتم جستجوی دودویی

جستجوی دودویی (Binary Search) یک الگوریتم جستجو است که موقعیت مقدار هدف را درون یک آرایه مرتب‌شده پیدا می‌کند. جستجوی دودویی مقدار مورد نظر را با عنصر میانه آرایه مقایسه می‌کند. پیاده‌سازی آن در جاوا به صورت زیر است:

package MyPackage;
public class BinarySearch {
// Java implementation of recursive Binary Search
// Returns index of x if it is present in arr[l..
// r], else return -1
int binarySearch(int arr[], int l, int r, int x)
{
if (r >= l) {
int mid = l + (r - l) / 2;
// If the element is present at the
// middle itself
if (arr[mid] == x)
return mid;
// If element is smaller than mid, then
// it can only be present in left subarray
if (arr[mid] >x)
return binarySearch(arr, l, mid - 1, x);
// Else the element can only be present
// in right subarray
return binarySearch(arr, mid + 1, r, x);
}
// We reach here when element is not present
// in array
return -1;
}
public static void main(String args[])
{
BinarySearch ob = new BinarySearch();
int arr[] = { 2, 3, 4, 10, 40 };
int n = arr.length;
int x = 40;
int result = ob.binarySearch(arr, 0, n - 1, x);
if (result == -1)
System.out.println("Element not present");
else
System.out.println("Element found at index " + result);
}
}

با اجرای کد فوق، عنصر موجود در یک ایندکس خاص را جستجو می‌کند. خروجی کد فوق چنین است:

Element found at index 4

برنامه پیاده‌سازی الگوریتم HeapSort

مرتب‌سازی هیپ یک تکنیک مرتب‌سازی مبتنی بر مقایسه است که روی ساختمان داده Heap اجرا می‌شود. این الگوریتم مشابه مرتب‌سازی انتخابی است که در آن بزرگ‌ترین عنصر پیدا شده و سپس در انتهای لیست قرار می‌گیرد. در ادامه همین فرایند برای بقیه عناصر تکرار می‌شود. کد برنامه مرتب‌سازی هیپ در جاوا به صورت زیر است:

package MyPackage;
public class HeapSort
{
public void sort(int arr[])
{
int n = arr.length;
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
// One by one extract an element from heap
for (int i=n-1; i>=0; i--)
{
// Move current root to end
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
void heapify(int arr[], int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2*i + 1; // left = 2*i + 1
int r = 2*i + 2; // right = 2*i + 2
// If left child is larger than root
if (l< n && arr[l] >arr[largest])
largest = l;
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest])
largest = r;
 
// If largest is not root
if (largest != i)
{
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
/* A utility function to print array of size n */
static void printArray(int arr[])
{
int n = arr.length;
for (int i=0; i<n; ++i)
System.out.print(arr[i]+" ");
System.out.println();
}
// Driver program
public static void main(String args[])
{
int arr[] = {12, 11, 13, 5, 6, 7};
int n = arr.length;
HeapSort ob = new HeapSort();
ob.sort(arr);
System.out.println("Sorted array is");
printArray(arr);
}
}

خروجی کد فوق چنین است:

5,6,7,11,12,13

برنامه حذف عناصر از یک لیست‌آرایه

ArrayList یک پیاده‌سازی از اینترفیس لیست است که در آن عناصر می‌توانند به صورت دینامیک به لیست حذف یا اضافه شوند. همچنین اندازه لیست در صورت نیاز به افزون عناصر بیشتر از مقدار اولیه، به طور دینامیک افزایش می‌یابد. در برنامه زیر ابتدا برخی عناصر را دریک ArrayList درج می‌کنیم و سپس عناصر را بر اساس مشخصاتی از لیست حذف خواهیم کرد:

package MyPackage;
 
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
 
public class ArrayListExample {
public static void main(String[] args) {
List<String> programmingLanguages = new ArrayList<>();
programmingLanguages.add("C");
programmingLanguages.add("C++");
programmingLanguages.add("Java");
programmingLanguages.add("Kotlin");
programmingLanguages.add("Python");
programmingLanguages.add("Perl");
programmingLanguages.add("Ruby");
 
System.out.println("Initial List: " + programmingLanguages);
 
// Remove the element at index `5`
programmingLanguages.remove(5);
System.out.println("After remove(5): " + programmingLanguages);
 
// Remove the first occurrence of the given element from the ArrayList
// (The remove() method returns false if the element does not exist in the ArrayList)
boolean isRemoved = programmingLanguages.remove("Kotlin");
System.out.println("After remove(\"Kotlin\"): " + programmingLanguages);
 
// Remove all the elements that exist in a given collection
List<String> scriptingLanguages = new ArrayList<>();
scriptingLanguages.add("Python");
scriptingLanguages.add("Ruby");
scriptingLanguages.add("Perl");
 
programmingLanguages.removeAll(scriptingLanguages);
System.out.println("After removeAll(scriptingLanguages): " + programmingLanguages);
 
// Remove all the elements that satisfy the given predicate
programmingLanguages.removeIf(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("C");
}
});
 
System.out.println("After Removing all elements that start with \"C\": " + programmingLanguages);
 
// Remove all elements from the ArrayList
programmingLanguages.clear();
System.out.println("After clear(): " + programmingLanguages);
}
}

خروجی کد فوق چنین است:

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 را در جاوا مشاهده می‌کنید:

package MyPackage;
 
import java.util.HashMap;
import java.util.Map;
 
public class Hashmap
{
public static void main(String[] args)
{
HashMap<String, Integer> map = new HashMap<>();
print(map);
map.put("abc", 10);
map.put("mno", 30);
map.put("xyz", 20);
 
System.out.println("Size of map is" + map.size());
 
print(map);
if (map.containsKey("abc"))
{
Integer a = map.get("abc");
System.out.println("value for key \"abc\" is:- " + a);
}
map.clear();
print(map);
}
public static void print(Map<String, Integer> map)
{
if (map.isEmpty())
{
System.out.println("map is empty");
}
else
{
System.out.println(map);
}
}
}

خروجی کد فوق چنین است:

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 نیز یک اشاره‌گر به گره بعدی است. کد پیاده‌سازی این برنامه به صورت زیر است:

package MyPackage;
 
public class CircularlinkedList {
//Represents the node of list.
public class Node{
int data;
Node next;
public Node(int data) {
this.data = data;
}
}
//Declaring head and tail pointer as null.
public Node head = null;
public Node tail = null;
 
//This function will add the new node at the end of the list.
public void add(int data){
//Create new node
Node newNode = new Node(data);
//Checks if the list is empty.
if(head == null) {
//If list is empty, both head and tail would point to new node.
head = newNode;
tail = newNode;
newNode.next = head;
}
else {
//tail will point to new node.
tail.next = newNode;
//New node will become new tail.
tail = newNode;
//Since, it is circular linked list tail will point to head.
tail.next = head;
}
}
 
//Displays all the nodes in the list
public void display() {
Node current = head;
if(head == null) {
System.out.println("List is empty");
}
else {
System.out.println("Nodes of the circular linked list: ");
do{
//Prints each node by incrementing pointer.
System.out.print(" "+ current.data);
current = current.next;
}while(current != head);
System.out.println();
}
}
 
public static void main(String[] args) {
CircularlinkedList cl = new CircularlinkedList();
//Adds data to the list
cl.add(1);
cl.add(2);
cl.add(3);
cl.add(4);
//Displays all the nodes present in the list
cl.display();
}
}

با اجرای این برنامه، یک خروجی مانند زیر به دست می‌آید:

Nodes of the circular linked list:
1 2 3 4

برنامه اتصال به یک پایگاه داده SQL

JDBC یک API استاندارد جاوا برای اتصال‌پذیری وابسته به پایگاه داده بین زبان برنامه‌نویسی جاوا و طیف گسترده‌ای از دیتابیس‌ها است. این اینترفیس برنامه کاربردی امکان انکود کردن گزاره‌های درخواست دسترسی را به «زبان کوئری ساخت‌یافته» (Structured Query Language | SQL) فراهم ساخته است. در ادامه این گزاره‌ها به برنامه‌ای که دیتابیس را مدیریت می‌کند، ارسال خواهند شد. JDBC به طور عمده به منظور اجرای وظایف باز کردن یک اتصال به دیتابیس، ایجاد یک دیتابیس SQL، اجرای کوئری‌های SQL، و همچنین دریافت خروجی استفاده می‌شود.

در کد نمونه زیر یک پایگاه داده ایجاد کرده و پس از برقراری اتصال با آن اقدام به اجرای کوئری می‌کنیم.

package MyPackage;
import java.sql.*;
import java.sql.DriverManager;
public class Example {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/emp";
// Database credentials
static final String USER = "root";
static final String PASS = "MyPackage";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//STEP 2: Register JDBC driver
Class.forName("com.mysql.cj.jdbc.Driver");
//STEP 3: Open a connection
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,"root","MyPackage");
//STEP 4: Execute a query
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, first, last, age FROM Employees";
ResultSet rs = stmt.executeQuery(sql);
//STEP 5: Extract data from result set
while(rs.next()){
//Retrieve by column name
int id = rs.getInt("id");
int age = rs.getInt("age");
String first = rs.getString("first");
String last = rs.getString("last");
//Display values
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", First: " + first);
System.out.println(", Last: " + last);
}
//STEP 6: Clean-up environment
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
//Handle errors for JDBC
se.printStackTrace();
}catch(Exception e){
//Handle errors for Class.forName
e.printStackTrace();
}finally{
//finally block used to close resources
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}// nothing can be done
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}//end finally try
}//end try
System.out.println("Goodbye!");
}//end main
} // end Example

با اجرای کد فوق، یک اتصال با دیتابیس برقرار می‌شود و داده‌های موجود در پایگاه داده بازگشت می‌یابد:

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]. به دست می‌آید.

package MyPackage;
 
public class Transpose
{
static final int N = 4;
 
// This function stores transpose
// of A[][] in B[][]
static void transpose(int A[][], int B[][])
{
int i, j;
for (i = 0; i< N; i++)
for (j = 0; j <N; j++)
B[i][j] = A[j][i];
}
 
public static void main (String[] args)
{
int A[][] = { {1, 1, 1, 1},
{2, 2, 2, 2},
{3, 3, 3, 3},
{4, 4, 4, 4}};
 
int B[][] = new int[N][N], i, j;
 
transpose(A, B);
 
System.out.print("Result matrix is n");
for (i = 0; i<N; i++)
{
for (j = 0; j<N; j++)
System.out.print(B[i][j] + " ");
System.out.print("n");
}
}
}

با اجرای کد فوق، خروجی زیر به دست می‌آید:

Result matrix is
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
نمونه کد جاوا

سخن پایانی

به این ترتیب به پایان این مقاله با موضوع معرفی نمونه‌ کد جاوا می‌رسیم. جاوا یکی از محبوب‌ترین زبان‌های برنامه‌نویسی است که از زمان معرفی شدن، همواره جزء یکی از سه زبان محبوب توسعه‌دهندگان بوده است.

در این مقاله تلاش کردیم با ارائه انواع نمونه کد جاوا شما را چه در ابتدای مسیر یادگیری این زبان باشید و چه در زمینه یادگیری جاوا به سطح متوسطی رسیده باشید، کمک کنیم. همچنین نمونه کدها و الگوریتم‌های معرفی شده در بخش انتهایی این راهنما احتمالاً حتی برای توسعه‌دهندگان حرفه‌ای و باتجربه نیز به عنوان یک یادآوری سریع و عملی، مفید واقع خواهند شد.

بر اساس رای ۳ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
geeksforgeeks javacodegeeks edureka
One thought on “نمونه کد جاوا — نمونه کدهای کاربردی برای برنامه نویسان جاوا

من C# کار کردم شنیده بودم شبیه جاواست ولی نمیدانستم تا این حد شبیه هم هستند.

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *