0Pricing
Java Academy · درس

NumberFormat وprintf

نسّق الأعداد للعرض باستخدام NumberFormat وDecimalFormat وأنماط printf

NumberFormat وprintf درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

NumberFormat وprintf

توفر Java واجهات برمجة غنية لتنسيق الأرقام: إذ يُستخدم NumberFormat لتنسيق العملات والنسب المئوية وفق الإعدادات المحلية، ويُستخدم DecimalFormat للأنماط المخصصة، بينما يُستخدم printf/String.format للتنسيق بأسلوب C.

أساسيات String.format

يستخدم String.format() محددات التنسيق لإنشاء السلاسل النصية. ومن المحددات الشائعة: %d (عدد صحيح)، و%f (عدد عشري)، و%s (سلسلة نصية)، و%n (سطر جديد).

String name = "Alice";
int score = 95;
double avg = 87.567;

String msg = String.format(
    "Player: %s | Score: %d | Average: %.2f", name, score, avg);
System.out.println(msg);
// Player: Alice | Score: 95 | Average: 87.57

// printf is equivalent — formats directly to output
System.out.printf("%-10s %5d %8.2f%n", name, score, avg);
// Alice          95    87.57

العرض والحشو والمحاذاة

تدعم محددات التنسيق خيارات العرض والمحاذاة: %10d (محاذاة إلى اليمين ضمن 10 محارف)، و%-10d (محاذاة إلى اليسار)، و%010d (الحشو بالأصفار).

// Table layout with padding
System.out.printf("%-20s %10s %10s%n", "Product", "Qty", "Price");
System.out.printf("%-20s %10d %10.2f%n", "Java Book", 3, 49.99);
System.out.printf("%-20s %10d %10.2f%n", "USB Hub", 1, 24.95);
System.out.printf("%-20s %10d %10.2f%n", "Mechanical Keyboard", 2, 129.00);

// Zero-padding for order IDs
int orderId = 42;
System.out.printf("Order: ORD-%08d%n", orderId); // Order: ORD-00000042

NumberFormat للعملات

ينسّق NumberFormat.getCurrencyInstance(Locale) الأرقام كسلاسل عملات، مع الرمز والفواصل وعدد المنازل العشرية الصحيح وفق إعدادات محلية محددة.

import java.text.*;
import java.util.*;

NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat eur = NumberFormat.getCurrencyInstance(Locale.GERMANY);
NumberFormat gbp = NumberFormat.getCurrencyInstance(Locale.UK);

double amount = 1234567.89;
System.out.println(usd.format(amount)); // $1,234,567.89
System.out.println(eur.format(amount)); // 1.234.567,89 EUR
System.out.println(gbp.format(amount)); // GBP1,234,567.89

NumberFormat للنسب المئوية

ينسّق NumberFormat.getPercentInstance() عددًا عشريًا كسلسلة تمثل نسبة مئوية. مرّر قيمة بين 0 و1.

import java.text.*;
import java.util.*;

NumberFormat pct = NumberFormat.getPercentInstance(Locale.US);
pct.setMaximumFractionDigits(1);

System.out.println(pct.format(0.75));     // 75%
System.out.println(pct.format(0.1234));   // 12.3%
System.out.println(pct.format(1.0));      // 100%

// Conversion rate in e-commerce
double convRate = 3_456.0 / 42_000.0;
System.out.println("Conversion: " + pct.format(convRate)); // 8.2%

DecimalFormat باستخدام أنماط مخصصة

يستخدم DecimalFormat سلسلة نمط، حيث يعني # رقمًا اختياريًا، ويعني 0 رقمًا إلزاميًا.

import java.text.*;

DecimalFormat df1 = new DecimalFormat("#,###.00");
System.out.println(df1.format(1234567.5));  // 1,234,567.50

DecimalFormat df2 = new DecimalFormat("000.0");
System.out.println(df2.format(7.5));  // 007.5

DecimalFormat df3 = new DecimalFormat("0.00E0");
System.out.println(df3.format(0.000123)); // 1.23E-4

// Scientific notation for large values
DecimalFormat sci = new DecimalFormat("0.000E0");
System.out.println(sci.format(123456789)); // 1.235E8

تحليل الأرقام من السلاسل النصية

يمكن لـ NumberFormat أيضًا تحليل السلاسل المنسقة وفق الإعدادات المحلية وإعادتها إلى أرقام. وهذا ضروري لقراءة إدخالات المستخدمين وفق إعدادات محلية مختلفة.

import java.text.*;
import java.util.*;

NumberFormat nf = NumberFormat.getInstance(Locale.GERMANY);
try {
    // German uses comma as decimal separator
    Number parsed = nf.parse("1.234,56");
    System.out.println(parsed.doubleValue()); // 1234.56

    // Parse US currency string
    NumberFormat usd = NumberFormat.getCurrencyInstance(Locale.US);
    Number amount = usd.parse("$1,234.56");
    System.out.println(amount.doubleValue()); // 1234.56
} catch (ParseException e) {
    System.out.println("Parse error: " + e.getMessage());
}

