JavaRush /Blog Java /Random-VI /Nghỉ giải lao #108. 12 cách sử dụng phổ biến của luồng Ja...

Nghỉ giải lao #108. 12 cách sử dụng phổ biến của luồng Java, Cách đánh giá phân bổ bộ nhớ của đối tượng trong Java

Xuất bản trong nhóm

12 cách phổ biến để sử dụng luồng Java

Nguồn: Dev.to API Java Streams xuất hiện lần đầu tiên trong Java 8. Mục đích của nó là cung cấp một cách nhỏ gọn hơn để thực hiện các thao tác phổ biến trên các bộ sưu tập đối tượng. Ngoài ra, API Java Streams có thể được sử dụng để triển khai các thuật toán phức tạp. Trong bài viết này, chúng ta sẽ nói về các trường hợp sử dụng phổ biến của Luồng Java. Nghỉ giải lao #108.  12 cách sử dụng phổ biến của các luồng Java, Cách đánh giá việc phân bổ bộ nhớ của đối tượng trong Java - 1Trước tiên, hãy làm rõ một số điều cơ bản:
  • luồng() - tạo luồng từ bộ sưu tập.

  • coll() - thu thập luồng vào một đối tượng. Một đối tượng có thể là một bộ sưu tập, một lớp nguyên thủy hoặc một lớp tùy chỉnh.

  • Collectors là lớp cung cấp (nhiều) phương thức tĩnh để thu thập luồng.

Bây giờ hãy xem xét một số trường hợp sử dụng Luồng:

1. Lọc

  • Được sử dụng để xóa các giá trị khỏi Bộ sưu tập dựa trên một điều kiện.

  • Để lọc các phần tử của bộ sưu tập dựa trên một điều kiện, hãy sử dụng phương thức filter() . Chỉ các phần tử phù hợp mới được lưu.

Ví dụ: xóa tất cả các số lẻ khỏi danh sách.
List<Integer> evenNumbers = originalList.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

2. Tiền xử lý

  • Hữu ích khi mọi giá trị trong bộ sưu tập cần được thay đổi tại chỗ.

  • Phương thức map() được sử dụng để áp dụng một hàm cho từng phần tử của bộ sưu tập và trả về một tập hợp các giá trị được tính toán mới.

Ví dụ: hãy chuyển đổi từng giá trị thành bình phương của nó.
List<Integer> squares = originalList.stream()
        .map(n -> n * n)
        .collect(Collectors.toList());

3. Chuyển đổi

  • Hữu ích khi chúng ta muốn chuyển đổi một bộ sưu tập thành một bộ sưu tập khác.

  • Có một số cách để đạt được điều này.

Như đã đề cập ở trên, chúng ta có thể sử dụng các phương thức map()coll() để chuyển đổi một bộ sưu tập thành một bộ sưu tập khác.

Ví dụ 1: Tạo Bản đồ từ Danh sách.

Chuyển đổi danh sách các chuỗi thành bản đồ các chuỗi và độ dài.
Map<String, Integer> wordLengths = words.stream()
        .collect(Collectors.toMap(
                word -> word,
                word -> word.length()));

Ví dụ 2. Chuyển đổi danh sách thành tập hợp.

Đây là trường hợp sử dụng phổ biến để loại bỏ các bản sao. Ngoài ra, nếu muốn đưa các phần tử trở lại danh sách, chúng ta có thể sử dụng các phương thức stream()coll() hai lần . Ví dụ: hãy chuyển đổi danh sách các chuỗi thành danh sách các chuỗi duy nhất:
// if we want to collect to a set
Set<String> uniqueWords = words.stream()
        .collect(Collectors.toSet());

// OR

// if we want to start and end as a list
List<String> uniqueWords = words.stream()
        .collect(Collectors.toSet()).stream().collect(Collectors.toList());

Ví dụ 3. Chuyển đổi danh sách sản phẩm thành danh sách tên của chúng. (Làm phẳng - Căn chỉnh)

List<String> productNames = products.stream()
        .map(product -> product.getName())
        .collect(Collectors.toList());

