<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: luan vu</title>
    <description>The latest articles on Forem by luan vu (@luanvu).</description>
    <link>https://forem.com/luanvu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F788022%2Fca767570-4336-4769-806b-3f02ebfeead6.jpeg</url>
      <title>Forem: luan vu</title>
      <link>https://forem.com/luanvu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/luanvu"/>
    <language>en</language>
    <item>
      <title>ArrayList và LinkedList trong Java</title>
      <dc:creator>luan vu</dc:creator>
      <pubDate>Sat, 23 Apr 2022 09:38:59 +0000</pubDate>
      <link>https://forem.com/luanvu/arraylist-va-linkedlist-trong-java-4706</link>
      <guid>https://forem.com/luanvu/arraylist-va-linkedlist-trong-java-4706</guid>
      <description>&lt;p&gt;List là một collection được sử dụng rất phổ biến trong Java, đặc biệt là ArrayList và LinkedList. Đã bao giờ bạn tự hỏi sự khác nhau giữa hai list này và các tình huống sử dụng của chúng. Cùng tìm hiểu dưới đây.&lt;/p&gt;

&lt;h2&gt;
  
  
  List trong Java
&lt;/h2&gt;

&lt;p&gt;List trong Java, hay interface java.util.List được mô tả như là một&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Danh sách có thứ tự&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Có thể truy xuất phần tử ở một vị trí bất kỳ trong list&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ArrayList
&lt;/h2&gt;

&lt;p&gt;Ưu điểm của array là tiết kiệm bộ nhớ và tốc độ truy xuất ngẫu nhiên (tìm một phần tử ở vị trí bất kỳ) nhanh. Tuy nhiên, đổi lại thì array phải có độ dài cố định khi bạn khởi tạo. Nếu khai báo nhiều quá sẽ tốn bộ nhớ, ít quá thì không đủ để lưu trữ.&lt;br&gt;
 Để thuận tiện cho cả việc sử dụng và tốc độ truy xuất, ArrayList ra đời để khắc phục các nhược điểm đó nhưng vẫn kế thừa ưu điểm trong việc truy xuất dữ liệu của array.&lt;br&gt;
 ArrayList làm điều đó bằng cách sử dụng một &lt;a href="https://en.wikipedia.org/wiki/Dynamic_array"&gt;dynamic array&lt;/a&gt; để lưu trữ các phần tử. Khi bạn thêm hoặc xóa phần tử, ArrayList sẽ tính toán để tạo một array mới có kích thước phù hợp và copy toàn bộ phần tử từ array cũ sang array mới.&lt;br&gt;
 Khởi điểm array sẽ rỗng và có một biến integer cho biết kích thước thực của ArrayList, gọi là size, bằng 0.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aMP3WakD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmf3alo3q8cczuxfy7rx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aMP3WakD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmf3alo3q8cczuxfy7rx.png" alt="Image description" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Array này là một static array rỗng và share cho tất cả các hàm khởi tạo ArrayList để giảm thiểu bộ nhớ sử dụng nếu bạn mới chỉ khởi tạo chứ chưa dùng.&lt;br&gt;
 Khi bắt đầu thêm mới một phần tử, elementData sẽ được gán bằng một mảng mới có độ dài thường là bằng 10.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H7Atfw3_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqkjx9avnyq0z14oqikw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H7Atfw3_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqkjx9avnyq0z14oqikw.png" alt="Image description" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Khi tiếp tục thêm phần tử, elementData sẽ được lấp đầy&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Wij1usT3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzl31twpshwpvvmpid0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Wij1usT3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzl31twpshwpvvmpid0u.png" alt="Image description" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Giả sử elementData đã được lấp đầy (10 phần tử)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nE0NLs_j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zo66d2e2g5gxbrn8ik3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nE0NLs_j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zo66d2e2g5gxbrn8ik3v.png" alt="Image description" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Khi ta lại thêm phần tử, elementData sẽ lại được khởi tạo bằng một array mới có size tăng thêm 50% size gốc&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZW67FcC6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iu2qjdjhssiv50wwsbre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZW67FcC6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iu2qjdjhssiv50wwsbre.png" alt="Image description" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cách thức tăng của elementData là newSize = oldSize * 1.5&lt;br&gt;
 Tương tự:&lt;br&gt;
 10 -&amp;gt; 15&lt;br&gt;
 15 -&amp;gt; 22&lt;br&gt;
 22 -&amp;gt; 33&lt;br&gt;
 33 -&amp;gt; 49&lt;br&gt;
 49 -&amp;gt; 73&lt;/p&gt;

&lt;p&gt;Trong trường hợp delete, giả sử delete tại index 5, thực hiện:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Copy item từ vị trí 5 + 1 tới cuối và đè vào index 5&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Giá trị ở vị trí cuối sẽ bị thừa ra, đặt giá trị thành null&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Giảm size của list đi 1&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Muhx7Te--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4baosvtuc02q6l8wu53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Muhx7Te--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4baosvtuc02q6l8wu53.png" alt="Image description" width="800" height="549"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Giờ ta có một list chỉ còn 10 phần tử.&lt;br&gt;
&lt;strong&gt;Nhận xét&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Với cách liên tục tạo mới array và copy array, ArrayList sẽ kém trong việc thêm mới hoặc xóa phần tử, sẽ ngày một tệ hơn khi số phần tử tăng lên.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Truy xuất ngẫu nhiên trong ArrayList chính là truy xuất theo index trong array nên tốc độ rất nhanh.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cách delete của ArrayList sẽ hoạt động kém nếu bạn delete với những index nhỏ, tệ nhất sẽ là index = 0. Giả sử list của bạn có size = 100. Nếu bạn delete phần tử đầu tiên, ArrayList sẽ phải copy 99 phần tử.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;array trong ArrayList sẽ ngày một to ra khi bạn thêm phần tử, thêm mỗi lần 50% khi thiếu chỗ lưu và sẽ không giảm đi khi bạn delete.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  LinkedList
&lt;/h2&gt;

