Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions html-generators/generate.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ void buildLocale(String locale, Templates templates, SequencedMap<String, Snippe
var extraTokens = new LinkedHashMap<String, String>();
extraTokens.putAll(strings);
extraTokens.put("locale", locale);
extraTokens.put("htmlDir", locale.equals("ar") ? "rtl" : "ltr");
extraTokens.put("ogLocale", locale.replace("-", "_"));
extraTokens.put("basePrefix", basePrefix);
extraTokens.put("homeUrl", homeUrl);
Expand Down Expand Up @@ -264,6 +265,7 @@ void buildLocale(String locale, Templates templates, SequencedMap<String, Snippe
indexTokens.put("tipCards", tipCards);
indexTokens.put("snippetCount", String.valueOf(allSnippets.size()));
indexTokens.put("locale", locale);
indexTokens.put("htmlDir", locale.equals("ar") ? "rtl" : "ltr");
indexTokens.put("ogLocale", locale.replace("-", "_"));
indexTokens.put("canonicalUrl", isEnglish ? BASE_URL : BASE_URL + "/" + locale);
indexTokens.put("homeUrl", homeUrl);
Expand Down
4 changes: 4 additions & 0 deletions html-generators/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ def generate_html(template, why_card_template, related_card_template,
"supportDescription": escape(data["support"]["description"]),
"supportBadge": _support_badge(data["support"]["state"]),
"supportBadgeClass": _support_badge_class(data["support"]["state"]),
"locale": "en",
"htmlDir": "ltr",
"canonicalUrl": f"{BASE_URL}/{cat}/{slug}.html",
"flatUrl": f"{BASE_URL}/{slug}.html",
"titleJson": json_escape(data["title"]),
Expand Down Expand Up @@ -285,6 +287,8 @@ def main():
index_html = replace_tokens(index_template, {
"tipCards": tip_cards,
"snippetCount": str(count),
"locale": "en",
"htmlDir": "ltr",
})
with open(os.path.join(SITE_DIR, "index.html"), "w") as f:
f.write(index_html)
Expand Down
1 change: 1 addition & 0 deletions html-generators/locales.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ en=English
de=Deutsch
es=Español
pt-BR=Português (Brasil)
ar=العربية
fr=Français
ja=日本語
2 changes: 1 addition & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="{{locale}}">
<html lang="{{locale}}" dir="{{htmlDir}}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Expand Down
2 changes: 1 addition & 1 deletion templates/slug-template.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="{{locale}}">
<html lang="{{locale}}" dir="{{htmlDir}}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Expand Down
17 changes: 17 additions & 0 deletions translations/content/ar/collections/collectors-teeing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "Collectors.teeing()"
oldApproach: "تمريرتان على البيانات"
modernApproach: "teeing()"
summary: "احسب تجميعَين في تمريرة واحدة على Stream."
explanation: "يُرسل Collectors.teeing() كل عنصر إلى مُجمِّعَين فرعيَّين ثم يدمج النتيجتين. يتجنّب هذا تكرار تدفق البيانات مرتين أو استخدام متراكم قابل للتعديل."
whyModernWins:
- icon: "⚡"
title: "تمريرة واحدة"
desc: "تمر على Stream مرة واحدة بدلاً من مرتين."
- icon: "🧩"
title: "قابل للتركيب"
desc: "ادمج أي مُجمِّعَين باستخدام دالة دمج."
- icon: "🔒"
title: "نتيجة ثابتة"
desc: "ادمج مباشرةً في record أو كائن قيمة."
support:
description: "متاح على نطاق واسع منذ JDK 12 (مارس 2019)"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "نسخ المجموعات بصورة ثابتة"
oldApproach: "نسخ يدوي + تغليف"
modernApproach: "List.copyOf()"
summary: "أنشئ نسخة ثابتة من أي مجموعة في استدعاء واحد."
explanation: "تُنشئ List.copyOf() و Set.copyOf() و Map.copyOf() نسخاً ثابتة من المجموعات الموجودة. إذا كان المصدر مجموعةً ثابتةً بالفعل فلن تُنشأ نسخة."
whyModernWins:
- icon: "⚡"
title: "نسخ ذكي"
desc: "يتجاوز النسخ إذا كان المصدر ثابتاً بالفعل."
- icon: "📏"
title: "استدعاء واحد"
desc: "لا حاجة لإنشاء ArrayList يدوياً ثم تغليفه."
- icon: "🛡️"
title: "نسخة دفاعية"
desc: "التغييرات في المصدر لا تؤثر على النسخة."
support:
description: "متاح على نطاق واسع منذ JDK 10 (مارس 2018)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/immutable-list-creation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "إنشاء قوائم ثابتة"
oldApproach: "تغليف مطوّل"
modernApproach: "List.of()"
summary: "أنشئ قوائم ثابتة في تعبير واحد نظيف."
explanation: "تُنشئ List.of() قائمةً ثابتةً حقيقيةً دون تغليف أو نسخ دفاعية. وهي لا تقبل القيم الفارغة وهي ثابتة هيكلياً. كانت الطريقة القديمة تتطلب ثلاثة استدعاءات متداخلة."
whyModernWins:
- icon: "📏"
title: "استدعاء واحد"
desc: "استبدل ثلاثة استدعاءات متداخلة بدالة مصنع واحدة."
- icon: "🔒"
title: "ثابتة حقاً"
desc: "ليست مجرد غلاف — القائمة نفسها ثابتة."
- icon: "🛡️"
title: "آمنة من القيم الفارغة"
desc: "ترفض عناصر null وقت الإنشاء وتفشل مبكراً."
support:
description: "متاح على نطاق واسع منذ JDK 9 (سبتمبر 2017)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/immutable-map-creation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "إنشاء خرائط ثابتة"
oldApproach: "نمط بناء الخريطة"
modernApproach: "Map.of()"
summary: "أنشئ خرائط ثابتة مضمّنةً دون مُنشئ."
explanation: "تقبل Map.of() أزواجاً من المفاتيح والقيم مضمّنةً وتُرجع خريطةً ثابتة. للحصول على أكثر من 10 إدخالات، استخدم Map.ofEntries() مع أزواج Map.entry()."
whyModernWins:
- icon: "📏"
title: "إنشاء مضمّن"
desc: "لا حاجة لخريطة مؤقتة قابلة للتعديل."
- icon: "🔒"
title: "نتيجة ثابتة"
desc: "لا يمكن تعديل الخريطة بعد إنشائها."
- icon: "🚫"
title: "لا مفاتيح/قيم فارغة"
desc: "تُرفض الإدخالات الفارغة فوراً."
support:
description: "متاح على نطاق واسع منذ JDK 9 (سبتمبر 2017)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/immutable-set-creation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "إنشاء مجموعات ثابتة"
oldApproach: "تغليف مطوّل"
modernApproach: "Set.of()"
summary: "أنشئ مجموعات ثابتة باستدعاء مصنع واحد."
explanation: "تُنشئ Set.of() مجموعةً ثابتةً حقيقيةً ترفض القيم الفارغة والعناصر المكررة وقت الإنشاء. لا مزيد من تغليف المجموعات القابلة للتعديل."
whyModernWins:
- icon: "📏"
title: "موجز"
desc: "سطر واحد بدلاً من ثلاثة استدعاءات متداخلة."
- icon: "🚫"
title: "يكشف التكرار"
desc: "يُطلق استثناءً إذا مررت عناصر مكررة عن طريق الخطأ."
- icon: "🔒"
title: "ثابتة"
desc: "لا إضافة أو حذف ممكن بعد الإنشاء."
support:
description: "متاح على نطاق واسع منذ JDK 9 (سبتمبر 2017)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/map-entry-factory.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "دالة مصنع Map.entry()"
oldApproach: "SimpleEntry"
modernApproach: "Map.entry()"
summary: "أنشئ إدخالات الخريطة بدالة مصنع نظيفة."
explanation: "تستبدل Map.entry() مُنشئ AbstractMap.SimpleEntry المطوّل. وهي تُرجع إدخالاً ثابتاً مما يجعلها مثاليةً مع Map.ofEntries() وعمليات Stream."
whyModernWins:
- icon: "📏"
title: "موجز"
desc: "سطر واحد بدلاً من ثلاثة بنيّة أوضح."
- icon: "🔒"
title: "ثابت"
desc: "لا يمكن تعديل الإدخال المُرجَع."
- icon: "🧩"
title: "قابل للتركيب"
desc: "يعمل بشكل مثالي مع Map.ofEntries() للخرائط الكبيرة."
support:
description: "متاح على نطاق واسع منذ JDK 9 (سبتمبر 2017)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/reverse-list-iteration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "التكرار العكسي على القوائم"
oldApproach: "ListIterator يدوي"
modernApproach: "reversed()"
summary: "كرّر على قائمة بترتيب عكسي باستخدام حلقة for-each نظيفة."
explanation: "تُرجع الدالة reversed() من SequencedCollection عرضاً عكسياً للقائمة. هذا العرض مدعوم بالقائمة الأصلية دون نسخ. تجعل صيغة حلقة for المحسّنة التكرار العكسي بنفس سهولة التكرار الأمامي."
whyModernWins:
- icon: "📖"
title: "بنية طبيعية"
desc: "حلقة for المحسّنة بدلاً من ListIterator المطوّل."
- icon: "⚡"
title: "لا نسخ"
desc: "reversed() تُرجع عرضاً — لا تكلفة أداء."
- icon: "🧩"
title: "واجهة برمجية موحّدة"
desc: "تعمل على List و Deque و SortedSet بشكل موحّد."
support:
description: "متاح على نطاق واسع منذ JDK 21 LTS (سبتمبر 2023)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/sequenced-collections.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "المجموعات المتسلسلة"
oldApproach: "حساب الفهارس"
modernApproach: "getFirst/getLast"
summary: "الوصول إلى العناصر الأولى والأخيرة والعروض العكسية بدوال API نظيفة."
explanation: "تضيف SequencedCollection الدوالَ getFirst() و getLast() و reversed() و addFirst() و addLast() إلى List و Deque و SortedSet و LinkedHashSet. لا مزيد من حساب size-1 أو التكرار العكسي اليدوي."
whyModernWins:
- icon: "📖"
title: "موثّق ذاتياً"
desc: "getLast() أوضح من get(size()-1)."
- icon: "🔄"
title: "عرض عكسي"
desc: "reversed() تُعطي عرضاً — لا نسخ مطلوب."
- icon: "🧩"
title: "واجهة برمجية موحّدة"
desc: "تعمل بنفس الطريقة على List و Deque و SortedSet."
support:
description: "متاح على نطاق واسع منذ JDK 21 LTS (سبتمبر 2023)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/stream-toarray-typed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "تحويل Stream إلى مصفوفة محدّدة النوع"
oldApproach: "نسخ المصفوفة يدوياً"
modernApproach: "toArray(generator)"
summary: "حوّل Stream إلى مصفوفة محدّدة النوع باستخدام مرجع دالة."
explanation: "تُنشئ الدالة toArray(IntFunction) مصفوفةً محدّدة النوع من Stream. يُخبر المولّد (String[]::new) التدفقَ بنوع المصفوفة المراد إنشاؤها."
whyModernWins:
- icon: "🎯"
title: "آمن من حيث النوع"
desc: "لا تحويل لـ Object[] — نوع المصفوفة صحيح."
- icon: "🔗"
title: "قابل للتسلسل"
desc: "يعمل في نهاية أي خط معالجة Stream."
- icon: "📏"
title: "موجز"
desc: "تعبير واحد يستبدل الحلقة اليدوية."
support:
description: "متاح على نطاق واسع منذ JDK 8 (مارس 2014)"
17 changes: 17 additions & 0 deletions translations/content/ar/collections/unmodifiable-collectors.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "مُجمِّعات غير قابلة للتعديل"
oldApproach: "collectingAndThen"
modernApproach: "stream.toList()"
summary: "جمّع مباشرةً إلى قائمة غير قابلة للتعديل باستخدام stream.toList()."
explanation: "أضاف Java 10 الدوالَ toUnmodifiableList() و toUnmodifiableSet() و toUnmodifiableMap() لاستبدال غلاف collectingAndThen المطوّل. بالنسبة للقوائم تحديداً، توفر stream.toList() في Java 16 بديلاً أبسط — دون استدعاء collect() على الإطلاق. استخدم toUnmodifiableSet() و toUnmodifiableMap() لأنواع المجموعات الأخرى."
whyModernWins:
- icon: "📏"
title: "الأقصر على الإطلاق"
desc: "stream.toList() لا تحتاج استدعاء collect() أو استيراد Collectors."
- icon: "🔒"
title: "ثابتة"
desc: "لا يمكن تعديل النتيجة — لا طفرات عرضية."
- icon: "📖"
title: "مقروءة"
desc: "تُقرأ بشكل طبيعي كخطوة نهائية في أي خط Stream."
support:
description: "متاح على نطاق واسع منذ JDK 16 (مارس 2021)"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "تسلسل CompletableFuture"
oldApproach: "Future.get() المحجوب"
modernApproach: "CompletableFuture"
summary: "سلسل العمليات غير المتزامنة دون حجب باستخدام CompletableFuture."
explanation: "تُتيح CompletableFuture خطوط معالجة غير متزامنة غير محجوبة. سلسل العمليات بـ thenApply و thenCompose و thenAccept. عالج الأخطاء بـ exceptionally(). اجمع عدة مستقبلات بـ allOf/anyOf."
whyModernWins:
- icon: "🔗"
title: "قابل للتسلسل"
desc: "اجمع الخطوات غير المتزامنة في خط معالجة مقروء."
- icon: "🚫"
title: "غير محجوب"
desc: "لا يجلس خيط في انتظار النتائج بلا عمل."
- icon: "🛡️"
title: "معالجة الأخطاء"
desc: "exceptionally() و handle() لاسترداد الأخطاء بشكل نظيف."
support:
description: "متاح على نطاق واسع منذ JDK 8 (مارس 2014)"
17 changes: 17 additions & 0 deletions translations/content/ar/concurrency/concurrent-http-virtual.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "طلبات HTTP متزامنة مع الخيوط الافتراضية"
oldApproach: "مجمع خيوط + URLConnection"
modernApproach: "الخيوط الافتراضية + HttpClient"
summary: "اجلب عناوين URL كثيرة بالتوازي باستخدام الخيوط الافتراضية و HttpClient."
explanation: "تجعل الخيوط الافتراضية إنشاء خيط لكل طلب HTTP أمراً عملياً. مع HttpClient يستبدل ذلك أنماط ردود الاتصال غير المتزامنة المعقدة بكود حجب بسيط يتوسّع بشكل جيد."
whyModernWins:
- icon: "♾️"
title: "خيط لكل طلب"
desc: "لا حاجة لضبط حجم المجمع — خيط افتراضي لكل عنوان URL."
- icon: "📖"
title: "كود بسيط"
desc: "اكتب كوداً حجبياً مباشراً."
- icon: "⚡"
title: "إنتاجية عالية"
desc: "آلاف الطلبات المتزامنة بموارد ضئيلة."
support:
description: "متاح على نطاق واسع منذ JDK 21 LTS (سبتمبر 2023)"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "الإغلاق التلقائي لـ ExecutorService"
oldApproach: "إيقاف تشغيل يدوي"
modernApproach: "try-with-resources"
summary: "استخدم try-with-resources لإيقاف تشغيل المنفّذ تلقائياً."
explanation: "منذ Java 19، تُنفّذ ExecutorService واجهة AutoCloseable. تستدعي الدالة close() الدالةَ shutdown() وتنتظر اكتمال المهام. لا مزيد من أنماط try/finally اليدوية لإيقاف التشغيل."
whyModernWins:
- icon: "🧹"
title: "تنظيف تلقائي"
desc: "يحدث الإيقاف تلقائياً عند الخروج من الكتلة."
- icon: "🛡️"
title: "لا تسريبات"
desc: "يُوقَف المنفّذ دائماً حتى عند حدوث استثناءات."
- icon: "📖"
title: "نمط مألوف"
desc: "نفس try-with-resources المستخدم مع الملفات والاتصالات."
support:
description: "متاح على نطاق واسع منذ JDK 19 (سبتمبر 2022)"
17 changes: 17 additions & 0 deletions translations/content/ar/concurrency/lock-free-lazy-init.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "التهيئة الكسولة بدون أقفال"
oldApproach: "synchronized + volatile"
modernApproach: "StableValue"
summary: "استبدل القفل المزدوج بـ StableValue للحصول على مفاردات كسولة."
explanation: "يُغلّف StableValue نمط التهيئة الكسولة مع أمان صحيح للخيوط. يمكن لـ JVM تحسين مسار القراءة بعد التهيئة مما قد يجعله أسرع من قراءات volatile."
whyModernWins:
- icon: "🧹"
title: "لا كليشيه"
desc: "لا volatile ولا synchronized ولا فحص مزدوج للقيمة الفارغة."
- icon: "⚡"
title: "قراءات أسرع"
desc: "يمكن لـ JVM طي القيمة بعد التهيئة."
- icon: "✅"
title: "صحيح بصورة مُبرهنة"
desc: "لا أخطاء ترتيب خفية — JVM يتولى الأمر."
support:
description: "معاينة في JDK 25 (JEP 502، StableValue). يتطلب --enable-preview."
17 changes: 17 additions & 0 deletions translations/content/ar/concurrency/process-api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "واجهة برمجة العمليات الحديثة"
oldApproach: "Runtime.exec()"
modernApproach: "ProcessHandle"
summary: "افحص عمليات نظام التشغيل وأدِرها باستخدام ProcessHandle."
explanation: "يوفر ProcessHandle معرّفات العملية PID ومعلومات العملية (الأمر والوسائط ووقت البدء واستخدام المعالج) وعلاقات الوالد/الطفل وتدمير العمليات. لا مزيد من الأجزاء الداخلية غير الموثّقة لـ Process."
whyModernWins:
- icon: "🔍"
title: "معلومات كاملة"
desc: "الوصول إلى PID والأمر والوسائط ووقت البدء واستخدام المعالج."
- icon: "🌳"
title: "شجرة العمليات"
desc: "التنقل بين الوالد والأبناء والأحفاد."
- icon: "📊"
title: "المراقبة"
desc: "onExit() يُرجع CompletableFuture للمراقبة غير المتزامنة."
support:
description: "متاح على نطاق واسع منذ JDK 9 (سبتمبر 2017)"
17 changes: 17 additions & 0 deletions translations/content/ar/concurrency/scoped-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "القيم ذات النطاق"
oldApproach: "ThreadLocal"
modernApproach: "ScopedValue"
summary: "شارك البيانات عبر مكدسات الاستدعاء بأمان دون مخاطر ThreadLocal."
explanation: "يوفر ScopedValue سياقاً ثابتاً وقابلاً للوراثة ومحدود النطاق. بخلاف ThreadLocal، تُنظَّف القيم ذات النطاق تلقائياً وتعمل مع الخيوط الافتراضية ولا يمكن للمستدعين تعديلها."
whyModernWins:
- icon: "🔒"
title: "ثابتة"
desc: "يمكن للمستدعين القراءة لكن لا يستطيعون تعديل القيمة ذات النطاق."
- icon: "🧹"
title: "تنظيف تلقائي"
desc: "لا حاجة لـ remove() يدوي — القيمة محددة النطاق للكتلة."
- icon: "⚡"
title: "آمنة مع الخيوط الافتراضية"
desc: "تعمل بكفاءة مع ملايين الخيوط الافتراضية."
support:
description: "أُنهيت في JDK 25 LTS (JEP 506، سبتمبر 2025)."
17 changes: 17 additions & 0 deletions translations/content/ar/concurrency/stable-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: "القيم الثابتة"
oldApproach: "القفل المزدوج"
modernApproach: "StableValue"
summary: "تهيئة كسولة آمنة للخيوط دون volatile أو synchronized."
explanation: "يوفر StableValue قيمةً مُهيَّأةً كسولاً وثابتةً مع أمان مدمج للخيوط. لا قفل مزدوج ولا حقول volatile ولا كتل synchronized. يمكن لـ JVM حتى تحسين مسار القراءة بعد التهيئة."
whyModernWins:
- icon: "🧹"
title: "صفر كليشيه"
desc: "لا volatile ولا synchronized ولا فحوصات null."
- icon: "⚡"
title: "مُحسَّن من JVM"
desc: "يمكن لـ JVM طي القيمة بعد التهيئة."
- icon: "🛡️"
title: "مضمون مرة واحدة"
desc: "المورّد يعمل مرة واحدة بالضبط حتى في حال التنافس."
support:
description: "معاينة في JDK 25 (JEP 502). يتطلب --enable-preview."
Loading