امروز ما در مورد کار با شمارش رشته ها و به طور خاص تر، با
enum
کلاس هایی صحبت خواهیم کرد که تعامل با ثابت های رشته را سازماندهی می کنند.
با استفاده از شمارش رشته ها
در طول توسعه برنامه، شما باید به صورت دوره ای روی مجموعه ای ثابت از مقادیر رشته کار کنید. این می تواند هر چیزی باشد. به عنوان مثال، لیستی از کدهای رنگی که توسط برنامه پشتیبانی می شود، یا لیستی از دستگاه هایی که برنامه ما می تواند با آنها تعامل داشته باشد، فصل ها و غیره. همه اینها یک مجموعه از پیش تعریف شده از ثابت های رشته ای با ساختار مشترک است که لازم است تعامل برنامه در سطح کد جاوا برقرار شود. هنگامی که نیاز به تعامل با مجموعه ای از ثابت های رشته ای (و دیگر) از پیش تعریف شده دارید، بهترین راه حل این است که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
. - لازم است یک متغیر تعریف کنیم - یک فیلد کلاس که ثابت های رشته ای را که ما تعریف کرده ایم ذخیره می کند. شما باید برای این فیلد یک متد دریافت کننده ایجاد کنید تا از مقادیر ثابت رشته ها به صورت خارجی استفاده کنید.
تکرار بیش از شمارش رشته
در این مرحله، میتوانیم روی تمام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 مرتبط با این ثابت، از دریافت کننده ای که تعریف کردیم استفاده کردیم.
گرفتن یک ثابت رشته از enum
برای بدست آوردن مقدار هر ثابت رشته ای، می توانیم یک گیرنده روی هر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 با نام
گاهی اوقات لازم است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
، 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
در این مورد، یک نقشه در داخل 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;
}
// Создаем 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 توسط String) مکرر انجام می شود، بهتر است از گزینه دوم استفاده کنید. Enum
در دوره JavaRush می توانید با این مبحث و به طور کلی کلاس ها بیشتر آشنا شوید. دانش آموزان JavaRush را Enum
قبلاً در اولین سخنرانی سطح پنجم یاد می گیرند .
GO TO FULL VERSION