السلاسل المنسقة (Java 15 فأحدث)

أضافت Java 15 فأحدث String.formatted() بوصفها أسلوبًا بديلاً تابعًا للكائن عن String.format()، وهي مفيدة في سلاسل استدعاءات الأساليب وخطوط معالجة التدفقات.

record Product(String name, double price, int stock) {}

var products = List.of(
    new Product("Laptop", 999.0, 5),
    new Product("Mouse",  29.99, 42),
    new Product("Monitor", 349.0, 8)
);

products.stream()
    .map(p -> "%-15s $%8.2f  [stock: %d]"
        .formatted(p.name(), p.price(), p.stock()))
    .forEach(System.out::println);
// Laptop          $  999.00  [stock: 5]
// Mouse           $   29.99  [stock: 42]
// Monitor         $  349.00  [stock: 8]

تجميع الأرقام والإعدادات المحلية

يختلف تجميع الأرقام، أي فاصل الآلاف، باختلاف الإعدادات المحلية. استخدم NumberFormat دائمًا في المخرجات الموجهة للمستخدم بدلًا من كتابة الفواصل يدويًا.

import java.text.*;
import java.util.*;

long users = 1_234_567;

for (Locale locale : new Locale[]{Locale.US, Locale.FRANCE, Locale.GERMANY}) {
    NumberFormat nf = NumberFormat.getIntegerInstance(locale);
    System.out.printf("%-10s: %s%n", locale, nf.format(users));
}
// en_US     : 1,234,567
// fr_FR     : 1 234 567
// de_DE     : 1.234.567

مثال على إنشاء فاتورة

تجميع المفاهيم: إنشاء نسخة مطبوعة منسقة لفاتورة، مع العملة والنسبة المئوية ومحاذاة الجدول بالشكل الصحيح.

import java.text.*;
import java.util.*;

NumberFormat curr = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat pct  = NumberFormat.getPercentInstance();
pct.setMaximumFractionDigits(0);

double subtotal = 1259.97;
double discount = 0.10;
double discountAmt = subtotal * discount;
double taxRate = 0.08;
double taxAmt = (subtotal - discountAmt) * taxRate;
double total = subtotal - discountAmt + taxAmt;

System.out.println("=== INVOICE ===");
System.out.printf("%-20s %15s%n", "Subtotal",       curr.format(subtotal));
System.out.printf("%-20s %15s%n", "Discount (" + pct.format(discount) + ")",
    "-" + curr.format(discountAmt));
System.out.printf("%-20s %15s%n", "Tax (" + pct.format(taxRate) + ")",
    curr.format(taxAmt));
System.out.printf("%-20s %15s%n", "TOTAL", curr.format(total));

أخطاء شائعة

انتبه إلى أخطاء التنسيق الشائعة التالية:

  • يؤدي استخدام String.format مع محدد نوع غير صحيح، مثل استخدام %d مع double، إلى طرح IllegalFormatConversionException
  • تنتج أدوات التنسيق الخاصة بالإعدادات المحلية مخرجات مختلفة على الأجهزة المختلفة
  • كائنات NumberFormat ليست آمنة للاستخدام مع الخيوط، لذا أنشئ كائنًا لكل خيط أو استخدم ThreadLocal
// Wrong specifier
try {
    String.format("%d", 3.14); // IllegalFormatConversionException
} catch (java.util.IllegalFormatConversionException e) {
    System.out.println("Wrong format specifier!");
}

// Thread-safe pattern using ThreadLocal
ThreadLocal<NumberFormat> localFmt = ThreadLocal
    .withInitial(() -> NumberFormat.getCurrencyInstance(Locale.US));
// each thread gets its own NumberFormat instance

تحقق سريع

ما الناتج الذي تنتجه String.format("%08.2f", 3.5)؟

مراجعة: NumberFormat وprintf

أهم النقاط:

  • يستخدم String.format / printf محددات التنسيق: %d و%f و%s و%.2f
  • خيارات العرض والمحاذاة: %10d (يمين)، و%-10d (يسار)، و%010d (حشو بالأصفار)
  • استخدم NumberFormat.getCurrencyInstance() لعرض العملات وفق الإعدادات المحلية
  • استخدم NumberFormat.getPercentInstance() لإخراج النسب المئوية
  • يستخدم DecimalFormat نمطي # (اختياري) و0 (إلزامي) للأرقام
  • يمكن لـ NumberFormat أيضًا تحليل السلاسل المنسقة وفق الإعدادات المحلية وإعادتها إلى أرقام

الأسئلة الشائعة

هل درس «NumberFormat وprintf» مجاني؟

نعم — نص درس «NumberFormat وprintf» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «NumberFormat وprintf»؟

نسّق الأعداد للعرض باستخدام NumberFormat وDecimalFormat وأنماط printf تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «NumberFormat وprintf»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. أساسيات الفئة Math
  2. حساب الأعداد الصحيحة وتجاوز السعة
  3. استخدام BigDecimal في الحسابات المالية
  4. NumberFormat وprintf
← العودة إلى Java Academy