4. Giảm

  • Giảm Bộ sưu tập thành một giá trị duy nhất.

  • Phương thức less() được sử dụng để áp dụng một hàm cho từng phần tử của bộ sưu tập và trả về một giá trị duy nhất.

Lưu ý rằng vì phương thức less() trả về một giá trị duy nhất nên nó không thể được sử dụng để trả về Bộ sưu tập. Ví dụ, chúng tôi tổng hợp tất cả các giá trị trong danh sách:
int sum = numbers.stream()
        .reduce(0, (a, b) -> a + b);

5. Phân nhóm

  • Nhóm các thành phần của Bộ sưu tập dựa trên một điều kiện nhất định.

  • Để nhóm các thành phần của Bộ sưu tập theo điều kiện, hãy sử dụng phương thức Collectors.groupingBy() .

Ví dụ: hãy nhóm tất cả các sản phẩm vào danh sách sản phẩm theo danh mục của chúng.
Map<String, List<Product>> productsByCategory = products.stream()
        .collect(Collectors.groupingBy(product -> product.getCategory()));

6. Tìm kiếm

  • Tìm kiếm phần tử Bộ sưu tập đầu tiên hoặc bất kỳ phần tử nào khớp với một điều kiện.

  • Các phương thức findFirst()findAny() được sử dụng để tìm kiếm .

Điều này thường tương tự như tìm kiếm tuyến tính. Ví dụ: chúng tôi đang tìm kiếm từ đầu tiên trong danh sách, độ dài của từ này vượt quá 5 ký tự.
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. Sắp xếp

  • Sắp xếp các thành phần của Bộ sưu tập.

  • Phương thức được sắp xếp () được sử dụng để sắp xếp .

Nói chung, Collections.sort() là đủ để sắp xếp một bộ sưu tập. Chúng ta có thể sử dụngsort () một cách cụ thể nếu muốn chạy một thao tác khác. Ví dụ: hãy sắp xếp danh sách các số theo thứ tự tăng dần và sau đó trả về k phần tử đầu tiên.
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. Phân vùng

  • Phân tách các thành phần của Bộ sưu tập dựa trên một điều kiện nhất định.

  • Phương thức Collectors.partitioningBy() được sử dụng để phân tách các phần tử .

Sự phân tách tương tự như một nhóm, ngoại trừ việc nó trả về hai tập hợp—một cho các phần tử phù hợp với điều kiện và một cho các phần tử không khớp với điều kiện. Ví dụ: hãy chia học sinh thành những người đã vượt qua kỳ thi và những người đã trượt.
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. Đếm

  • Đếm số phần tử thoả mãn điều kiện.

  • Phương thức count() được sử dụng để đếm số phần tử thỏa mãn một điều kiện .

Ví dụ: hãy đếm số từ trong danh sách có độ dài vượt quá 5 ký tự.
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. Phạm vi

  • Tạo ra một loạt các giá trị.

  • Để tạo một phạm vi giá trị, hãy sử dụng phương thức range() .

Có các lớp đặc biệt để tạo các luồng thuộc một số loại nhất định - IntStream , LongStream , DoubleStreamStream . Các lớp này rất hữu ích khi làm việc với các kiểu số nguyên thủy. Để chuyển đổi một mảng thành một luồng, hãy sử dụng Arrays.stream() . Ví dụ: hãy tạo một dãy số từ 0 đến 10.
int[] numbers = IntStream.range(0, 10).toArray();

11. Kết hợp

  • Khớp các phần tử của một tập hợp với một vị từ (điều kiện).

  • Các phương thức như AnyMatch() , allMatch()noneMatch() được sử dụng để khớp các phần tử bộ sưu tập với một vị từ và trả về giá trị boolean .

Ví dụ: hãy kiểm tra các sản phẩm có giá cao hơn 10.
// true when all elements match the predicate
boolean allMatch = products.stream()
        .allMatch(product -> product.getPrice() > 10);

// true when any element matches the predicate
boolean anyMatch = products.stream()
        .anyMatch(product -> product.getPrice() > 10);

// true when no elements match the predicate
boolean noneMatch = products.stream()
        .noneMatch(product -> product.getPrice() > 10);