&lt;p&gt;LinkedList là một danh sách liên kết kép ( &lt;a href="https://en.wikipedia.org/wiki/Linked_list#Doubly_linked_list"&gt;Doubly-linked list&lt;/a&gt;), thay vì dùng array để lưu dữ liệu như ArrayList, LinkedList lại dùng cấu trúc danh sách liên kết để lưu trữ.&lt;br&gt;
 Cách thức hoạt động như sau:&lt;br&gt;
 LinkedList bao gồm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;size để lưu dung lượng thực của list, giống ArrayList&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node first để lưu phần tử đầu tiên của list. Ban đầu chưa có sẽ là null&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node last để lưu phần tử cuối cùng của list. Ban đầu chưa có sẽ là null&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mỗi node sẽ chứa data thực của node, gọi là item, một node kế tiếp của nó, gọi là next và một node đứng ngay trước nó, gọi là prev&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Khởi điểm, LinkedList sẽ bao gồm 2 node first và last đều mang giá trị null&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PkWCz8Kr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwxf4mif5lhhkti1h8c7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PkWCz8Kr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwxf4mif5lhhkti1h8c7.png" alt="Image description" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Khi thêm phần tử đầu tiên, thay thế node first bằng phần tử đó&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Pk5xYT0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wujdopew7mdu9ur92oy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Pk5xYT0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9wujdopew7mdu9ur92oy.png" alt="Image description" width="748" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Khi thêm phần tử tiếp theo, thay vào node last và liên kết giữa node first và node last. Nay list đã có tối thiểu 2 node&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DCVr9cRE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/50y376h1rgrhrtkx47h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DCVr9cRE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/50y376h1rgrhrtkx47h3.png" alt="Image description" width="714" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cứ như vậy, khi tiếp tục insert, dù là ở cuối danh sách hay đầu danh sách, LinkedList chỉ việc liên kết các node lại với nhau&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CyilfvKh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6gvc28zv2f40ad9tw47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CyilfvKh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x6gvc28zv2f40ad9tw47.png" alt="Image description" width="800" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tương tự khi thêm ở giữa list thì list cũng chỉ cần đơn giản là tạo ra node mới, thay đổi liên kết 2 node bên cạnh node mới thêm vào&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ltRcEab9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nmdd7yzoh9rapufqhgiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ltRcEab9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nmdd7yzoh9rapufqhgiq.png" alt="Image description" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Khi cần delete, LinkedList cũng thay đổi liên kết 2 node bên cạnh node vừa bị xóa&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dvasql89--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny1jnwqd8jn9fphvybfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dvasql89--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny1jnwqd8jn9fphvybfh.png" alt="Image description" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Khi cần lấy ra một phần tử ở index bất kỳ, không như ArrayList, LinkedList phải đi dần dần từng node một từ first hay last phụ thuộc vào index ở gần bên nào hơn.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cq2t2w2I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6u5obdjumy7b4h6rlmrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cq2t2w2I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6u5obdjumy7b4h6rlmrw.png" alt="Image description" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Giả sử bạn có một list với 1000 phần tử. Khi bạn cần lấy ra phần tử có index = 500, LinkedList sẽ phải duyệt tới toàn bộ 500 phần tử để có thể lấy ra cái bạn muốn, điều đó là rất tệ.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nhận xét&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Việc tìm phần tử ở vị trí ngẫu nhiên của LinkedList kém hơn ArrayList, đặc biệt với index ở trung tâm&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Việc thêm hoặc xóa node trong LinkedList rất dễ dàng nhưng sẽ tệ dần nếu bạn insert/delete càng về trung tâm của list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ArrayList vs LinkedList
&lt;/h2&gt;

&lt;p&gt;Từ những nhận xét ở trên, các bạn hoàn toàn có thể rút ra so sánh giữa ArrayList và LinkedList.&lt;br&gt;
 Cá nhân mình, chưa bao giờ dùng LinkedList, vì các lý do sau:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Chúng ta đều sử dụng những list có kích thước nhỏ.
&lt;/h3&gt;

&lt;p&gt;Khi list có kích thước nhỏ thì tốc độ mở rộng của dynamic array không hề thua kém so với LinkedList.&lt;br&gt;
 Dưới đây là benchmark tốc độ insert với các kích thước khác nhau.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7B5qeOfx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qot2jbvqq3zdxc0w5pn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7B5qeOfx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qot2jbvqq3zdxc0w5pn.png" alt="Image description" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Không có quá nhiều khác biệt&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Chúng ta có xu hướng sử dụng list để duyệt và tìm kiếm nhiều hơn so với insert từng phần tử một.
&lt;/h3&gt;

&lt;p&gt;Việc duyệt bằng array chắc chắn là vượt trội hơn so với cách duyệt qua từng phần tử của LinkedList&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Có nhiều cách để tạo ra 1 ArrayList chứa nhiều phần tử mà vẫn khắc phục được nhược điểm của ArrayList
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tạo ArrayList từ Collection khác: new ArrayList&amp;lt;&amp;gt;(Collection&amp;lt;&amp;gt; e);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thêm nhiều phần tử một lúc bằng list.addAll(Collection&amp;lt;&amp;gt; e);&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Định số phần tử trước khi insert: new ArrayList&amp;lt;&amp;gt;(int initialCapacity)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dùng Stream API (Stream API sử dụng list.addAll)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. LinkedList tốn nhiều bộ nhớ để lưu trữ
&lt;/h3&gt;

&lt;p&gt;Giả sử có một list các integer, với size = 1000, và size = 1000_000, dung lượng cần để lưu trữ như sau:&lt;/p&gt;

&lt;p&gt;Cách tính một ArrayList khi add lần lượt 1000 integer sẽ bao gồm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;object header = 12&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;size = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;modCount = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;elementData reference = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;elementData header = 12&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;elementData size = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;elementData item = 16 * 1234&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total 19784 byte&lt;br&gt;
 Với LinkedList:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;object header = 12&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;size = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;modCount = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node first reference = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node last reference = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Object alignment gap = 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node size = 12 (object header) + 4 (item reference) + 16 (Integer) + 4 (next reference) + 4 (prev reference) = 40&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All node= node size * 1000 = 40000&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total 40032 byte&lt;/p&gt;

&lt;p&gt;Bạn có thể thấy là LinkedList tốn dung lượng gấp đôi so với ArrayList. Ngoài ra array luôn thân thiện với Garbage Collection hơn so với các Node của LinkedList.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. LinkedList insert/delete tốt nhưng chưa chắc đã nhanh.
&lt;/h3&gt;

&lt;p&gt;Giả sử bạn cần insert hoặc delete ở giữa list. Trước khi có thể insert/delete, nó phải duyệt qua một nửa số phần tử của list, điều mà LinkedList làm tệ nhất&lt;/p&gt;

&lt;h2&gt;
  
  
  Một số mẹo khi dùng với list
&lt;/h2&gt;

&lt;h2&gt;
  
  
  findFirst hay findAny
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z47a5Ajr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qjnipe56s5uoq5npio6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z47a5Ajr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qjnipe56s5uoq5npio6.png" alt="Image description" width="508" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Có người thích dùng findFirst, có người lại findAny, cái nào đúng hơn?&lt;br&gt;
 Với &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html#sequential--"&gt;sequential stream&lt;/a&gt; và List trong Java là một list có thứ tự thì findFirst hay findAny cho ra kết quả như nhau và tốc độ như nhau trong mọi trường hợp.&lt;br&gt;
 Nhưng đối với parallel stream, findAny có thể trả ra kết quả khác với findFirst. Hoặc bạn dùng nó với Set thì 2 hàm cũng cho ra kết quả khác nhau.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tìm kiếm một phần tử trong list
&lt;/h3&gt;

&lt;p&gt;Trước Java 8, tôi thường code như dưới đây&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e5GwL6T1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/owh1wnhe9gmumhaad6hk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e5GwL6T1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/owh1wnhe9gmumhaad6hk.png" alt="Image description" width="680" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nhưng đến nay, hãy code như sau:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rUw9h5UJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vk9zrcvjgojth14zjxsq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rUw9h5UJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vk9zrcvjgojth14zjxsq.png" alt="Image description" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Không if-else, không for-loop&lt;/p&gt;

&lt;h3&gt;
  
  
  Kiểm tra tất cả phần tử thỏa mãn điều kiện
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l7ZuWYkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gepm8lwwgeddy18g1v9e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l7ZuWYkJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gepm8lwwgeddy18g1v9e.png" alt="Image description" width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Kiểm tra có ít nhất một phần tử thỏa mãn điều kiện
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--msMs2e1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8rqe3eaj7j47ld26e6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--msMs2e1A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r8rqe3eaj7j47ld26e6h.png" alt="Image description" width="800" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sort list theo một field
&lt;/h3&gt;

&lt;p&gt;Sort theo ascending&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ueqf3EGg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1s7xfe5mj396ykm8axnc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ueqf3EGg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1s7xfe5mj396ykm8axnc.png" alt="Image description" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sort theo descending&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--exORXEpS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8me4bewi7mbb2c23ahzv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--exORXEpS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8me4bewi7mbb2c23ahzv.png" alt="Image description" width="800" height="147"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete các phần tử thỏa mãn điều kiện với removeIf
&lt;/h3&gt;

&lt;p&gt;Gọn hơn so với cách dùng iterator.remove.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YFKrr7BY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oznklv064telslcblen3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YFKrr7BY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oznklv064telslcblen3.png" alt="Image description" width="800" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dzone.com/articles/java-object-size-estimation-measuring-verifying"&gt;&lt;strong&gt;Java Object Size: Estimating, Measuring, and Verifying via Profiling - DZone Java&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html"&gt;&lt;strong&gt;ArrayList (Java Platform SE 8 )&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html"&gt;&lt;strong&gt;LinkedList (Java Platform SE 8 )&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://luanvv.com/blog/arraylist-va-linkedlist/"&gt;https://luanvv.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>arraylist</category>
      <category>linkedlist</category>
      <category>list</category>
    </item>
    <item>
      <title>From Zero to PSM I, less than 24 hours!</title>
      <dc:creator>luan vu</dc:creator>
      <pubDate>Sat, 22 Jan 2022 10:07:05 +0000</pubDate>
      <link>https://forem.com/luanvu/from-zero-to-psm-i-less-than-24-hours-3o77</link>
      <guid>https://forem.com/luanvu/from-zero-to-psm-i-less-than-24-hours-3o77</guid>
      <description>&lt;p&gt;All the knowledge you need to pass the certification exam, encapsulated in the so-called Scrum Guide, 19 pages, which you can read at &lt;a href="https://www.scrumguides.org/scrum-guide.html"&gt;https://www.scrumguides.org/scrum-guide.html&lt;/a&gt;. So, firstly, you need to read it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scrum Guide - 10 hours
&lt;/h3&gt;

&lt;p&gt;I don't think reading 19 pages will make it easy to pass the exam unless you can memorize these 19 pages exactly every word. I think you should read it many times; some people even have to read up to 10 times. I recommend only reading up to 5 times because it's useless to read once you don't understand.&lt;/p&gt;

&lt;p&gt;Reading often does not mean reading continuously without stopping; this is not chanting or mantras! It will help if you read for the first time to understand. Then watch the course (I will talk about it later), then go back to read concepts you don't understand. Then when doing the Practice test(talk later too), you should also go back to read the places you don't understand. And finally, you should make a note section that summarizes the guide's content, and of course, you have to re-read it. In short, I calculate that I read about five times, each time takes 1 hour (3 minutes/page is already relatively slow).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact&lt;/strong&gt;: I only read it once; when I took notes, the other four times, I listened to it, taking advantage of the time to wash the dishes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Online course - 2 hours
&lt;/h3&gt;

&lt;p&gt;If you are a person who has no concept of Scrum, just reading the theory will only cause headaches. So, I recommend taking more online courses, in my opinion about $ 10, 3 Practice Test lessons and 2 hours of your life for the course is highly worth it.&lt;/p&gt;

&lt;p&gt;The course is here &lt;a href="https://www.udemy.com/course/scrum-master-certification-preparation-mock-exam-questions-psm-i/"&gt;https://www.udemy.com/course/scrum-master-certification-preparation-mock-exam-questions-psm-i/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The content of the course is not outside the Scrum Guide. However, the course will give you more visual examples and provide some tips &amp;amp; tricks for the exam. I consider this course the most critical key, especially for someone who has no idea about Scrum (like me).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: you can skip the live webinar, as it's not relevant to the test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact&lt;/strong&gt;: I also took advantage of the time to wash the dishes to watch the entire 2 hours of the course&lt;/p&gt;

&lt;h3&gt;
  
  
  Practice test - 10 hours
&lt;/h3&gt;

&lt;p&gt;Practice tests are also significant. Knowledge is only 19 pages, so the question set of the real exam cannot be boundless. According to my experience, about 60% of the questions in the exam are pretty close to the Practice tests. In addition, doing many practice tests will help you get used to the speed of the test and practice fast thinking.&lt;/p&gt;

&lt;p&gt;When I took the exam, it only took me 40 minutes for 80 questions; the remaining 20 minutes I spent reviewing 7--8 questions.&lt;/p&gt;

&lt;p&gt;Some tests you can refer to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://mlapshin.com/index.php/scrum-quizzes/sm-learning-mode/"&gt;https://mlapshin.com/index.php/scrum-quizzes/sm-learning-mode/&lt;/a&gt; (Free). You can try Real Mode, but there is no need because the topic here is quite simple.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.scrum.org/open-assessments/scrum-open"&gt;Open Assessments&lt;/a&gt; (Free). The owner's topic should ultimately be at the same level as the real test. However, they only gave 30 questions and did it in 30 minutes.&lt;/li&gt;
&lt;li&gt;  3 Practice tests in the course I have introduced above&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After learning the above knowledge, the practice tests are not tricky; I usually only take about 40 minutes for each test with over 80 questions; the rest is to review. So I keep counting about 90 minutes at a time. When doing a particular sentence, you should practice looking at the keywords of the sentence and the method of exclusion. Also, your English shouldn't be too bad. For example, I have didn't know the word "&lt;em&gt;prohibit&lt;/em&gt;" means "&lt;em&gt;forbidden&lt;/em&gt;," so when I took the test, I got one wrong sentence. So, improve your vocabulary in practice tests.&lt;/p&gt;

&lt;p&gt;You should score above 80% in Practice tests. In the course I mentioned above, there were three tests; I did it repeatedly, a total of about five times. I only did the article on &lt;a href="https://mlapshin.com/"&gt;https://mlapshin.com&lt;/a&gt; once because it was too easy. Open Assessments also only do it once because I'm pretty sure all of them.&lt;/p&gt;

&lt;p&gt;When reviewing the test, never try to remember the question and the answer. Please read questions, answers, and explanations carefully; refer to the Scrum Guide for understanding. You will get stuck on puns during the real exam if you just try to memorize them. I WAS SHOCKED when I took the actual test because they had about 30% of the questions much more complicated than the Practice test. Those questions had slightly changed the wording, the answers also sounded different from the Scrum Guide, but they are never outside the Scrum Guide. Therefore, understanding is critical.&lt;/p&gt;

&lt;p&gt;When you are confident, it's time to take the test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact&lt;/strong&gt;: I can't take advantage of this while washing the dishes because my hands are covered with soap. I usually take advantage before going to bed or free afternoon, even in some boring meetings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exam, 1 hour 10 minutes
&lt;/h3&gt;

&lt;p&gt;Below are the details of the exam. To see the latest updates, you should visit the homepage at &lt;a href="https://www.scrum.org/professional-scrum-master-i-certification#Details"&gt;https://www.scrum.org/professional-scrum-master-i-certification#Details&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Fee: $150 per attempt&lt;/li&gt;
&lt;li&gt;  Passing score: 85%&lt;/li&gt;
&lt;li&gt;  Time limit: 60 minutes&lt;/li&gt;
&lt;li&gt;  Number of Questions: 80&lt;/li&gt;
&lt;li&gt;  Format: Multiple Choice, Multiple Answer, and True/False&lt;/li&gt;
&lt;li&gt;  Difficulty: Intermediate&lt;/li&gt;
&lt;li&gt;  Language: English only&lt;/li&gt;
&lt;li&gt;  Scrum Resources&lt;/li&gt;
&lt;li&gt;  Required course: None&lt;/li&gt;
&lt;li&gt;  Recommended courses: &lt;a href="https://www.scrum.org/courses/professional-scrum-foundations-training"&gt;Professional Scrum Foundations&lt;/a&gt; or &lt;a href="https://www.scrum.org/courses/professional-scrum-master-training"&gt;Professional Scrum Master&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.scrum.org/resources/suggested-reading-professional-scrum-master"&gt;PSM Subject Areas&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Practice Assessment: &lt;a href="https://www.scrum.org/open-assessments/scrum-open"&gt;Scrum Open&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Ways to &lt;a href="https://www.scrum.org/resources/ways-learn-about-scrum"&gt;Learn More&lt;/a&gt; to help you prepare&lt;/li&gt;
&lt;li&gt;  Passwords have no expiration date but are valid for one attempt only&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exam is online testing; you can comfortably use everything at home. However, the number of questions is quite large (80 questions), the time is (too) short (60 minutes), and the score is very high (85%); every mistake, no matter how small, comes at a price, so keep focus.&lt;/p&gt;

&lt;p&gt;A considerable disadvantage of online exams is the speed of the network. If your network is slow or your computer is dead, it's a disaster. Don't forget the notes I mentioned above; it will be convenient to look up. Another thing is that when you click Next, Previous, pay special attention; during the page load, you may click again and choose the wrong answer again. Or if your hands are shaking too much, it's easy to reload the page or close the tab/browser by accident, I don't know if it's okay, but it's going to be a problem. Be careful with each touch.&lt;/p&gt;

&lt;p&gt;To register for the test is quite simple. You register an account on &lt;a href="https://www.scrum.org/,"&gt;https://www.scrum.org/,&lt;/a&gt; buy Assessment, a password will be sent to your email, and you can start taking the test immediately with the password you just received.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6-hTJYtn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9ze25djo981gjmnc2ds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6-hTJYtn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v9ze25djo981gjmnc2ds.png" alt="PSM I certification" width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I have summarized the PSM I am learning in just 23 hours and 10 minutes. It took me a week to study and take the exam because I didn't wash the dishes 24 hours in a row. My friend has taken only four days. With only two days of continuous learning, the total time could be less than 23 hours.&lt;/p&gt;

&lt;p&gt;However, writing articles is how I do it, but $150 is yours to spend, and this is not a speed contest, so don't be too hasty to lose your money. Take the test when you are ready. Good luck.&lt;/p&gt;

</description>
      <category>certification</category>
      <category>psmi</category>
      <category>scrummaster</category>
    </item>
    <item>
      <title>How to Pass the AWS Solutions Architect Professional Exam</title>
      <dc:creator>luan vu</dc:creator>
      <pubDate>Sat, 22 Jan 2022 09:53:23 +0000</pubDate>
      <link>https://forem.com/luanvu/how-to-pass-the-aws-solutions-architect-professional-exam-4f34</link>
      <guid>https://forem.com/luanvu/how-to-pass-the-aws-solutions-architect-professional-exam-4f34</guid>
      <description>&lt;p&gt;You are looking to take the AWS Certified Solutions Architect — Professional certification exam. Today I will help you with some tips &amp;amp; tricks that I learned during my professional exam preparation two years ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I PASSED the New AWS Solutions Architect Professional?
&lt;/h2&gt;

&lt;p&gt;Another guide to the certification exam, probably reading the White Paper, watching videos on YouTube, taking that course, etc. No! Such articles are present on the internet a lot. I can get you some:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://acloud.guru/forums/aws-csa-pro-2019/discussion/-L_joCzK9FTbpP2P7H0Z/how_i_passed_the_new_aws_solut"&gt;How I PASSED the New AWS Solutions Architect Professional (Feb 2019 version) exam last March 9!&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://acloud.guru/forums/aws-csa-pro-2019/discussion/-Lc31u8nAIbpeo9q9mM7/aws_certified_solutions_archit"&gt;AWS Certified Solutions Architect --- Professional 2019 (feedback)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://virtualbonzo.com/2020/02/03/my-aws-solution-architect-professional-certification-experience/"&gt;My AWS Solution Architect Professional Certification Experience&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://medium.com/grey-frogs/my-path-to-aws-certified-solutions-architect-professional-bebd42eb5d5"&gt;My path to AWS Certified Solutions Architect --- Professional&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://acloud.guru/forums/aws-certified-solutions-architect-professional/discussion/-KEAY5AHdre2DzoI-H99/passed-sa-pro-today"&gt;Passed SA Pro today&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those articles are already too many, and adding one of mine is nothing more. Are the other people correct? Right. But to do it is not as easy as it sounds. The exam depends on your ability to learn and your background knowledge. If you study for four months, you will die (I have looked for a whole year, what a shame), but you could still don't pass no matter an entire year's preparation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the standard learning path?
&lt;/h3&gt;

&lt;p&gt;In general, The path to passing the AWS certification exam includes (don't miss anything):&lt;/p&gt;

&lt;h3&gt;
  
  
  1.  Read White papers
&lt;/h3&gt;

&lt;p&gt;There are hundreds of White papers, some with thousands of pages. Can you read it all? No matter how many you read, how much are you able to remember?&lt;/p&gt;

&lt;p&gt;I just checked, now there are 314 White Paper &amp;amp; Guides; you can check them at &lt;a href="https://aws.amazon.com/whitepapers/?whitepapers-main.sort-by=item.additionalFields.sortDate&amp;amp;whitepapers-main.sort-order=desc&amp;amp;awsm.page-whitepapers-main=1"&gt;AWS Whitepapers &amp;amp; Guides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You should read all the essential White Papers mentioned in those articles above.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.  Read FAQs
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/faqs/"&gt;AWS | FAQs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FAQs are also important. You should read all.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.  Watch AWS re:Invent, This Is My Architecture in YouTube
&lt;/h3&gt;

&lt;p&gt;If you don't have much chance to try services architectures (like me), these videos are beneficial. They show you how a service should be used in actual projects (the exam too, of course) and how a group of services interact in architecture to resolve problems.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/c/amazonwebservices/search?query=AWS%20Re%3Ainvent"&gt;Amazon Web Services&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4.  Take some online/offline courses
&lt;/h3&gt;

&lt;p&gt;It is the easiest to access. Many (most) AWS courses are available, both paid and paid. AWS also has some Exam Readiness (Free) to guide you through the exam questions&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/training/course-descriptions/exam-workshop-solutions-architect-professional/"&gt;Exam Readiness: AWS Certified Solutions Architect --- Professional&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many types of courses, but they are not enough in general. Especially some of the default courses require you to have a good knowledge of AWS and the overview for you. If you stick to them only, failure is inevitable.&lt;/p&gt;

&lt;p&gt;I found a precious course on Udemy. It could be more expensive than usual, but the author deserves it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/share/104sE03@v25ocWwp5mS6EczCcLEoR6xjbdtVk0GPohkBLMVwUaLf4HB5bd4GAH_1dxW_J10=/"&gt;https://www.udemy.com/share/104sE03@v25ocWwp5mS6EczCcLEoR6xjbdtVk0GPohkBLMVwUaLf4HB5bd4GAH_1dxW_J10=/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fun Fact: The first time I took the exam, It hit me in the face with a service called Amazon Mechanical Turk, which didn't appear in any of the White Papers, FAQs, or AWS Console. I think it is a question that has not been scored, so don't worry if AWS gives you such a surprise.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5.  Practice
&lt;/h3&gt;

&lt;p&gt;Those learning materials are certainly informative, but it's hard to remember them all if you just read them and watch them do it. Practicing helps you understand better reflect better. Never skip practice any service.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.  Learn English
&lt;/h3&gt;

&lt;p&gt;It's serious. It depends on the certification level you take the exam. With Professional, I took the exam, and all questions are very long; printing must also be over 50 pages. As I read and thought of the answer, it was indeed a terrible sprint. For test takers whose native language is not English (non-English speakers or English as a Second Language), AWS allows you to request accommodations, whereby you get a bonus of 30 minutes each time, so take advantage of it.&lt;/p&gt;

&lt;p&gt;Many of you are probably shocked and don't dare to study, but that's the truth. This test is challenging, requiring hundreds of hours of study and practice. You should have terrible determination to make it through. Fortunately, Amazon will only test you on a few essential services. If you know (to the point of mastering) them, you have achieved over 80%. And if you don't understand these services and lose points, then strange services you never touch will be a lifesaver, but it is boundless knowledge. That is why AWS Solutions Architect Professional is touched, it is difficult to understand something deeply, and if it is broad, it is too wide to understand it all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip &amp;amp; Trick
&lt;/h2&gt;




&lt;p&gt;I'm not a person who can remember well. I tried to learn by going from service to service and memorizing them. According to statistics, I have read at least 47 full books about AWS, about 10--20 White Papers. However, the more I try to remember, the more I forget, learning 10--20 services, overlooking the first ones, reading a lot of books also forgetting quite a bit. So, I chose to study on my own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service classification
&lt;/h3&gt;

&lt;p&gt;AWS has already categorized it for you at &lt;a href="https://aws.amazon.com/products/"&gt;https://aws.amazon.com/products/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Service classification is critical. It helps you know what you face and how you deal with it. If you encounter a storage service, you need to know security, capacity, availability, and reliability. If you use databases, remember it is RDBMS or NoSQL, cache, or Big data.&lt;/p&gt;

&lt;p&gt;It also helps you to remember the service better. There are various service names you have never heard before, so classification helps you have some idea about it. For instance, EC2 Auto Scaling or Elastic Load Balancer sounds reminiscent, but what do you think Neptune's purpose? Universe? Snowball, Glacier, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Based on Well-Architected Framework's Five Pillars
&lt;/h3&gt;

&lt;p&gt;Well-Architected Framework provides guidelines to help customers deploy systems on AWS. The framework offers five main pillars:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Security&lt;/li&gt;
&lt;li&gt;  Reliability&lt;/li&gt;
&lt;li&gt;  Performance Efficiency&lt;/li&gt;
&lt;li&gt;  Cost Optimization&lt;/li&gt;
&lt;li&gt;  Operational Excellence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When encountering any service, you need to think about these pillars.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.  Security
&lt;/h3&gt;

&lt;p&gt;AWS places great emphasis on security across all architects. There are two main types of security that you need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Security operations&lt;/li&gt;
&lt;li&gt;  Data protection&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Security operations
&lt;/h4&gt;

&lt;p&gt;There are always employees who do wrong things they are not authorized to do or should not do. Those are why there are services like IAM, Organizations, Cognito, CloudTrail, etc. When learning a specific service, you must know how to grant access or limit it. Amazon S3, how to not allow others to publish it? How do I allow access to someone with another AWS account (and only them)? How to prevent someone from Terminating EC2 instances? Knowing what a service can do is important, but securing it is just as important.&lt;/p&gt;

&lt;h4&gt;
  
  
  Data protection
&lt;/h4&gt;

&lt;p&gt;You must get used to the concept of Encrypt at rest and Encrypt in transit. Is data stored in Storage encrypted? Is it encrypted when transferring data to the internet or on-premises via VPN? Most services are encrypted in transit by default, but encrypt at rest is not (Encryption is not enabled by default on EBS). There are still a lot of demanding customers out there. They require even more security. Have to use CloudHSM, use their certificate, or use end-to-end encryption too, and it's tough as well. You will become confusing with such services as KMS, CloudHSM, Direct Connect, Security Hub, Transit Gateway, VPN, etc... Still, it will frequently appear in the exam because that's how enterprise applications are built.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.  Resiliency: Availability and Disaster Recovery (DR)
&lt;/h3&gt;

&lt;p&gt;High Availability, Blue/Green Deployment, Zero Down Time, Uptime, service level agreement (SLA), recovery time objective (RTO), recovery point objective (RPO), Redundancy, Failback, etc. You must go into deep dives on it.&lt;/p&gt;

&lt;p&gt;Maybe the projects you have done or are doing are at an elementary level: one server, one database, one data center, etc. Stop and start again. But when it came to AWS, the architecture standard took a new high level. Your system must be redundant for everything: hardware failure leading to server stop or data loss. Possibilities like hurricanes, earthquakes, and volcanoes destroy a data center. Even, you have to consider the case of the main error from AWS.&lt;/p&gt;

&lt;p&gt;You need to know four ways to preserve the system&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Backup and Restore&lt;/li&gt;
&lt;li&gt;  Pilot Light&lt;/li&gt;
&lt;li&gt;  Warm Standby&lt;/li&gt;
&lt;li&gt;  Multi-site Example&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, EC2 only guarantees 95.0% availability, which means every 1 hour, EC2 can be down for 3 minutes. We need to combine with Auto Scaling Group, Load Balancer to increase availability. More advanced, use Cross-region Load Balancer, Multi-site between AWS infrastructure and on-premises. The Serverless option can also be considered as an alternative. What about data? EC2 stores data in EBS. How to ensure no data loss? By now, you will probably have to know things like RAID, Snapshot, Point-in-time-recovery (PITR).&lt;/p&gt;

&lt;p&gt;Similarly, in RDS, we have RDS snapshot, backtrack, Replica, Multi-AZ, etc. With ElastiCache, there is also Multi A-Z, Failover, Append Only Files (AOF)...You also need to know how long it takes to recover (RTO) and how much data can be lost (RPO). If customers need to restore the system within 1 hour, storing it in Glacier is wrong.&lt;br&gt;
Refer&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://aws.amazon.com/blogs/publicsector/rapidly-recover-mission-critical-systems-in-a-disaster/"&gt;Rapidly recover mission-critical systems in a disaster&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://cloud.netapp.com/blog/understanding-aws-high-availability-compute-sql-and-storage"&gt;AWS High Availability: Compute, SQL and Storage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://aws.amazon.com/blogs/startups/high-availability-for-mere-mortals/"&gt;High Availability for Mere Mortals&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.  Performance
&lt;/h3&gt;

&lt;p&gt;The performance here is understood as using computing resources to meet system requirements and maintain performance when conditions change or technology evolves. Some of the issues raised could be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Latency&lt;/li&gt;
&lt;li&gt;  IOPS&lt;/li&gt;
&lt;li&gt;  Throughput&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When choosing a service to use for your architecture, there are four types of resources you need to consider: compute, storage, database, and network.&lt;/p&gt;

&lt;h4&gt;
  
  
  Compute
&lt;/h4&gt;

&lt;p&gt;There are three main types of computing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Instance&lt;/em&gt;: a virtual server, typically EC2 and Lightsail. You can use EC2 to solve everything if there is no other option. For example, launch a MySQL server inside an EC2 instance.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Container&lt;/em&gt;: this is a way of virtualizing the operating system, I can immediately think of Docker, Kubernetes. With AWS, think about ECS, Fargate, and EKS. When to use Container instead of Instance? Most of the answers (in the test) will be customers who already use on-premises containers and want to spend the least amount of effort if migrating to AWS.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Function&lt;/em&gt;: focus on code and run without having to manage instances. Functions have three essential benefits: minimal management effort, outstanding scalability and are particularly suitable for event-based programs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Storage
&lt;/h4&gt;

&lt;p&gt;There are three main types of storage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Object Storage: just S3&lt;/li&gt;
&lt;li&gt;  Block Storage: just EBS&lt;/li&gt;
&lt;li&gt;  File Storage: EFS, FSx&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my opinion, Storage Gateway should also be included here. The storage classification doesn't make much sense either. You can save it in Object Storage, Block Storage, or File Storage with a file. However, there is a slight difference. E.g., S3 is limited to 3,500 PUT/COPY/POST/DELETE and 5,500 GET/HEAD requests per second per prefix (directory name), and don't forget there's also a KMS limit if you choose to encrypt. And yet, accessing files from S3 will have extremely high latency. Think about them when you use them. With EBS, it is necessary to know the difference between the volume types, which are optimal for IOPS? Which are optimal for Throughput? If you need even higher performance, you can think of RAID, but what are the disadvantages of RAID? Data loss, Downtime. EBS still has certain limitations: IOPS, Throughput, Hybrid Storage, Limit storage size, Sharing, Availability, etc. Then you will need to use EFS.&lt;/p&gt;

&lt;h4&gt;
  
  
  Database
&lt;/h4&gt;

&lt;p&gt;Databases can be divided into seven types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Relational: RDS&lt;/li&gt;
&lt;li&gt;  Key-Value: DynamoDB, or maybe even Redis&lt;/li&gt;
&lt;li&gt;  Document: DocumentDB&lt;/li&gt;
&lt;li&gt;  In-Memory: ElastiCache, MemoryDB (new)&lt;/li&gt;
&lt;li&gt;  Graph: Neptune&lt;/li&gt;
&lt;li&gt;  Time-Series: Timestream&lt;/li&gt;
&lt;li&gt;  Ledger: QLDB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each type of database will be used for different purposes, but sometimes it is not too noticeable.&lt;/p&gt;

&lt;p&gt;E.g., Customers using MySQL on-premises does not mean that going to AWS is required to use RDS. That's also just an option. Another option could be MySQL on EC2 instance, converting MySQL to DynamoDB.&lt;/p&gt;

&lt;p&gt;If you want a database with high access frequency low latency, it can be DynamoDB, but if the data is not too necessary, ElastiCache is also a good choice.&lt;/p&gt;

&lt;p&gt;In general, the database selection problem is not too complex. Usually, the question will revolve around the issue of optimizing a particular type of database.&lt;/p&gt;

&lt;p&gt;E.g., the customer is using MySQL on RDS and is noticing slow response as traffic increases. Think about multi-writer, multi-reader, and maybe even ElastiCache to reduce RDS load.&lt;/p&gt;

&lt;p&gt;Refer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.youtube.com/watch?v=q81TVuV5u28&amp;amp;ref=wellarchitected"&gt;AWS re:Invent 2019: Leadership session: AWS purpose-built databases (DAT209-L)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Network
&lt;/h4&gt;

&lt;p&gt;All AWS components are connected through a network, AWS's private network, or the internet.&lt;/p&gt;

&lt;p&gt;EC2 instances connect to EBS through the internal network; Route53, CloudFront, S3 in/out internet; the connection between AWS and on-premises... In this regard, there are several standard solutions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  CloudFront can reduce latency when accessing global&lt;/li&gt;
&lt;li&gt;  Deploying (adding a system) on a region near the user is also the best way to reduce latency&lt;/li&gt;
&lt;li&gt;  Upload/Download on S3 is slow: Use S3 transfer acceleration&lt;/li&gt;
&lt;li&gt;  Connecting to On-premises using VPN is slow: Spend more money to use Direct Connect&lt;/li&gt;
&lt;li&gt;  Latency-Based Routing in Amazon Route 53&lt;/li&gt;
&lt;li&gt;  Use VPC Endpoints to use AWS's internal network
Refer&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_1.en.html"&gt;PERF 1: How do you select the best performing architecture?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_2.en.html"&gt;PERF 2: How do you select your compute solution?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_3.en.html"&gt;PERF 3: How do you select your storage solution?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_4.en.html"&gt;PERF 4: How do you select your database solution?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_5.en.html"&gt;PERF 5: How do you configure your networking solution?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_6.en.html"&gt;PERF 6: How do you evolve your workload to take advantage of new releases?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_7.en.html"&gt;PERF 7: How do you monitor your resources to ensure they are performing?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.question.PERF_8.en.html"&gt;PERF 8: How do you use tradeoffs to improve performance?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wat.pillar.performance.en.html"&gt;Performance Efficiency&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.  Cost
&lt;/h3&gt;

&lt;p&gt;Usually, there are two scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Customers already have the system and want to reduce the price&lt;/li&gt;
&lt;li&gt;  Customers want to migrate to AWS for the lowest possible price.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So how to optimize the price:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Choose cheaper services. When to use Kinesis instead of SQS? When to use a VPN instead of Direct Connect? When to use Spot Instances?&lt;/li&gt;
&lt;li&gt;  Remove unnecessary resources.&lt;/li&gt;
&lt;li&gt;  Commitment: Savings Plans, Reserved Instances&lt;/li&gt;
&lt;li&gt;  Cost Management: Consolidated Billing, Cost Allocation Tags, Trust Advisor,...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And finally, remember, optimizing for price also comes at the expense of other things (performance, availability, reliability, security, etc.). The architecture you choose may not be perfect, but it is still the correct answer if it is feasible and the most cost-effective according to the customer's requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.  Operational Excellence
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;"The Operational Excellence pillar includes the ability to support development and run workloads effectively, gain insight into their operations, and to continuously improve supporting processes and procedures to deliver business value"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It depends on services, but there are some common aspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Infrastructure as code: in short, CloudFormation, Opsworks. You don't need to understand what Ansible or Puppet is, but you should know what Opsworks is and what it is suitable for. You also don't need to master the CloudFormation template, but you must know some basic syntax and create some services by CloudFormation, such as VPC, Subnets, RDS...&lt;/li&gt;
&lt;li&gt;  Basic settings: some services have unique settings you must be familiar. E.g.: could I change Lambda CPU configuration? Restore an RDS snapshot, make a failover on an RDS instance? Change Launch Template, etc.&lt;/li&gt;
&lt;li&gt;  Monitoring, Incident response: logging, metric visualizer, alarms, incident management, and remediation&lt;/li&gt;
&lt;li&gt;  Some managed operator services: there are some services you should get to know, such as CloudTrail, Config, Personal Health Dashboard, Organizations, Service Catalog, Systems Manager.
Refer&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.pillar.operationalExcellence.en.html"&gt;https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.pillar.operationalExcellence.en.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Don't trust keywords
&lt;/h3&gt;

&lt;p&gt;When taking the exam, many of you will have a trick that believes in the keyword, see this keyword, and immediately decide. But here, things are not so clear. If you insist on choosing the most appropriate service, it is easy to lead you to the wrong architecture because this is a collection of services and methods, not a story of just one service.&lt;/p&gt;

&lt;p&gt;E.g., When a customer needs a Relational database, RDS comes to mind, but don't forget you could also use EC2 and launch the database on its instance. Why does it? Because of the cost, there are features of the database that RDS does not support.&lt;/p&gt;

&lt;p&gt;When customers think of storing static data, you think of S3. But, saving in EBS, EFS is also away.&lt;/p&gt;

&lt;p&gt;When facing a problem, the answers will gather a lot of services and methods to solve it. Your job is to choose the most suitable plan, only the most appropriate service is not enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do what customers ask
&lt;/h3&gt;

&lt;p&gt;There are widespread errors I have encountered. Each question will present many problems, and you must focus on only some of them: What the customer wants. These could be requests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  How to optimize price?&lt;/li&gt;
&lt;li&gt;  How to reduce latency?&lt;/li&gt;
&lt;li&gt;  How to shorten the processing time?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why is it a problem? Because the content of the question will be very rambling and make you think of its request in the wrong way.&lt;/p&gt;

&lt;p&gt;E.g., The customer has a website deployed in region us-east-1, using EC2 instance and Application Load Balancer, Auto Scaling Group. The website has about 1 million users worldwide. Customers find that users accessing from Asia will experience significant latency. Ask how to optimize the price?&lt;/p&gt;

&lt;p&gt;You can think of CloudFront with global access, high latency, and optimal price. However, CloudFront is not price-optimized too much, sometimes even increasing costs, while customer requirements are price-optimized. So you have to think about Spot Instances, Reserved Instances. So, your job is to choose the answer to the question, don't let other things distract you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time management
&lt;/h3&gt;

&lt;p&gt;You have 170 minutes (or 200 minutes if you request as ESL) to solve 75 questions. However, the topic is very long. Furthermore, to the pressure of the exam, it is easy to get immersed in some difficult questions and waste a lot of time. Try to practice solving each question within 2 or 2.5 minutes. I will review the sentences marked with review the rest of the time.&lt;/p&gt;

&lt;p&gt;Also, do not mark the review too many. Should only keep the check under 20 sentences. For questions you don't know or think you can't answer, answer indiscriminately and don't look back; spend your precious time on questions that are more likely to earn points.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclude
&lt;/h2&gt;

&lt;p&gt;The AWS Certified Solutions Architect --- Professional exam is challenging. You need a solid determination to overcome. But whether you pass or not, it doesn't matter; what matters is that you will gain various knowledge, which will help you in a real career path.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>sapc01</category>
      <category>certification</category>
    </item>
    <item>
      <title>Spring Boot project using AWS RDS and Secrets Manager</title>
      <dc:creator>luan vu</dc:creator>
      <pubDate>Sat, 22 Jan 2022 08:54:40 +0000</pubDate>
      <link>https://forem.com/luanvu/spring-boot-project-using-aws-rds-and-secrets-manager-1kc4</link>
      <guid>https://forem.com/luanvu/spring-boot-project-using-aws-rds-and-secrets-manager-1kc4</guid>
      <description>&lt;p&gt;In this article, I will show you how to integrate Amazon RDS connection information into a Spring project using AWS Secrets Manager.&lt;/p&gt;

&lt;p&gt;With traditional Spring projects, we tend to configure the data source directly inside the source code. In different environments (development, staging, production), it is common to use Spring profiles to change these parameters. This solution is convenient, but it lacks security (credentials explosion, inability to access manager), difficult to manage and change (password rotation policy).&lt;/p&gt;

&lt;p&gt;AWS offers a solution using &lt;a href="https://aws.amazon.com/secrets-manager/" rel="noopener noreferrer"&gt;AWS Secrets Manager&lt;/a&gt; integration with RDS and &lt;a href="https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html" rel="noopener noreferrer"&gt;Rotating Secrets&lt;/a&gt;, simplifying management and ensuring security. Refer to &lt;a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_BestPractices.Security.html" rel="noopener noreferrer"&gt;Security best practices for Amazon RDS&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are 2 simple steps to integrate RDS data source and Spring Boot project using AWS Secrets Manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1. Add this dependency in pom.xml file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.amazonaws.secretsmanager&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;aws-secretsmanager-jdbc&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.5&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2. Change data source configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;spring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;datasource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jdbc-secretsmanager:mysql://database-host:3306/rdsdb&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rdsrotation&lt;/span&gt;
    &lt;span class="na"&gt;driver-class-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;com.amazonaws.secretsmanager.sql.AWSSecretsManagerMySQLDriver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  url: it has a prefix &lt;em&gt;jdbc-secretsmanager&lt;/em&gt; instead of just &lt;em&gt;jdbc&lt;/em&gt; as usual&lt;/li&gt;
&lt;li&gt;  username: &lt;em&gt;Secret Name&lt;/em&gt; which you’ve got in AWS Secrets Manager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The magic here is that &lt;em&gt;driver-class-name&lt;/em&gt; is &lt;em&gt;AWSSecretsManagerMySQLDriver.&lt;/em&gt; It is the AWS Secrets Manager Driver driver which wraps the original driver (for instance &lt;em&gt;com.mysql.cj.jdbc.Driver&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Some databases and corresponding drivers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;MySQL&lt;/strong&gt;: &lt;em&gt;AWSSecretsManagerMySQLDriver&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;MariaDB&lt;/strong&gt;: &lt;em&gt;AWSSecretsManagerMariaDBDriver&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Oracle DB&lt;/strong&gt;: &lt;em&gt;AWSSecretsManagerOracleDriver&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;PostgreSQL&lt;/strong&gt;: &lt;em&gt;AWSSecretsManagerPostgreSQLDriver&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;MSSQL&lt;/strong&gt;: &lt;em&gt;AWSSecretsManagerMSSQLServerDriver&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a &lt;a href="https://github.com/luanvuhlu/rds-secrets-sample" rel="noopener noreferrer"&gt;GitHub link&lt;/a&gt; to this implementation.&lt;/p&gt;

&lt;p&gt;So it’s done. Now you can use Spring data source normally. You can rotate your password automatically every day, every month in AWS Secrets Manager and your program will still work as you expected without restarting every time you change the password.&lt;/p&gt;

&lt;p&gt;But How? If you need to understand in more detail how it works, continue to follow below.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it work
&lt;/h2&gt;

&lt;p&gt;When the program needs a JDBC connection, the java.sql.Driver#&lt;em&gt;connect&lt;/em&gt; function is called. Instead of retrieving an existing username/password, the Driver wrapper (eg AWSSecretsManagerMySQLDriver) will call into the AWS Secrets Manager to retrieve the username/password.&lt;/p&gt;

&lt;p&gt;The problem is that you have to calls the AWS Secrets Manager API every time you use the connection, it will take time and cost a lot(AWS Secrets Manager charges by the number of API calls). So, the better way is to cache and reuse username/password next time instead of calling AWS Secrets Manager.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthg03hvakcbyjdiuwhrb.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthg03hvakcbyjdiuwhrb.jpeg" alt="JDBC Driver acquires a connection diagram"&gt;&lt;/a&gt;&lt;br&gt;
If the cached has expired (default is 1 hour), the driver will continue to call into AWS Secrets Manager to retrieve the username/password (can be new or old).&lt;/p&gt;

&lt;p&gt;So what if the cached has not expired but the username/password in AWS Secrets Manager(also in RDS of course) has been changed? Driver uses fallback mechanism. It doesn’t know credentials are changed, so it continuous connects to database using the existing username/password (in the cached), if the database returns an error indicating the wrong username/password, call AWS Secrets Manager to get the new username/password.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fieq3k06fy0tjos2r05kv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fieq3k06fy0tjos2r05kv.jpeg" alt="JDBC Driver acquires a connection diagram"&gt;&lt;/a&gt;&lt;br&gt;
And that’s it. Above is the guide on how to integrate Amazon RDS and AWS Secrets Manager into Spring Boot project. This method is not limited to Spring but can be used with any Java project that uses JDBC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;=========&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_BestPractices.Security.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_BestPractices.Security.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://dzone.com/articles/spring-boot-handle-aws-rds-password-change-or-rota" rel="noopener noreferrer"&gt;https://dzone.com/articles/spring-boot-handle-aws-rds-password-change-or-rota&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/aws/aws-secretsmanager-jdbc" rel="noopener noreferrer"&gt;https://github.com/aws/aws-secretsmanager-jdbc&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://aws.amazon.com/blogs/security/use-aws-secrets-manager-client-side-caching-libraries-to-improve-the-availability-and-latency-of-using-your-secrets/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/security/use-aws-secrets-manager-client-side-caching-libraries-to-improve-the-availability-and-latency-of-using-your-secrets/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>aws</category>
      <category>jdbc</category>
      <category>spring</category>
    </item>
    <item>
      <title>10 syntax in Java You should know</title>
      <dc:creator>luan vu</dc:creator>
      <pubDate>Sat, 08 Jan 2022 09:11:47 +0000</pubDate>
      <link>https://forem.com/luanvu/10-syntax-in-java-you-should-know-1e2h</link>
      <guid>https://forem.com/luanvu/10-syntax-in-java-you-should-know-1e2h</guid>
      <description>&lt;h3&gt;
  
  
  1. Underscore in Numeric Literals
&lt;/h3&gt;

&lt;p&gt;You have to write dozen of numbers to present a number of millions, billions and even more. You always must count it again and again to make sure the number is correct. Actually, you could place some underscore inside the number to make it clear, like you use comma in real life.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;noUnderscore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100000000000&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;withUnderscore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100_000_000_000&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer: &lt;a href="https://docs.oracle.com/javase/8/docs/technotes/guides/language/underscores-literals.html"&gt;Underscores in Numeric Literals&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Pattern.asPredicate
&lt;/h3&gt;

&lt;p&gt;When use java.util.regex.Pattern with Stream API, I feel uncomfortable when I have to create a Matcher, and then use that matcher to test whether my text is matched the pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;validEmails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;EMAIL_REGEX&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matcher&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;find&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;  
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have no idea why Java make it so complex for such a simple thing. Anyway, Java provides a way to shorten the code and make it more clear. That’s Pattern.asPredicate&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;validEmails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;emails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;EMAIL_REGEX&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asPredicate&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;  
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#asPredicate--"&gt;Oracle docs Pattern.html#asPredicate&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Named RegEx Capturing Group
&lt;/h3&gt;

&lt;p&gt;When I need extract multiple information in texts with single Pattern. I have to use java.util.regex.Matcher#group and I usually pass the index of a capturing group in its pattern. The indexes always confuse me. So, you should place a named group to easily extract it by name, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pattern&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;  
        &lt;span class="s"&gt;"^Today is (?&amp;lt;month&amp;gt;\\\\w+) (?&amp;lt;day&amp;gt;\\\\d+), (?&amp;lt;year&amp;gt;\\\\d+)"&lt;/span&gt;  
&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;matcher&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Today is August 4, 2026"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"month"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;  
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"day"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;  
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#special"&gt;Oracle docs Pattern.html#special&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Arrays.asList
&lt;/h3&gt;

&lt;p&gt;Need to create a List inline. The fastest way is use Arrays.asList&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;singletonList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Just me"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beware: the list is returned is a fixed-size (but mutable) list.&lt;br&gt;
Refer: &lt;a href="https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#singleton(T)"&gt;Oracle docs Collections.html#singleton(T)&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  5. Collections.singleton*
&lt;/h3&gt;

&lt;p&gt;Do you know an ArrayList, a HashSet or a HashMap instance wastes plenty of memory even when you just need to store a single item. They need an array to store data, and int value to store real size and a HashMap (lol)&lt;br&gt;
If you need a collection to store the single item, you should use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collections.singleton to create a Set&lt;/li&gt;
&lt;li&gt;Collections.singletonList to create a List&lt;/li&gt;
&lt;li&gt;Collections.singletonMap to create a Map
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;singletonSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;singleton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;singletonList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;singletonList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;singletonMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;singletonMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"version"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It’s a simple but very effective.&lt;/p&gt;

&lt;p&gt;Refer: &lt;a href="https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#singleton(T)"&gt;Oracle docs Collections#singleton&lt;/a&gt;)&lt;/p&gt;
&lt;h3&gt;
  
  
  6. Collections.empty*
&lt;/h3&gt;

&lt;p&gt;Stop returning null value as a collection, return an empty collection instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getValidEmails&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Collections&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emptyList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;  
    &lt;span class="o"&gt;}&lt;/span&gt;  
    &lt;span class="o"&gt;...&lt;/span&gt;  
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;emptyList&lt;/li&gt;
&lt;li&gt;emptyMap&lt;/li&gt;
&lt;li&gt;emptySet&lt;/li&gt;
&lt;li&gt;emptyIterator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And more, use them.&lt;br&gt;&lt;br&gt;
Refer: &lt;a href="https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#emptyList()"&gt;Oracle docs Collections emptyList&lt;/a&gt;)&lt;/p&gt;
&lt;h3&gt;
  
  
  7. Objects equality check
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gameA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"The Legend of Zelda: Breath of the Wild"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gameB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Monster Hunter Rise"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameB&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Am I seriously? Why don’t I use equals method to solve a simple thing. Well, what happened if either gameA or gameB is null? I would get an &lt;em&gt;NullPointerException&lt;/em&gt; if I have a bad luck.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gameA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gameB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Monster Hunter Rise"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameB&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;  
&lt;span class="c1"&gt;// =&amp;gt; Exception in thread "main" java.lang.NullPointerException&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can avoid it by using Objects.equals, it does work no matter either gameA or gameB is null.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gameA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;gameB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Monster Hunter Rise"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameA&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gameB&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer: &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/Objects.html#equals-java.lang.Object-java.lang.Object-"&gt;Oracle docs Objects&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  8. List.of, Set.of and Map.of (since 9)
&lt;/h3&gt;

