Hôm nay chúng ta sẽ nói về cách làm việc với bảng liệt kê chuỗi và cụ thể hơn là với
enum
các lớp tổ chức tương tác với các hằng chuỗi.
Sử dụng kiểu liệt kê chuỗi
Trong quá trình phát triển ứng dụng, bạn cần định kỳ thao tác trên một tập hợp các giá trị chuỗi cố định. Nó có thể là bất cứ điều gì. Ví dụ: danh sách mã màu được ứng dụng hỗ trợ hoặc danh sách các thiết bị mà ứng dụng của chúng tôi có thể tương tác, các mùa, v.v. Tất cả điều này là một tập hợp các hằng chuỗi được xác định trước có cấu trúc chung, cần thiết để thiết lập tương tác chương trình ở cấp mã Java. Khi bạn cần tương tác với một tập hợp các hằng số chuỗi (và các hằng số khác) được xác định trước, giải pháp tốt nhất là viếtenum
lớp của riêng bạn. Dưới đây chúng ta sẽ xem xét các ví dụ về chuyển đổi enum
sang string
.
Tạo chuỗi liệt kê
Hãy tạoenum
một lớp lưu trữ danh sách các môi trường khác nhau để triển khai ứng dụng, cũng như URL của từng môi trường:
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;
}
}
Trong lớp này chúng ta đã xác định 4 môi trường:
PROD
- giải phóngTEST
- để kiểm tra thủ côngAUTO_TEST
— môi trường cho các bài kiểm tra tự độngDEV
- cục bộ để phát triển và gỡ lỗi
- Mỗi URL là một hằng số chuỗi trong bảng liệt kê của chúng tôi: chúng được xác định trong dấu ngoặc đơn bên cạnh mỗi hằng
enum
số. - Phải có một hàm tạo lấy đối số cùng loại với mỗi hằng
enum
số. - Phạm vi của hàm tạo
private
làpackage private
. - Cần phải định nghĩa một biến - một trường lớp sẽ lưu trữ các hằng chuỗi mà chúng ta đã định nghĩa. Bạn phải tạo một phương thức getter cho trường này để sử dụng các giá trị của hằng chuỗi bên ngoài.
Lặp lại các phép liệt kê chuỗi
Ở giai đoạn này, chúng ta đã có thể lặp lại tất cảenum
các giá trị có sẵn cũng như nhận các hằng chuỗi liên kết với chúng. Để lấy tất cả các giá trị của bất kỳ enum
lớp nào, bạn cần sử dụng phương thức values()
:
public class Main {
public static void main(String[] args) {
for (Environment env : Environment.values()) {
System.out.println(env + " : " + env.getUrl());
}
}
}
Phần kết luận:
PROD : https://release.application.com/
TEST : https://test.application.com/
AUTO_TEST : https://autotest.application.com/
DEV : http://localhost:8080
Như có thể thấy từ ví dụ, để in tên của enum
hằng số, chúng tôi đã chuyển nó cho phương thức System.out.println
và để in url được liên kết với hằng số này, chúng tôi đã sử dụng getter mà chúng tôi đã xác định.
Lấy một chuỗi hằng từ enum
Để lấy giá trị của bất kỳ hằng chuỗi nào, chúng ta cũng có thể gọi một getter trên bất kỳenum
hằng số nào:
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);
}
}
Phần kết luận:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
Lấy hằng số enum theo tên
Đôi khi cần lấyenum
một hằng số theo tên chuỗi của nó. Việc này được thực hiện bằng phương thức valueOf(String)
, phương thức này trả về một hằng số theo tên của nó:
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());
}
}
Phần kết luận:
Production url is: https://release.application.com/
Development url is: http://localhost:8080
Nhưng cần thận trọng ở đây. Nếu phương thức không tìm thấy enum
hằng số có tên được chỉ định, một ngoại lệ sẽ được đưa ra java.lang.IllegalArgumentException
.
Chuyển đổi chuỗi thành Enum
Đôi khi lại nảy sinh nhu cầu ngược lại. Biết giá trịenum
, lấy enum
chính hằng số đó. Những thứ kia. trong ví dụ của chúng tôi, biết một địa chỉ nhất định, bạn cần lấy hằng Environment
số tương ứng. Có một số lựa chọn để làm điều này. Và tất cả chúng đều yêu cầu sự cải thiện trong enum
chính lớp học đó. Tùy chọn 1. Liệt kê bên trong lớp. Bạn cần tạo một phương thức sẽ chấp nhận một chuỗi và so sánh nó với tất cả các giá trị enum
của lớp. Nếu khớp, phương thức sẽ trả về bảng liệt kê mong muốn. Trong ví dụ của chúng ta, chúng ta cần Environment
tạo phương thức sau bên trong lớp:
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 + "]");
}
Sau đó chúng ta có thể lấy enum
từ chuỗi như thế này:
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);
}
}
Phần kết luận:
Environment name for url=[http://localhost:8080] is: DEV
Cách tiếp cận này có nhược điểm của nó. Mỗi lần, để lấy enum
một hằng số, bạn sẽ phải lặp qua tất cả các giá trị và thực hiện một số phép so sánh nhất định. Hình phạt hiệu suất trong trường hợp này sẽ được xác định bởi số lượng hằng số và số lượng hoạt động tương tự. Phương pháp thứ hai để giải quyết vấn đề này không có vấn đề này. Mã lớp đầy đủ 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 + "]");
}
}
Tùy chọn 2: Cách sử dụng HashMap
Trong trường hợp này, chúng tôi tạo một bản đồ bên trong enum của mình và điền nó một lần vào thời gian biên dịch, sau đó lấy các giá trị từ nó:
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);
}
}
Về mặt sử dụng, cả hai tùy chọn đều giống nhau:
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);
}
}
Phần kết luận:
Environment name for url=[http://localhost:8080] is: DEV
Nhưng phương pháp này cũng có nhược điểm. Thứ nhất, có nhiều mã hơn. Và thứ hai, HashMap
tất cả enum
các giá trị sẽ được lưu trữ vĩnh viễn trong bộ nhớ ứng dụng. Như bạn có thể thấy, mọi thứ đều có ưu và nhược điểm. Nhưng vì enum
các lớp thường lưu trữ không nhiều giá trị nên hầu như không thể nhận ra những nhược điểm. Có một lưu ý: nếu một thao tác như vậy (nhận giá trị Java Enum theo Chuỗi) được thực hiện thường xuyên thì tốt hơn nên sử dụng tùy chọn thứ hai. Bạn có thể tìm hiểu thêm về chủ đề này và Enum
các lớp nói chung trong khóa học JavaRush. Học sinh đã học JavaRush Enum
ở bài giảng đầu tiên của cấp độ thứ năm .
GO TO FULL VERSION