12. Tham gia

  • Nối các phần tử của tập hợp thành một chuỗi.

  • Để nối các phần tử của bộ sưu tập thành một chuỗi, hãy sử dụng phương thức Collectors.joining() .

Ví dụ: hãy nối tất cả các từ trong danh sách thành một chuỗi.
String joinedWords = words.stream()
        .collect(Collectors.joining(" "));
Đó là cho các kịch bản chung. Có những tình huống khác ít phổ biến hơn mà bạn có thể tự mình khám phá:
  • Luồng song song;
  • Số liệu thống kê;
  • Nhà sưu tập tùy chỉnh.

Lợi ích của chủ đề

  • Mã nhỏ gọn hơn—giảm số lượng mã cần thiết để xử lý bộ sưu tập.

  • Ít biến trung gian hơn. Các biến can thiệp có thể gây ra lỗi. Càng ít thì càng dễ tránh những sai sót không mong muốn.

  • Mã trực quan. Một số nhà phát triển sẽ không đồng ý rằng các luồng trực quan hơn các phương pháp khác. Tuy nhiên, khi chúng ta đã quen với chúng, chúng trở nên trực quan hơn nhiều so với các phương pháp khác.

Cảm ơn bạn đã đọc. Tôi hy vọng bạn thích bài viết này. Còn nhiều trường hợp khác mà các chủ đề có thể được sử dụng mà không được đề cập trong chủ đề này. Vui lòng thêm bất kỳ tình huống phổ biến nào mà tôi đã bỏ lỡ.

Cách đánh giá cấp phát bộ nhớ của đối tượng trong Java

Nguồn: DZone Bài viết này trình bày ba cách phổ biến nhất để đánh giá việc phân bổ bộ nhớ của đối tượng trong Java.

Đánh giá trí nhớ bằng Profiler

Cách dễ nhất để ước tính bộ nhớ của một số đối tượng là xem trực tiếp vào bộ nhớ JVM bằng cách sử dụng một trình lược tả như Visual VM . Nghỉ giải lao #108.  12 cách sử dụng phổ biến của các luồng Java, Cách đánh giá việc phân bổ bộ nhớ của đối tượng trong Java - 2Vấn đề với cách tiếp cận này là bạn cần kết nối với một JVM đang chạy, điều này có thể không thực hiện được đối với môi trường sản xuất vì lý do bảo mật.

Đánh giá trí nhớ bằng dụng cụ

Một cách khác để ước tính bộ nhớ được phân bổ cho một đối tượng nhất định là sử dụng Công cụ. Nói một cách đơn giản, chúng ta cần tạo một lớp và biên dịch nó thành một JAR. Sau khi tạo JAR, chúng ta phải thực thi JVM của mình cùng với JAR đó. Bạn có thể tìm hiểu thêm về phương pháp này tại đây . Nhược điểm ở đây là cần phải thêm một tệp jar cụ thể vào JVM, tệp này có thể không được chấp nhận để sản xuất do các vấn đề bảo mật hoặc liên quan.

Đánh giá trí nhớ bằng Thư viện JOL

Là một tùy chọn khác, chúng ta có thể sử dụng JOL Library . Đây là một thư viện rất mạnh có thể cung cấp ước tính chi tiết về trọng lượng của một đối tượng và bộ nhớ được phân bổ bởi một thể hiện đối tượng. Để sử dụng thư viện, chúng ta cần thêm một phụ thuộc:
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
Sau đó chúng ta có thể sử dụng nó như thế này:
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")

ObjectSizeCalculator từ kho lưu trữ Twitter

Kho lưu trữ GitHub công khai của Twitter có một lớp công cụ tên là ObjectSizeCalculator có thể ước tính bộ nhớ được phân bổ cho một phiên bản đối tượng nhất định. Nó không tốn nhiều bộ nhớ hoặc thời gian để sử dụng. Quá trình đánh giá mất vài giây, ngay cả đối với các đối tượng lớn. Sử dụng lớp này khá đơn giản:
ObjectSizeCalculator.getObjectSize(address)
Tôi khuyên dùng phương pháp này nhưng hãy nhớ rằng nó chỉ được hỗ trợ bởi Java Hotspot, OpenJDK và TwitterJDK.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION