در این مقاله، به آموزش ایجاد حلقه های تودرتو در جاوا می پردازیم و در قالب چند مثال و یک نمودار روش استفاده از آنها را آموزش می دهیم. پس اگر قصد دارید در زبان برنامه نویسی جاوا، حلقه های تودرتوی if یا while ایجاد کنید، این مقاله ی آموزشی را مطالعه نمایید. 


همان طور که دستورات if می توانند تودرتو باشند، حلقه ها نیز چنین هستند. ما می توانیم یک حلقه ی while را در داخل یک حلقه ی while قرار دهیم، یا یک حلقه ی for را در داخل یک حلقه ی for قرار دهیم، یا می توانیم یک حلقه ی while را در داخل یک حلقه for قرار دهیم یا از هر ترکیب دیگری استفاده کنیم. 

وقتی که حلقه ها تودرتو باشند، هر جفت از حلقه ها، حاوی یک حلقه ی درونی و یک حلقه ی بیرونی می باشد. حلقه ی درونی باید کاملاً در داخل حلقه ی بیرونی باشد؛ حلقه ها هرگز نمی توانند روی یکدیگر بیفتند. تصویر 6.18 یک نمودار را نشان می دهد که حلقه ی رنگی شده(آبی) در آن، درون یک حلقه ی دیگر قرار دارد. یعنی ناحیه ی آبی رنگ، حلقه ی درونی را مشخص می کند. 

ما به صورت مجازی می توانیم هر تعداد که بخواهیم، حلقه های تودرتو ایجاد کنیم؛ اما دستگاه ما در یک نقطه، دیگر قادر به ذخیره تمام اطلاعات مورد نیاز حلقه نیست.

(تصویر 6.18 : حلقه های تودرتو)

آموزش حلقه های تودرتو در جاوا

فرض کنید می خواهیم موجودی های آینده ی یک حساب بانکی را در حالیکه هم سال ها و هم نرخ های سود، متغیر است، نمایش دهیم. تصویر 6.19 یک اپلیکیشن را نشان می دهد که حاوی یک حلقه ی بیرونی است که نرخ سود را بین حدود مشخص شده، تغییر می دهد. در ابتدای حلقه ی بیرونی(یعنی حلقه ی for بیرونی)، موجودیِ استفاده شونده، به مقدار اولیه ی خود ریست می شود(balance = initialBalance;)؛ به طوری که محاسبات برای هر مقدار نرخ سود اصلاح شده صحیح باشد. حلقه ی رنگی شده ی درونی، تعداد سا ل ها را نمایش می دهد و هر موجودی(balance) محاسبه شده را نمایش می دهد. تصویر 6.20 یک محاسبه ی نمونه را نشان می دهد. 

(تصویر 6.19 : کلاس BankBalanceByRateAndYear که حاوی حلقه های تودرتو است)

یک کلاس در مورد حلقه های تودرتو در جاوا

(تصویر 6.20 : اجرای برنامه ی BankBalanceByRateAndYear)

یک برنامه از حلقه های تودرتو در جاوا

نکته: در تصویر 6.20 محاسبات ممیز شناور منجر به ایجاد موجودی هایی می شود که حاوی کسری از پنی(سنت؛ یک صدم دلار)  هستند. اگر این برنامه را برای یک بانک بنویسید، باید بپرسید که آیا سود باید با کسری از سنت(مانند اینجا) ترکیب شود یا اینکه مقادیر باید گرد یا کوتاه شوند.


وقتی که ما حلقه های تودرتو ایجاد می کنیم، گاهی اوقات هیچ فرقی نمی کند که کدام متغیر حلقه ی بیرونی و کدام متغیر حلقه ی درونی را کنترل می کند؛ اما اغلب اوقات تفاوت ایجاد می کند. وقتی که از یک حلقه در درون یک حلقه ی دیگر استفاده می کنیم، همواره باید به حلقه ی بیرونی بعنوان حلقه ی  همه جانبه(all-encompassing) نگاه کنیم. متغیری که در حلقه ی بیرونی قرار دارد، به ندرت تغییر می کند.

بعنوان مثال، فرض کنید یک متد به نام outputLabel() داریم که برچسب های پستی مشتری را در سه رنگ مختلف، برای استفاده در پست های تبلیغاتی(successive promotional mailings)  ایجاد می کند. حلقه ی تودرتوی زیر، متد مذکور را 60 بار فراخوانی می کند و برای اولین مشتری، سه برچسب تولید می کند و برای مشتری دوم نیز سه برچسب تولید می کند و همین طور الی اخر:

for(customer = 1; customer <= 20; ++customer)
  for(color = 1; color <= 3; ++color)
    outputLabel();

حلقه ی تودرتوی زیر نیز متد outputLabel() را 60 بار فراخوانی می کند و درنهایت 60 برچسب مشابه را تولید می کند اما این حلقه، 20 برچسب را به رنگ اول و 20 برچسب را به رنگ دوم و 20 برچسب را به رنگ سوم ایجاد می کند:

for(color = 1; color <= 3; ++color)
  for(customer = 1; customer <= 20; ++customer)
    outputLabel();

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


دو عبارت صحیح و یک عبارت اشتباه

موضوع: آموزش حلقه های تودرتو

1. ما می توانیم یک حلقه ی while را در داخل یک حلقه ی while دیگر قرار دهیم یا می توانیم یک حلقه ی for را در درون یک حلقه for قرار دهیم اما نمی توانیم این نوع حلقه ها را با یکدیگر ترکیب کنیم.

2. حلقه ای که در درون یک حلقه ی تودرتو قرار دارد باید به طور کامل در حلقه ی بیرونی قرار گیرد. 

3. بدنه ی حلقه ی پایین، 20 بار اجرا می شود:

for(int x = 0; x < 4; ++x)
  for(int y = 0; y < 5; ++y)
    System.out.println("Hi");

پاسخ:

عبارت شماره 1 اشتباه است. ما می توانیم یک حلقه ی while را در داخل یک حلقه ی while دیگر قرار دهیم  و می توانیم یک حلقه ی for را در داخل یک حلقه ی for دیگر قرار دهیم و می توانیم یک حلقه ی while را در یک حلقه for قرار دهیم یا هر ترکیب دیگری را انجام دهیم.