سنتحدث اليوم عن العمل مع تعدادات السلسلة، وبشكل أكثر تحديدًا، مع
enum
الفئات التي تنظم التفاعل مع ثوابت السلسلة.
استخدام تعداد السلسلة
أثناء تطوير التطبيق، تحتاج بشكل دوري إلى العمل على مجموعة ثابتة من قيم السلسلة. يمكن أن يكون أي شيء. على سبيل المثال، قائمة رموز الألوان التي يدعمها التطبيق، أو قائمة الأجهزة التي يمكن أن يتفاعل معها تطبيقنا، والمواسم، وما إلى ذلك. كل هذا عبارة عن مجموعة محددة مسبقًا من ثوابت السلسلة ذات بنية مشتركة، والتي من الضروري من خلالها إنشاء تفاعل البرنامج على مستوى كود Java. عندما تحتاج إلى التفاعل مع مجموعة محددة مسبقًا من ثوابت السلسلة (وغيرها)، فإن الحل الأفضل هو كتابة فصلك الخاصenum
. أدناه سننظر في أمثلة التحويل enum
إلى string
.
إنشاء تعدادات السلسلة
لنقم بإنشاءenum
فئة تخزن قائمة بالبيئات المختلفة لنشر التطبيق، بالإضافة إلى عنوان URL لكل بيئة:
public enum Environment {
PROD("https://release.application.com/"),
TEST("https://test.application.com/"),
AUTO_TEST("https://autotest.application.com/"),
DEV("http://localhost:8080");
private final String url;
Environment(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
}
في هذا الفصل قمنا بتعريف 4 بيئات:
PROD
- يطلقTEST
- للاختبار اليدويAUTO_TEST
— بيئة للاختبارات التلقائيةDEV
- محلي للتطوير والتصحيح
- كل عنوان URL عبارة عن سلسلة ثابتة في تعدادنا: يتم تعريفها بين قوسين بجوار كل
enum
ثابت. - يجب أن يكون هناك مُنشئ يأخذ وسيطة من نفس نوع كل
enum
ثابت. - نطاق المنشئ
private
إماpackage private
. - من الضروري تحديد متغير - حقل فئة يقوم بتخزين ثوابت السلسلة التي حددناها. يجب عليك إنشاء طريقة getter لهذا الحقل حتى تتمكن من استخدام قيم ثوابت السلسلة خارجيًا.
التكرار على تعداد السلسلة
في هذه المرحلة، يمكننا بالفعل التكرار على جميعenum
القيم المتاحة، وكذلك الحصول على ثوابت السلسلة المرتبطة بها. للحصول على جميع قيم أي enum
فئة، عليك استخدام الطريقة values()
:
public class Main {
public static void main(String[] args) {
for (Environment env : Environment.values()) {
System.out.println(env + " : " + env.getUrl());
}
}
}
خاتمة:
PROD : https://release.application.com/
TEST : https://test.application.com/
AUTO_TEST : https://autotest.application.com/
DEV : http://localhost:8080
كما يتبين من المثال، لطباعة اسم enum
الثابت، قمنا بتمريره إلى الطريقة System.out.println
، ولطباعة عنوان URL المرتبط بهذا الثابت، استخدمنا getter الذي حددناه.
الحصول على ثابت سلسلة من التعداد
للحصول على قيمة أي ثابت سلسلة، يمكننا أيضًا استدعاء getter على أيenum
ثابت:
public class Main {
public static void main(String[] args) {
String prodUrl = Environment.PROD.getUrl();
String devUrl = Environment.DEV.getUrl();
System.out.println("Production url is: " + prodUrl);
System.out.println("Development url is: " + devUrl);
}
}
خاتمة:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
الحصول على ثابت التعداد بالاسم
في بعض الأحيان يكون من الضروري الحصول علىenum
ثابت باسم السلسلة الخاص به. يتم ذلك باستخدام الطريقة valueOf(String)
التي تُرجع ثابتًا باسمه:
public class Main {
public static void main(String[] args) {
Environment prod = Environment.valueOf("PROD");
Environment dev = Environment.valueOf("DEV");
System.out.println("Production url is: " + prod.getUrl());
System.out.println("Development url is: " + dev.getUrl());
}
}
خاتمة:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
لكن الحذر مطلوب هنا. إذا لم تجد الطريقة enum
ثابتًا بالاسم المحدد، فسيتم طرح استثناء java.lang.IllegalArgumentException
.
تحويل السلسلة إلى التعداد
في بعض الأحيان تنشأ الحاجة المعاكسة. بمعرفة القيمةenum
، احصل على enum
الثابت نفسه. أولئك. في مثالنا، عند معرفة عنوان معين، تحتاج إلى الحصول على Environment
الثابت المقابل. هناك عدة خيارات للقيام بذلك. وكلها تتطلب تحسينًا في enum
الفصل نفسه. الخيار 1. التعداد داخل الفصل. تحتاج إلى إنشاء طريقة تقبل سلسلة ومقارنتها بجميع قيم enum
الفئة. إذا كان هناك تطابق، فسوف تقوم الطريقة بإرجاع التعداد المطلوب. على سبيل المثال، نحتاج إلى Environment
إنشاء الطريقة التالية داخل الفصل:
public static Environment getEnvByUrl(String url) {
for (Environment env : values()) {
// либо equalsIgnoreCase, на ваше усмотрение
if (env.getUrl().equals(url)) {
return env;
}
}
// Либо просто вернуть null
throw new IllegalArgumentException("No enum found with url: [" + url + "]");
}
ثم يمكننا أن نحصل enum
من السلسلة مثل هذا:
public class Main {
public static void main(String[] args) {
String url = "http://localhost:8080";
Environment env = Environment.getEnvByUrl(url);
System.out.println("Environment name for url=[" + url + "] is: " + env);
}
}
خاتمة:
Environment name for url=[http://localhost:8080] is: DEV
هذا النهج له سلبياته. في كل مرة، للحصول على enum
ثابت، سيتعين عليك تكرار جميع القيم وإجراء عدد معين من المقارنات. سيتم تحديد عقوبة الأداء في هذه الحالة بعدد الثوابت وعدد العمليات المشابهة. الطريقة الثانية لحل هذه المشكلة لا تحتوي على هذه المشكلة. رمز الفصل الكامل Enum
:
public enum Environment {
PROD("https://release.application.com/"),
TEST("https://test.application.com/"),
AUTO_TEST("https://autotest.application.com/"),
DEV("http://localhost:8080");
private final String url;
Environment(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public static Environment getEnvByUrl(String url) {
for (Environment env : values()) {
if (env.getUrl().equals(url)) {
return env;
}
}
throw new IllegalArgumentException("No enum found with url: [" + url + "]");
}
}
الخيار 2: الاستخدام HashMap
في هذه الحالة، نقوم بإنشاء خريطة داخل التعداد الخاص بنا ونملأها مرة واحدة في وقت الترجمة، ثم نأخذ القيم منها:
public enum Environment {
PROD("https://release.application.com/"),
TEST("https://test.application.com/"),
AUTO_TEST("https://autotest.application.com/"),
DEV("http://localhost:8080");
private final String url;
Environment(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
// Создаем static final карту
private static final Map<String, Environment> LOOKUP_MAP = new HashMap<>();
// Заполняем её всеми значениями
static {
for (Environment env : values()) {
LOOKUP_MAP.put(env.getUrl(), env);
}
}
// Возвращаем Environment по строковому url
public static Environment getEnvByUrl(String url) {
return LOOKUP_MAP.get(url);
}
}
من حيث الاستخدام، كلا الخيارين متطابقان:
public class Main {
public static void main(String[] args) {
String url = "http://localhost:8080";
Environment env = Environment.getEnvByUrl(url);
System.out.println("Environment name for url=[" + url + "] is: " + env);
}
}
خاتمة:
Environment name for url=[http://localhost:8080] is: DEV
لكن هذه الطريقة لها أيضًا عيوب. أولا، هناك الكثير من التعليمات البرمجية. وثانيا سيتم تخزين HashMap
كافة القيم في ذاكرة التطبيق بشكل دائم. enum
كما ترون، كل شيء له إيجابيات وسلبيات. ولكن بالنظر إلى أن enum
الفئات عادة لا تخزن الكثير من القيم، فإن العيوب ستكون غير مرئية تقريبًا. هناك تحذير: إذا تم تنفيذ مثل هذه العملية (الحصول على Java Enum حسب قيمة السلسلة) بشكل متكرر، فمن الأفضل استخدام الخيار الثاني. يمكنك معرفة المزيد حول هذا الموضوع والفصول Enum
الدراسية بشكل عام في دورة JavaRush. يتعلم الطلاب JavaRush Enum
بالفعل في المحاضرة الأولى من المستوى الخامس .
GO TO FULL VERSION