JavaRush /Blog Java /Random-VI /Nghỉ giải lao #221. Ba cách để tìm một phần tử trong mảng...

Nghỉ giải lao #221. Ba cách để tìm một phần tử trong mảng Java. Java Thread Local là gì và cách sử dụng nó

Xuất bản trong nhóm

Ba cách để tìm một phần tử trong mảng Java

Nguồn: Asyncq Bài đăng này sẽ giúp bạn hiểu rõ hơn về các cách khác nhau để tìm kiếm một phần tử trong một mảng trong Java. Nghỉ giải lao #221.  Ba cách để tìm một phần tử trong mảng Java.  Java Thread Local là gì và cách sử dụng - 1Tìm một phần tử cụ thể trong một tập hợp các giá trị là một thao tác rất phổ biến và được sử dụng thường xuyên trong quá trình phát triển phần mềm. Có nhiều cách tiếp cận khác nhau để giải quyết vấn đề này, từ đơn giản đến tối ưu hóa. Hãy nhìn vào chúng.

Dữ liệu đầu vào

Mảng đầu vào chứa dữ liệu id nguyên thủy và chúng ta cần biết liệu nó có chứa id->3 hay không.
int[] ids = { 1,2,13,14,15,3,10,11,12,4,5,6,7,8,9 };
int inputId = 3;

Cách 1 (đơn giản)

  1. Chúng ta truy cập tất cả các phần tử của mảng, mỗi lần một phần tử.
  2. Ngoài ra, chúng tôi theo dõi trạng thái của phần tử đích nếu nó tồn tại trong mảng.
  3. Ngay khi tìm thấy phần tử này, chúng tôi chuyển trạng thái từ false sang true .
  4. Sau khi vòng lặp hoàn thành, chúng ta trả về cờ trạng thái.
boolean valExist = false;
for (int id : ids) {
   if (inputId == id) {
             valExist = true;
   }
}
return valExist;
Giải pháp này hoạt động, nhưng nó không hiệu quả lắm. Nếu bạn nhìn vào điều kiện if , bạn sẽ nhận ra rằng chúng tôi đang kiểm tra điều kiện này cho tất cả các phần tử. Giả sử phần tử chúng ta đang tìm kiếm là phần tử đầu tiên, nhưng vòng lặp của chúng ta sẽ vẫn tiếp tục chạy cho tất cả các phần tử. Ở đây sẽ khôn ngoan hơn nếu thoát khỏi vòng lặp ngay khi chúng ta tìm thấy phần tử. Bằng cách này, chúng ta sẽ tiết kiệm được các phép tính khi phần tử chúng ta đang tìm kiếm không ở vị trí cuối cùng.
boolean valExist = false;
for (int id : ids) {
    if (inputId == id) {
                valExist = true;
                break;
     }
}
return valExist;
Bạn có thể làm cho mã của mình ngắn gọn hơn nữa bằng cách sử dụng return . Chúng ta có thể trả về true ngay khi nhìn thấy phần tử mà chúng ta đang tìm kiếm, nếu không chúng ta sẽ trả về false ngay khi vòng lặp hoàn thành. Và chúng ta không cần tạo và duy trì biến trạng thái.
for (int id : ids) {
      if (inputId == id) {
                return true;
       }
  }
  return false;