&lt;p&gt;Do you prefer Functional Programming, and love immutable objects? Creating a immutable collection class by yourself could be challenging. Well, Java provides Unmodifiable Lists, Unmodifiable Sets, Unmodifiable Maps which basically are immutable classes.&lt;/p&gt;

&lt;p&gt;For example, Unmodifiable Lists have some characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are unmodifiable. Elements cannot be added, removed, or replaced. Calling any mutator method on the List will always cause UnsupportedOperationException to be thrown. However, if the contained elements are themselves mutable, this may cause the List's contents to appear to change.&lt;/li&gt;
&lt;li&gt;They disallow null elements. Attempts to create them with null elements result in NullPointerException.&lt;/li&gt;
&lt;li&gt;They are serializable if all elements are serializable.&lt;/li&gt;
&lt;li&gt;The order of elements in the list is the same as the order of the provided arguments, or of the elements in the provided array.&lt;/li&gt;
&lt;li&gt;They are value-based. Callers should make no assumptions about the identity of the returned instances. Factories are free to create new instances or reuse existing ones. Therefore, identity-sensitive operations on these instances (reference equality (==), identity hash code, and synchronization) are unreliable and should be avoided.&lt;/li&gt;
&lt;li&gt;They are serialized as specified on the Serialized Form page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer: &lt;a href="https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/List.html#unmodifiable"&gt;Oracle docs List unmodifiable&lt;/a&gt;&lt;br&gt;&lt;br&gt;
To create an unmodifiable lists, use can use List.of&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="nf"&gt;of&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="err"&gt;​&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;E&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="err"&gt;​&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;E&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="err"&gt;​&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;E&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;E&lt;/span&gt; &lt;span class="n"&gt;e2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="err"&gt;​&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;E&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;E&lt;/span&gt; &lt;span class="n"&gt;e2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;E&lt;/span&gt; &lt;span class="n"&gt;e3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;…&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It sounds like Arrays.asList, but instead of a mutable list, List.of creates an immutable list and it doesn’t accept null values.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Comparator and null
&lt;/h3&gt;

&lt;p&gt;In the past, I didn’t noticed that Comparator don’t work with null value by default.&lt;br&gt;
For example, the code will throw a NullPointerException&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;naturalOrder&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;  
&lt;span class="c1"&gt;// ==&amp;gt; Exception in thread "main" java.lang.NullPointerException&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used to code like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
    &lt;span class="o"&gt;}&lt;/span&gt;  
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;  
    &lt;span class="o"&gt;}&lt;/span&gt;  
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compareTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="o"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luckily, there are two simple methods resolve my problem. They are Comparator.nullsFirst and Comparator.nullsLast&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  
&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nullsFirst&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Comparator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;naturalOrder&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;  
&lt;span class="c1"&gt;// [null, null, -1, 1, 2]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10. Predicate::not (since 11)
&lt;/h3&gt;

&lt;p&gt;Stream API is good, filter is great and Predicate is awesome, but have you ever written something like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;games&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;game&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nc"&gt;Strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isNullOrEmpty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;  
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fortunately, Java 11 save you from that ugly code by &lt;em&gt;Predicate.not&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;games&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;  
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Predicate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Strings:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;isNullOrEmpty&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;  
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
    </item>
  </channel>
</rss>