Phương pháp 2

  1. Chúng ta có thể sử dụng ArrayList chứa một phương thức theo mặc định tìm kiếm phần tử đích trong danh sách.
  2. Vì phương thức này được cung cấp bởi List , nên chúng ta cần chuyển đổi mảng nguyên thủy thành danh sách.
  3. Chúng ta có thể sử dụng một chuỗi lambda duy nhất để chuyển đổi kiểu nguyên thủy thành kiểu đối tượng và tạo danh sách từ đó.
    return Arrays.asList(Arrays.stream(ids).boxed().toArray())
                  .contains(inputId);
  4. Chúng tôi có thể sử dụng API luồng Java 8 để làm cho mã của chúng tôi hoạt động tốt hơn và ngắn hơn nhiều.
  5. Để hiểu cách API luồng hoạt động với luồng, chúng ta cần chuyển đổi mảng đầu vào thành luồng.
  6. Arrays.stream lấy mảng đầu vào và chuyển đổi nó thành luồng.
  7. Bây giờ chúng ta có các luồng, chúng ta có thể sử dụng nhiều phương thức hữu ích, một trong số đó là AnyMatch . Nó trả về phần tử khớp với vị ngữ (id == inputId) .
  8. Tất cả điều này làm cho mã của chúng tôi ngắn hơn và dễ đọc hơn nhiều.
    return Arrays.stream(ids)
              .anyMatch(id -> id == inputId);

Cách 3 (tối ưu)

Có, mã hiển thị ở trên hoạt động và dễ đọc nhưng chúng ta vẫn cần truy cập và so sánh từng phần tử trong luồng.
  1. Nếu bộ nhớ không phải là vấn đề và chúng ta muốn tối ưu hóa các phép tính thì một trong những điều chúng ta có thể làm ở đây là tạo một tập hợp từ mảng đầu vào.
  2. Một lần nữa chúng ta có thể sử dụng mã kiểu chức năng để chuyển đổi mảng nguyên thủy thành Set .
  3. Bây giờ chúng ta có Set , chúng ta có thể tìm kiếm một phần tử trong một khoảng thời gian không đổi.
S
et<Integer> idsSet = Arrays.stream(ids).boxed().collect(Collectors.toSet());
return idsSet.contains(inputId);

Thưởng

Việc tìm kiếm một phần tử có thể coi là một thao tác thông thường nhưng phổ biến hơn là tìm kiếm nhiều phần tử trong một mảng. Trong trường hợp này, nếu không sử dụng Set , chúng ta sẽ có hai vòng lặp và độ phức tạp về thời gian sẽ tăng lên để nhân độ dài của hai bộ sưu tập. Dưới đây là một ví dụ trong đó chúng tôi chuyển đổi một trong các mảng thành một tập hợp, sau đó lặp lại mảng khác và thực hiện tìm kiếm trong thao tác tập hợp. Bằng cách này, chúng tôi tăng bộ nhớ và đồng thời tiết kiệm chi phí tính toán.
int[] targetIds = { 1, 3, 6, 88, 999, 34, 44, 55};
int[] ids = { 1,2,13,14,15,3,10,11,12,4,5,6,7,8,9 };


Set<Integer> idsSet = Arrays.stream(ids).boxed().collect(Collectors.toSet());
return Arrays.stream(targetIds)
            .boxed()
            .filter(id -> !idsSet.contains(id))
            .mapToInt(a -> a)
            .toArray();

Java Thread Local là gì và cách sử dụng nó

Nguồn: Medium Trong bài viết này, chúng ta sẽ xem xét Java Thread Local và cách sử dụng nó một cách hiệu quả trong các ứng dụng Java của bạn. Nghỉ giải lao #221.  Ba cách để tìm một phần tử trong mảng Java.  Java Thread Local là gì và cách sử dụng - 2Java Thread Local là một tính năng mạnh mẽ cho phép các nhà phát triển chỉ tạo các biến cho một luồng cụ thể. Điều này có nghĩa là mỗi luồng có thể có bản sao của một biến riêng và những thay đổi được thực hiện đối với một biến trong một luồng sẽ không ảnh hưởng đến giá trị của nó trong một luồng khác.

Chủ đề địa phương là gì

Thread Local là một lớp trong API Java cho phép bạn tạo các biến cục bộ cho một luồng cụ thể. Nghĩa là, mỗi luồng có bản sao biến riêng và những thay đổi được thực hiện đối với một biến trong một luồng không ảnh hưởng đến giá trị của nó trong luồng khác. Điều này làm cho Thread Local trở thành một giải pháp lý tưởng để lưu trữ dữ liệu theo luồng cụ thể như thông tin xác thực người dùng, kết nối cơ sở dữ liệu hoặc bất kỳ thông tin cụ thể nào khác theo luồng.

Cách hoạt động của Thread Local trong Java

Để sử dụng Thread Local trong ứng dụng Java của bạn, trước tiên bạn cần tạo một thể hiện của lớp Thread Local . Điều này có thể được thực hiện bằng cách gọi hàm tạo ThreadLocal , hàm tạo này sẽ tạo một phiên bản mới của lớp này. Tiếp theo, bằng cách tạo một đối tượng Thread Local , bạn có thể sử dụng nó để lưu trữ và truy xuất dữ liệu dành riêng cho luồng. Đây là một ví dụ về cách sử dụng Thread Local trong ứng dụng Java của bạn:
public class MyThreadLocalClass {
  private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();

  public static void set(String value) {
    threadLocal.set(value);
  }

  public static String get() {
    return threadLocal.get();
  }
}
Trong ví dụ này, chúng ta đã tạo một đối tượng Thread Local có tên threadLocal thuộc loại String . Chúng tôi cũng đã tạo hai phương thức: set()get() cho phép chúng tôi lưu trữ và truy xuất giá trị của biến Thread Local . Để lưu trữ một giá trị trong biến Thread Local , chúng ta chỉ cần gọi phương thức set() và truyền vào giá trị mà chúng ta muốn lưu trữ. Ví dụ: chúng ta có thể gọi MyThreadLocalClass.set("Hello, World!") để lưu chuỗi “Hello, World!” trong biến cục bộ của Thread . Để lấy giá trị của biến Thread Local , chúng ta chỉ cần gọi phương thức get() . Ví dụ: chúng ta có thể gọi String value = MyThreadLocalClass.get() để lấy giá trị của biến Thread Local .

Khuyến nghị khi làm việc với Thread Local

Mặc dù Thread Local có thể là một công cụ mạnh mẽ trong các ứng dụng Java của bạn nhưng điều quan trọng là phải sử dụng nó đúng cách để tránh các sự cố tiềm ẩn. Dưới đây là một số nguyên tắc cần lưu ý khi sử dụng Thread Local :
  1. Chỉ sử dụng Thread Local khi cần thiết: chỉ dành cho dữ liệu dành riêng cho thread. Nếu dữ liệu không dành riêng cho luồng thì nó phải được lưu trữ theo cách khác.
  2. Tránh sử dụng quá nhiều bộ nhớ: Thread Local có thể tiêu tốn một lượng bộ nhớ đáng kể nếu không sử dụng cẩn thận. Hãy chắc chắn xóa các biến Thread Local khi chúng không còn cần thiết để tránh sử dụng quá nhiều bộ nhớ.
  3. Sử dụng Thread Local một cách thận trọng trong môi trường đa luồng: điều quan trọng là phải hiểu những rủi ro và hạn chế tiềm ẩn. Hãy nhớ kiểm tra kỹ mã của bạn để đảm bảo rằng Thread Local hoạt động như mong đợi trong môi trường cụ thể của bạn.

Phần kết luận

Java Thread Local là một công cụ tuyệt vời cho phép các nhà phát triển chỉ tạo các biến cho một luồng cụ thể. Sử dụng Thread Local , bạn có thể lưu trữ dữ liệu dành riêng cho luồng, chẳng hạn như thông tin xác thực người dùng, kết nối cơ sở dữ liệu hoặc thông tin dành riêng cho luồng khác. Mặc dù Thread Local có thể là một công cụ mạnh mẽ nhưng điều quan trọng là phải sử dụng nó đúng cách để tránh những vấn đề tiềm ẩn. Bằng cách làm theo các phương pháp hay nhất và kiểm tra mã của mình, bạn có thể sử dụng mã đó một cách hiệu quả để cải thiện hiệu suất và độ tin cậy của các ứng dụng Java của mình.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION