<?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>DEV Community: Khadija Ashraf</title>
    <description>The latest articles on DEV Community by Khadija Ashraf (@khadijaashraf).</description>
    <link>https://dev.to/khadijaashraf</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%2F2933358%2F2dfabbc3-7515-404a-b89e-79c07fab67f4.jpeg</url>
      <title>DEV Community: Khadija Ashraf</title>
      <link>https://dev.to/khadijaashraf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/khadijaashraf"/>
    <language>en</language>
    <item>
      <title>Unfolding: LeetCode 560. Subarray Sum Equals K</title>
      <dc:creator>Khadija Ashraf</dc:creator>
      <pubDate>Thu, 22 May 2025 04:45:21 +0000</pubDate>
      <link>https://dev.to/khadijaashraf/unfolding-560-subarray-sum-equals-k-1kkk</link>
      <guid>https://dev.to/khadijaashraf/unfolding-560-subarray-sum-equals-k-1kkk</guid>
      <description>&lt;p&gt;A disguised &lt;code&gt;medium&lt;/code&gt; difficulty problem in LeetCode. We must honor this as a &lt;code&gt;hard&lt;/code&gt; one... :) &lt;a href="https://github.com/khadija-ashraf/LeetCodePopular/blob/main/src/hashtable/prefixSum/SubArraySumEqualsK.java" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://leetcode.com/problems/subarray-sum-equals-k/description/" rel="noopener noreferrer"&gt;560. Subarray Sum Equals K&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k.&lt;/p&gt;

&lt;p&gt;A subarray is a contiguous non-empty sequence of elements within an array.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example 1:

Input: nums = [1,1,1], k = 2
Output: 2
Example 2:

Input: nums = [1,2,3], k = 3
Output: 2


Constraints:

1 &amp;lt;= nums.length &amp;lt;= 2 * 104
-1000 &amp;lt;= nums[i] &amp;lt;= 1000
-107 &amp;lt;= k &amp;lt;= 107
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Approach 1: Brute Force
&lt;/h2&gt;

&lt;p&gt;Brute Force: Generate every possible sub array &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Algorithm:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize a variable count = 0 to keep track of the number of subarrays with sum equal to k.&lt;/li&gt;
&lt;li&gt;for every index in the input array consider the index as &lt;code&gt;i&lt;/code&gt; index of a sub array&lt;/li&gt;
&lt;li&gt;for each &lt;code&gt;i&lt;/code&gt; index Loop through the array from &lt;code&gt;i&lt;/code&gt; index to &lt;code&gt;n - 1&lt;/code&gt; using index &lt;code&gt;j&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;nums[j]&lt;/code&gt; to sum&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;sum == k&lt;/code&gt;, increment count&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;after both loops complete, return count.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Example all possible subarray of Input: {1, -1, 2, 1, 1, -2, 2}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-&amp;gt; i = 0, j = i ... len(nums)
(1), (1,-1), (1,-1, 2), (1, -1, 2, 1), (1,-1, 2, 1, 1), (1,-1, 2, 1, 1, -2), (1,-1, 2, 1, 1, -2, 2)

-&amp;gt; i = 1, j = i ... len(nums)
(-1), (-1, 2), (-1, 2, 1), (-1, 2, 1, 1), (-1, 2, 1, 1, -2), (-1, 2, 1, 1, -2, 2)

so on..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;subarraySum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&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="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sum&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="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&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;sum&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;count&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="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;count&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;All the k-sum subarrays for k = 2, in the given input array,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inputs : 0, 1,-1, 2, 1, 1,-2, 2&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;prefix :  0, 1, 0, 2, 3, 4, 2, 4&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;index [1,3] : (1,-1,2)&lt;/li&gt;
&lt;li&gt;index [3,3] : (2)&lt;/li&gt;
&lt;li&gt;index [2,4] : (-1,2,1)&lt;/li&gt;
&lt;li&gt;index [3,6] : (2,1,1,-2)&lt;/li&gt;
&lt;li&gt;index [4,7] : (1,1,-2,2)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Time &amp;amp; Space:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Time O(n^2): check all subarrays, and there are roughly n(n+1)/2 subarrays.&lt;/li&gt;
&lt;li&gt;Space O(1): using only a few variables, no extra data structures.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Approach 2:  Prefix Sum
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Key Concept and Algorithm:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Intuition: "As you move forward, keep looking behind to check if the numbers you’ve summed so far equals to K."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;We traverse the input array from left towards right. While traversing we calculate the prefix sum for every index. Prefix sum is the running sum of every index position on the input array. Either we can maintain a new separate array for prefix sums or we can modify the input array itself if allowed. In this problem we are storing the prefixes in a new array.&lt;/li&gt;
&lt;li&gt;We traverse the prefix array from left to right. The idea is, in every index we ask, does this currenPrefixSum (current index position's prefixSum) already contains the sum of one/more subarray summing to k?&lt;/li&gt;
&lt;li&gt;To check this, we go k amount backwards by subtracting the amount 'k' from the currentPrefixSum. This subtracted value is the complementPrefixSum.&lt;/li&gt;
&lt;li&gt;complementPrefixSum is a number that is 'k' less than the currentPrefixSum in the prefixsum array.&lt;/li&gt;
&lt;li&gt;Then we check every index from the beginning until the current index of the prefix sum array to find any complementPrefixSum == (currentPrefixSum-k),&lt;/li&gt;
&lt;li&gt;If we find, than we have got a sub array that resides between the complementPrefixSum and the currentPrefixSum and this subarray is k-sum amount.&lt;/li&gt;
&lt;li&gt;So, currentPrefixSum - complementPrefixSum = k or, we can re-write, currentPrefixSum - k = complementPrefixSum
&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="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;subarraySumPrefixSum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;prefixSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&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;int&lt;/span&gt; &lt;span class="n"&gt;count&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="n"&gt;prefixSum&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="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;prefixSum&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;prefixSum&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="c1"&gt;// prefix-sum until position 'i'&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentPrefixSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prefixSum&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;complementSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;currentPrefixSum&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&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="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&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;prefixSum&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;complementSum&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;count&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="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;count&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;For example:&lt;/p&gt;

&lt;p&gt;Now, we demonstrate a portion of the algorithm execution. Note that, we traverse the precalculated prefix array.&lt;/p&gt;

&lt;p&gt;The k-sum subarray count for k = 2, in the given input array,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;indexs : 0, 1, 2, 3, 4, 5, 6 ,7&lt;/li&gt;
&lt;li&gt;inputs : 0, 1,-1, 2, 1, 1,-2, 2&lt;/li&gt;
&lt;li&gt;prefix : 0, 1, 0, 2, 3, 4, 2, 4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dry Run for Prefix index 4: we ask, does this currenPrefixSum already contains the sum of one/more subarray summing to k?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prefix[4] - k = 3-2 =&amp;gt; 1. This '1' is the &lt;code&gt;complementPrefixSum&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;if we can find this complementPrefixSum in the prefix array starting from index 0 until index 4, then we can say atleast a subarray exists of sum-k between the complementPrefixSum and the currentPrefixSum. if we find the complementPrefixSum more than once we count all of them as separate k-sum subarrays.&lt;/li&gt;
&lt;li&gt;we find prefix[1] == 1, which is equal to complementPrefixSum. therefore we found one k-sum subarray between inputs[1] and inputs[4].&lt;/li&gt;
&lt;li&gt;Verification: The subarray starts at index &lt;code&gt;2&lt;/code&gt; and ends at &lt;code&gt;4&lt;/code&gt;, thus the index range is [2,4] and the values subarray values are (-1, 2, 1) = -1+2+1 = 2 = k.&lt;/li&gt;
&lt;li&gt;since we found a complementSum in the prefix array so we increase the total number of k-sum subarray count.&lt;/li&gt;
&lt;li&gt;There is no more complementPrefixSum == 1 found until the current index in the prefix array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dry Run for prefix index 5: we ask, does this currenPrefixSum already contains the sum of one/more subarray summing to k?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prefix[5] - k = 4-2 =&amp;gt; 2. This '2' is the &lt;code&gt;complementPrefixSum&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;if we can find this complementPrefixSum in the prefix array starting from index 0 until index 5, then we can say atleast a subarray exists of sum-k between the complementPrefixSum and the currentPrefixSum. if we find the complementPrefixSum more than once we count all of them as separate k-sum subarrays.&lt;/li&gt;
&lt;li&gt;we find prefix[3] == 2, which is equal to complementPrefixSum. therefore we found one k-sum subarray between inputs[3] and inputs[5].&lt;/li&gt;
&lt;li&gt;Verification: The subarray starts at index &lt;code&gt;4&lt;/code&gt; and ends at &lt;code&gt;5&lt;/code&gt;, thus the index range is [4,5] and the subarray values are (1, 1) = 1+1 = 2 = k.&lt;/li&gt;
&lt;li&gt;since we found a complementSum in the prefix array so we increase the total number of k-sum subarray count.&lt;/li&gt;
&lt;li&gt;There is no more complementPrefixSum == 2 found until the current index in the prefix array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dry Run for prefix index 6: we ask, does this currenPrefixSum already contains the sum of one/more subarray summing to k&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prefix[6] - k = 2-2 =&amp;gt; 0. This '0' is the &lt;code&gt;complementPrefixSum&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If we can find this complementPrefixSum in the prefix array starting from index 0 until index 6, then we can say atleast a subarray exists of sum-k between the complementPrefixSum and the currentPrefixSum. If we find the complementPrefixSum more than once we count all of them as separate k-sum subarrays.&lt;/li&gt;
&lt;li&gt;We find prefix[0] == 0, which is equal to complementPrefixSum. Therefore we found one k-sum subarray between inputs[0] and inputs[6].&lt;/li&gt;
&lt;li&gt;Verification: The subarray starts at index &lt;code&gt;1&lt;/code&gt; and ends at &lt;code&gt;6&lt;/code&gt;, thus the index range is [1,6] and the subarray values are (1,-1, 2, 1, 1,-2) = 1+(-1)+2+1+1+(-2) = 2 = k.&lt;/li&gt;
&lt;li&gt;Since we found a complementSum in the prefix array so we increase the total number of k-sum subarray count.&lt;/li&gt;
&lt;li&gt;There is no more complementPrefixSum == 0 found until the current index in the prefix array.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dry Run for prefix index 7: we ask, does this currenPrefixSum already contains the sum of one/more subarray summing to k?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prefix[7] - k = 4-2 =&amp;gt; 2. This '2' is the &lt;code&gt;complementPrefixSum&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If we can find this complementPrefixSum in the prefix array starting from index 0 until index 7, then we can say atleast a subarray exists of sum-k between the complementPrefixSum and the currentPrefixSum. If we find the complementPrefixSum more than once we count all of them as separate k-sum subarrays.&lt;/li&gt;
&lt;li&gt;We find prefix[3] == 2, which is equal to complementPrefixSum. Therefore we found one k-sum subarray between inputs[3] and inputs[7].&lt;/li&gt;
&lt;li&gt;Verification: The subarray starts at index &lt;code&gt;4&lt;/code&gt; and ends at &lt;code&gt;7&lt;/code&gt;, thus the index range is [4,7] and the subarray values are (1, 1,-2, 2) = 1+1+(-2)+2 = 2 = k.&lt;/li&gt;
&lt;li&gt;Since we found a complementSum in the prefix array so we increase the total number of k-sum subarray count.&lt;/li&gt;
&lt;li&gt;Wait, we still have to scan the prefix array until the current index 7. While scanning forward, we found one more (complementPrefixSum == 2) at the index 6.&lt;/li&gt;
&lt;li&gt;We find prefix[6] == 2, which is equal to complementPrefixSum. Therefore we found one more k-sum subarray between inputs[6] and inputs[7].&lt;/li&gt;
&lt;li&gt;Verification: The subarray starts at index &lt;code&gt;7&lt;/code&gt; and ends at &lt;code&gt;7&lt;/code&gt;, thus the index range is [7,7] and the subarray values are (2) = k.&lt;/li&gt;
&lt;li&gt;Since we found one more complementPrefixSum in the prefix array so again we increase the total number of k-sum subarray count.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Time &amp;amp; Space:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Time O(n^2): check all previous prefixes until the current index&lt;/li&gt;
&lt;li&gt;Space O(n): using an extra array of size n for storing prefixes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Approach 3:  Prefix Sum + HashMap (optimized Time O(n))
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Key Concept and Algorithm:
&lt;/h3&gt;

&lt;p&gt;In the approach 2: Prefix Sum we used an array for storing our prefixes. There is a performance drain when we have to lookup for a complemenPrefixSum. We have to scan the prefix array until the current index to find if there is a prefix already in the map that matches the complemenPrefixSum. This is an average O(n) operation.&lt;/p&gt;

&lt;p&gt;To enhance the performance we can keep our prefixes in a HashMap. Then looking up for a complemenPrefixSum in that map would be a O(1) operation. We store the frequency of the prefixes so that we get the total number of occurrences of that prefix in the prefix array. The frequency of prefix is added to the k-sum subarray count when the prefix of that position matches to a complemenPrefixSum.&lt;/p&gt;

&lt;p&gt;Though for an all positive input array the prefix always increases from left to right.&lt;/p&gt;

&lt;p&gt;However, note that, since this problem allows negative numbers, therefor we might have duplicate prefixes in the prefix array. &lt;br&gt;
For example the input array mentioned under Approach 2, has prefix &lt;code&gt;2&lt;/code&gt; at both index 3, and 6. Because, the negative numbers at index 2 and 6 are bringing the prefix down. So at some point we might find duplicate prefix values in the array.&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;subarraySumPrefixSumHashMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currentPrefixSum&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="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&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="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&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="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;currentPrefixSum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// prefix-sum until position 'i'&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;complementSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;currentPrefixSum&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;k&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;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;complementSum&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;complementSum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentPrefixSum&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOrDefault&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentPrefixSum&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;return&lt;/span&gt; &lt;span class="n"&gt;count&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;In this implementation we initialize the map(key=0, val=1), intuition behind is, the prefix of an empty array is 0, and it occurs at least 1 time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time &amp;amp; Space:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Time O(n): traverses the prefix array once O(n), for every index the hashMap lookup is O(1) operation.&lt;/li&gt;
&lt;li&gt;Space O(n): using a HashMap of size n (worst case) for storing prefixes.&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>hashmap</category>
      <category>leetcode</category>
      <category>notslidingwindow</category>
      <category>prefixsum</category>
    </item>
    <item>
      <title>Data Structure &amp; Algorithm: Merge Sort</title>
      <dc:creator>Khadija Ashraf</dc:creator>
      <pubDate>Wed, 19 Mar 2025 17:12:02 +0000</pubDate>
      <link>https://dev.to/khadijaashraf/data-structure-algorithm-merge-sort-21jb</link>
      <guid>https://dev.to/khadijaashraf/data-structure-algorithm-merge-sort-21jb</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;u&gt;Recursive Algorithm:&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Step 1: find the mid index of the array&lt;/li&gt;
&lt;li&gt;Step 2: go for sorting left half&lt;/li&gt;
&lt;li&gt;Step 3: go for sorting right half&lt;/li&gt;
&lt;li&gt;Step 4: merge the left and right half, sorting is done during merging &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source Code Repository: &lt;a href="https://github.com/khadija-ashraf/data-structure-algorithm/blob/main/src/com/sorting/MergeSort.java" rel="noopener noreferrer"&gt;https://github.com/khadija-ashraf/data-structure-algorithm/blob/main/src/com/sorting/MergeSort.java&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we analyze the order of the steps in this recursive algorithm then, we see that, we keep slicing the array until no more slicing can be done, follow steps 1, 2, 3. No sorting is done in this slicing period. Only when the sliced array reaches to zero or 1 elements then we return from slicing and starting merging in the step 4.&lt;/p&gt;

&lt;p&gt;Since the the Step 2 executes before the Step 3 therefore the left part of the array will be sliced until it reaches to 1-element arrays, then the sort-and-merge will execute on the left side of the recursive tree, upon return from the left subtree the right subtree sort-and-merge will be executed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
public class MergeSort {
    public void sort(int[] arr, int left, int right) {
        if(left &amp;lt; right) {
            int midIndex = left + (right - left) / 2;

            sort(arr, left, midIndex);
            sort(arr, midIndex+1, right);

            merge(arr, left, midIndex, right);
        }
    }

    public void merge(int[] arr, int left, int midIndex, int right) {
        int leftArraySize = midIndex - left + 1;
        int rightArraySize = right - midIndex;

        int[] leftTempArr = new int[leftArraySize];
        int[] rightTempArr = new int[rightArraySize];

        for(int i = 0; i &amp;lt; leftArraySize; i++) {
            leftTempArr[i] = arr[left + i];
        }

        for(int i = 0; i &amp;lt; rightArraySize; i++) {
            rightTempArr[i] = arr[midIndex + 1 + i];
        }

        // merge

        int i = 0; 
        int j = 0; 
        int k = left;

        while(i &amp;lt; leftArraySize &amp;amp;&amp;amp; j &amp;lt; rightArraySize) {
            if(leftTempArr[i] &amp;lt;= rightTempArr[j]) {
                arr[k] = leftTempArr[i];
                i++;
            } else {
                arr[k] = rightTempArr[j];
                j++;
            }
            k++;
        }

        while(i &amp;lt; leftArraySize) {
            arr[k] = leftTempArr[i];
            i++;
            k++;
        }

        while(j &amp;lt; rightArraySize) {
            arr[k] = rightTempArr[j];
            j++;
            k++;
        }

    }

    public void print(int[] arr) {
        for(int n: arr) {
            System.out.print(n + ", ");
        }
    }

    public static void main(String a[]) {
        MergeSort ob = new MergeSort();

        int[] arr = {4,7,1,8,3,8,9};

        ob.sort(arr, 0, arr.length - 1);

        ob.print(arr);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>mergesort</category>
      <category>recursive</category>
      <category>interview</category>
    </item>
    <item>
      <title>Data Structure &amp; Algorithm: Quick Sort</title>
      <dc:creator>Khadija Ashraf</dc:creator>
      <pubDate>Mon, 17 Mar 2025 17:25:15 +0000</pubDate>
      <link>https://dev.to/khadijaashraf/data-structure-algorithm-quick-sort-5b49</link>
      <guid>https://dev.to/khadijaashraf/data-structure-algorithm-quick-sort-5b49</guid>
      <description>&lt;p&gt;The algorithm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chose an element from the input array (arbitrary or, or the first, or the last one)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;partition the array in left and right portions. The left part of the partition has all the elements smaller than the partition point. The right part of the partition has all the elements grater than the partition point. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The partition point is called the pivot element. After a partition completion the pivot element achieves its actual final position in the final answer, that means, after every partition we get at least one element sorted and positioned in the final sorted result. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Therefore, the later partitions excludes the pivot element cause its already sitting in the index where it is suppose to be in the final sorted array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We treat each left and right partition as a new input array and call quicksort on both of them recursively.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Concept behind the partition method:&lt;/strong&gt;&lt;br&gt;
For every pivot element we scan the entire input array of its scope. during this scan our goal is to find any smaller elements than the pivot and place them to left side of the input array. Any left element that is not smaller than the pivot will leave its space gracefully for a smaller (than pivot) element. Therefore, we can say, after a single scan all the elements smaller than the current pivot are to the left side of the input array. Then we place the pivot element right after those smaller elements. In this process we can not assert that all those smaller elements are sorted but we can say that the pivot element is the grater than all those small elements. and since we scanned the entire input array, so it is intuitive that the pivot is sitting at the right position where it will be in the final sorted array, because all the elements left to the pivot are smaller than it, and obviously, all the elements right to the pivot must be grater than it.&lt;/p&gt;

&lt;p&gt;This process run recursively in the left and right parts of the input array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
public class QuickSort {

    public void sort(int[] arr, int lowIndex, int highIndex) {
        if(lowIndex &amp;lt; highIndex) {
            int pivotIndex = partition(arr, lowIndex, highIndex);

            sort(arr, lowIndex, pivotIndex - 1);
            sort(arr, pivotIndex + 1, highIndex);
        }
    }

    public int partition(int[] arr, int lowIndex, int highIndex) {
        int pivotIndex = highIndex;
        int leftIndex = lowIndex - 1;

        for(int i = lowIndex; i &amp;lt;= highIndex - 1; i++) {
            if(arr[i] &amp;lt; arr[pivotIndex]) {
                leftIndex++;
                swap(arr, leftIndex, i);
            }
        }
        leftIndex++;
                // in this swap we are setting the pivot to the correct 
                // index where all elements to it's left are small,
                // and, all elements to the pivot's right are grater.
        swap(arr, leftIndex, pivotIndex); 
        return leftIndex;
    }

    public void swap(int[] arr, int leftIndex, int i) {
        int temp = arr[i];
        arr[i] = arr[leftIndex];
        arr[leftIndex] = temp;
    }

    public static void main(String a[]) {
//      int[] input = {8,2,6,1,7,9,3};
        int[] input = {5,2,3,1};

        QuickSort ob = new QuickSort();

        ob.sort(input, 0, input.length-1);

        for(int num: input)
        {
            System.out.println(num+", ");
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>sorting</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Data structure: Implement Type safe, Generic, Double-ended Queue.</title>
      <dc:creator>Khadija Ashraf</dc:creator>
      <pubDate>Sun, 16 Mar 2025 15:14:07 +0000</pubDate>
      <link>https://dev.to/khadijaashraf/data-structure-implement-type-safe-generic-double-ended-queue-12d8</link>
      <guid>https://dev.to/khadijaashraf/data-structure-implement-type-safe-generic-double-ended-queue-12d8</guid>
      <description>&lt;p&gt;Today we will implement a Double-ended queue in Java. We will use generics so that our queue can work with any datatypes, like Integer, Double, String, Cars, Trucks, Cats, Dogs, etc... :)&lt;/p&gt;

&lt;p&gt;The source code is in this github repository. &lt;a href="https://github.com/khadija-ashraf/data-structure-algorithm.git" rel="noopener noreferrer"&gt;https://github.com/khadija-ashraf/data-structure-algorithm.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;Node&lt;/em&gt; is a generic class. That means this class can take different dataypes. A &lt;em&gt;Node&lt;/em&gt; object has a generic type 'data' and two pointer 'prev' and 'next'. 'prev' points to the previous node, and 'next' pointer points to the next node in the queue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fkl7mhpldp5o9q8t163gw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fkl7mhpldp5o9q8t163gw.png" alt="Nodes in a deque" width="800" height="73"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.deque;


class Node&amp;lt;T&amp;gt;{
    T data;
    Node&amp;lt;T&amp;gt; prev;
    Node&amp;lt;T&amp;gt; next;

    public Node(T data){
        this.data = data;
        this.prev = null;
        this.next = null;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;MyDeque&lt;/em&gt; is the deque interface. It layout the deque behaviour.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.deque;

// A custom Double Ended Queue (Deque) implementation:

public interface MyDeque&amp;lt;T&amp;gt; {

    public &amp;lt;T&amp;gt; T addHead(T data);
    public &amp;lt;T&amp;gt; T addTail(T data);

    public T getHead();
    public T getTail();

    public &amp;lt;T&amp;gt; boolean contains(T data);

    public T removeHead();
    public T removeTail();

    public T peekHead();
    public T peekTail();

    public T pollHead();
    public T pollTail();

    public T pop();

    public int size();
    public void printDequq() ;

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A deque is a queue in which we can insert and remove from both the front and rear end. Conversely, in an original queue we insert at the front and remove from the rear end. &lt;/p&gt;

&lt;p&gt;In a deque, we have a head node and a tail node representing the start and the end of the queue respectively. We add remove from both front and rear ends from the head and tail referencing nodes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyDequeImpl&amp;lt;T&amp;gt; implements MyDeque&amp;lt;T&amp;gt;{
    private Node&amp;lt;T&amp;gt; head;
    private Node&amp;lt;T&amp;gt; tail;
    private int size;

    public MyDequeImpl(){
        head = null;
        tail = null;
        size = 0;
    }

    public &amp;lt;T&amp;gt; T addHead(T data) {
        Node current = new Node&amp;lt;&amp;gt;(data);
        if(head == null) {
            head = current;
            tail = current;
            size++;
            return data;
        }
        current.next = head;
        head.prev = current;
        head = current;
        size++;

        return data;
    }

    public &amp;lt;T&amp;gt; T addTail(T data) {
        Node current = new Node&amp;lt;T&amp;gt;(data);

        if(tail == null) {
            head = current;
            tail = current;
            size++;
            return data;
        }
        tail.next = current;
        current.prev = tail;
        tail = current;
        size++;
        return data;
    }

    public T getHead() {
        if (head == null)
            return null;
        return head.data;
    }

    public T getTail() {
        if(tail == null)
            return null;
        return tail.data;
    }

    public &amp;lt;T&amp;gt; boolean contains(T data) {
        if(head == null)
            return false;

        if(head.data == data) {
            return true;
        }

        if(tail.data == data) {
            return true;
        }

        Node current = head;

        while(current != null) {
            if(current.data == data) {
                return true;
            }
            current = current.next;
        }
        return false;
    }

    public T removeHead() {
        if(head == null) {
            return null;
        }

        T removedData = head.data;

        head = head.next;

        if(head == null) {
            tail = null;
        } else {
            head.prev = null;
        }
        size--;
        return removedData;
    }

    public T removeTail() {
        if(tail == null) {
            return null;
        }
        if(tail.prev == null) {
            return null;
        }
        T removedData = tail.data;
        tail = tail.prev;
        if(tail == null) {
            head = null;
        } else {
            tail.next = null;
        }
        size--;
        return removedData;
    }

    public T peekHead() {
        if(head == null)
            return null;

        return head.data;
    }

    public T peekTail() {
        if(tail == null)
            return null;

        return tail.data;
    }

    public T pollHead() {
        if(head == null)
            return null;

        T polledData = head.data;

        head = head.next;

        if(head == null) {
            tail = null;
        } else {
            head.prev = null;
        }
        size--;

        return polledData;
    }

    @Override
    public T pollTail() {
        if(tail == null) {
            return null;
        }
        T pollData = tail.data;

        tail = tail.prev;

        if(tail == null)
            head = null;
        else {
            tail.next = null;
        }

        size--;
        return pollData;
    }

    public T pop() {
        if(tail == null)
            return null;

        T popedData = tail.data;

        tail = tail.prev;

        if(tail == null)
            head = null;
        else {
            tail.next = null;
        }
        size--;
        return popedData;
    }

    public int size() {
        return size;
    }
    public void printDequq() {
        System.out.println("Printing the deque of size: "+size());
        if (head == null) {
            System.out.println("Dequq is empty.");
        }
        Node&amp;lt;T&amp;gt; current = head;
        while(current != null) {
            System.out.println(current.data);
            current = current.next;
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is some test insertions, removal, polling, peeking, and pop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.deque;

public class TestDeque{
    public static void main(String arg[]) {
        MyDeque&amp;lt;String&amp;gt; deque = new MyDequeImpl&amp;lt;&amp;gt;();
        deque.addHead("cat");
        deque.printDequq();
        deque.addHead("dog");
        deque.printDequq();
        deque.addHead("rabbit");
        deque.printDequq();
        deque.addHead("elephant");
        deque.printDequq();
        deque.addTail("squirrel");
        deque.printDequq();

        System.out.println("=============");
        System.out.println(deque.getHead());
        System.out.println(deque.getTail());
        System.out.println(deque.contains("monkey"));
        System.out.println(deque.contains("rabbit"));
        System.out.println(deque.removeHead());
        System.out.println(deque.removeTail());
        System.out.println("=======");

        System.out.println(deque.getHead());
        System.out.println(deque.getTail());
        System.out.println("=======");
        System.out.println(deque.peekHead());
        System.out.println(deque.peekTail());
        System.out.println("========");
        System.out.println(deque.pollHead());
        System.out.println(deque.pollTail());
        deque.printDequq();

        System.out.println("========");
        System.out.println(deque.pop());
        deque.printDequq();

        deque.addHead("birds");

        deque.printDequq();
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>doubleendedqueue</category>
      <category>javagenerics</category>
      <category>customdeque</category>
    </item>
    <item>
      <title>Beginner Tutorial: Build, Test, and deploy Spring Boot microservices with MongoDB and Docker</title>
      <dc:creator>Khadija Ashraf</dc:creator>
      <pubDate>Thu, 13 Mar 2025 22:30:45 +0000</pubDate>
      <link>https://dev.to/khadijaashraf/beginner-tutorial-build-test-and-deploy-springboot-microservices-with-mongodb-and-docker-178i</link>
      <guid>https://dev.to/khadijaashraf/beginner-tutorial-build-test-and-deploy-springboot-microservices-with-mongodb-and-docker-178i</guid>
      <description>&lt;p&gt;This is a beginner application to create a group of microservices to perform CRUD and filtering on a group of Users. This project is implemented in a MacBook Pro. The source code is available in the &lt;a href="https://github.com/khadija-ashraf/Spring-microservices-mongodb-mockito" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The steps we follow to successfully implement this project are below:&lt;/p&gt;

&lt;h2&gt;
  
  
  Initialize the springboot application.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Download a Springboot application from the spring initializr website, &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;https://start.spring.io/&lt;/a&gt;. 
Add dependency &lt;strong&gt;Spring Web&lt;/strong&gt;,  &lt;strong&gt;Spring Data MongoDB&lt;/strong&gt;, and &lt;strong&gt;Mockito&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the website &lt;strong&gt;spring initializr&lt;/strong&gt; downloading the project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmx83qf71cglwm5t707s5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmx83qf71cglwm5t707s5.png" alt="spring initializr website" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pom.xml&lt;/strong&gt; dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-data-mongodb&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-test&amp;lt;/artifactId&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.mockito&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;mockito-core&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; Add the &lt;strong&gt;mockito-core&lt;/strong&gt; dependency explicitly in your pom.xml if you don't find in the dependency directory in the spring initializr website. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Now import the project in your IDE. I'm using the eclipse community version. Then run the project from the entry point of the application that is the project name you selected while downloading from spring initializr website. In my example the application name is &lt;strong&gt;MongoDemoApplication&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgj7pizctejxwxaqjfyrf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgj7pizctejxwxaqjfyrf.png" alt="Springboot Application" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; Remember that the tomcat is embedded with the spring-boot-starter-web dependency. So when we run the application the tomcat server runs on port 8080. If we fail to stop the server before running the spring application again then a &lt;em&gt;Port 8080 was already in use&lt;/em&gt; error will fail the application to start again. So we need to stop the underlying tomcat server before we try starting that again. Among many options we can run the below command in the terminal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;kill -9 $(lsof -t -i:8080)&lt;/code&gt; This stops any process running on port 8080, which is Tomcat’s default port.)&lt;/p&gt;

&lt;p&gt;Now its time to install and configure the MongoDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and run the MongoDB in the local machine.
&lt;/h2&gt;

&lt;p&gt;Install MongoDB Using Homebrew (this example uses Macbook Pro):&lt;br&gt;
To install HomeBrew (if not already installed):&lt;br&gt;
&lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;check if Homebrew is installed correctly:&lt;br&gt;
&lt;code&gt;brew --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add Homebrew to Your Path:&lt;br&gt;
&lt;code&gt;echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' &amp;gt;&amp;gt; ~/.zshrc&lt;br&gt;
source ~/.zshrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then follow below steps to install MongoDB:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew update&lt;/code&gt; -- Update Homebrew&lt;br&gt;
&lt;code&gt;brew tap mongodb/brew&lt;/code&gt; -- Install MongoDB Community Edition&lt;br&gt;
&lt;code&gt;brew install mongodb-community@7.0&lt;/code&gt; &lt;br&gt;
&lt;code&gt;brew services start mongodb-community@7.0&lt;/code&gt; -- Start MongoDB as a background service&lt;br&gt;
&lt;code&gt;brew services stop mongodb-community@7.0&lt;/code&gt; --To stop MongoDB&lt;br&gt;
&lt;code&gt;mongod --version&lt;/code&gt; -- Check if MongoDB is running&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To add MongoDB in your application add below properties in the &lt;em&gt;application.properties&lt;/em&gt;. The &lt;em&gt;application.properties&lt;/em&gt; file is located under src/main/resources directory. In this example the DB name is &lt;em&gt;myFirstDB&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;spring.application.name=MongoDemo&lt;br&gt;
spring.data.mongodb.uri=mongodb://localhost:27017/myFirstDB&lt;br&gt;
spring.data.mongodb.database=myFirstDB&lt;br&gt;
&lt;/code&gt; &lt;/p&gt;


&lt;h2&gt;
  
  
  Create the MVC layers for User Services.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next we create the layers of the User managing microservice application. Controller (RESTApi endpoints) Layer, Service Layer, Repository Layer, and the Entity Layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; You can separate java packages or keep them in a single package. However, be sure to keep the &lt;em&gt;main&lt;/em&gt; class in the parent package. In this example I'm keeping &lt;strong&gt;MongoDemoApplication&lt;/strong&gt; in the parent package &lt;em&gt;com.example&lt;/em&gt;. If your controller, service, repository, entity classes are spread in different packages then be sure to the &lt;em&gt;@ComponentScan()&lt;/em&gt; to link the inner package classes. &lt;br&gt;
,&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SpringBootApplication
@ComponentScan(basePackages = "com.example.controller, com.example.Service, com.example.repository")
public class MongoDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(MongoDemoApplication.class, args); 
        System.out.println("Welcome to user world!");
    }

}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;User&lt;/strong&gt; entity is defined below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import com.mongodb.lang.NonNull;

@Document (collection = "users")
public class User {

    @Id
    private String id;

    @NonNull
    private String name;

    @NonNull
    private String email;

    public User() {}

    public User(String name, String email) {
        super();
        this.name = name;
        this.email = email;
    }

    public User(String id, String name, String email) {
        super();
        this.id = id;
        this.name = name;
        this.email = email;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;UserRepository&lt;/strong&gt; is defined below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.repository;

import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.example.entity.User;

@Repository
public interface UserRepository extends MongoRepository&amp;lt;User, String&amp;gt;{
    User findByEmail(String email);
    List&amp;lt;User&amp;gt; findByName(String name);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;UserService&lt;/strong&gt; interface is defined below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.service;

import java.util.List;

import com.example.entity.User;

public interface UserService {
    List&amp;lt;User&amp;gt; getAllUsers();

    User getUserById(String id);
    User getUserByEmail(String email);
    List&amp;lt;User&amp;gt; getUsersByName(String name);

    User createUser(User user);
    User updateUser(String id, User user);
    void deleteUser(String Id);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;UserServiceImpl&lt;/strong&gt; defined below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.service;

import java.util.List;

import org.springframework.stereotype.Service;

import com.example.entity.User;
import com.example.repository.UserRepository;

@Service
public class UserServiceImpl implements UserService{

    private final UserRepository userRepo;

    public UserServiceImpl(UserRepository userRepo) {
        super();
        this.userRepo = userRepo;
    }

    public List&amp;lt;User&amp;gt; getAllUsers() {
        return userRepo.findAll();
    }

    public User getUserById(String id) throws RuntimeException{
        return userRepo.findById(id).orElseThrow(() -&amp;gt; new RuntimeException("User not found "+id));
    }

    public User getUserByEmail(String email) {
        return userRepo.findByEmail(email);
    }

    public List&amp;lt;User&amp;gt; getUsersByName(String name) {
        return userRepo.findByName(name);
    }

    public User createUser(User user) {
        return userRepo.save(user);
    }

    public User updateUser(String id, User user) {
        User existing = getUserById(id);
        existing.setEmail(user.getEmail());
        existing.setName(user.getName());
        return userRepo.save(existing);
    }

    public void deleteUser(String id) {
        userRepo.deleteById(id);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now that, we have all our repository and service code implemented we write our RESTApi endpoints, that is the controller layer.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.AccessType;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.service.UserService;
import com.example.entity.User;

import java.util.List;


@RestController
@RequestMapping("/users")
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public User getAllUserById(@PathVariable String id){
        return userService.getUserById(id);
    }

    @GetMapping("/name/{name}")
    public List&amp;lt;User&amp;gt; getAllUsersByName(@PathVariable String name){
        return userService.getUsersByName(name);
    }

    @GetMapping("/email/{email}")
    public User getUserByEmail(@PathVariable String email) {
        return userService.getUserByEmail(email);
    }

    @PostMapping("/create")
    public ResponseEntity&amp;lt;User&amp;gt; createUser(@RequestBody User user) {
        userService.createUser(user);
        return ResponseEntity.status(HttpStatusCode.valueOf(HttpStatus.CREATED.value()))
                .body(user);
    }

    @PostMapping("/update/{id}")
    public User updateUser(@PathVariable String id, @RequestBody User user) {
        return userService.updateUser(id, user);
    }

    @DeleteMapping("/delete/{id}")
    public void deleteUserById(@PathVariable String id) {
        userService.deleteUser(id);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Testing the service layer and the RESTApi endpoints using Mockito
&lt;/h2&gt;

&lt;p&gt;Now, that we have our DB, and service layer, and REST endpoints we can write our test methods.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; Mockito does not run the entire application. It only mocks the service and controller objects to test their methods. The test results are valid however, since the application is not running and the RESTApis are not called over HTTP, therefore no DB actions are performed. To test the DB interactions we can use Postman, other RESTApi clients. However, these calls will make real and persistent changes in the DB. If we still want to test DB interactions but want to avoid testing in the development DB instance, then we can use Spring &lt;em&gt;TestContainers&lt;/em&gt;. In the Testcontainers we can run real DB instances inside a Docker container. For a testing session, Spring-boot spins up a Docker container with as new DB instance. When testing is done the container is stopped. &lt;em&gt;TestContainers&lt;/em&gt; are out of scope of this tutorial. We will see Mockito test classes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Test Service layer with Mockito
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;UserServiceTest&lt;/em&gt; is designated to the User @service class.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.MongoDemo;

// import static org.junit.Assert.assertNotNull;  — incorrect import
import static org.junit.jupiter.api.Assertions.assertNotNull; // -correct import

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

import java.util.Optional;

import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;

import com.example.entity.User;
import com.example.repository.UserRepository;
import com.example.service.UserServiceImpl;

@SpringBootTest
public class UserServiceTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserServiceImpl userServiceImpl;

    @Test
    void testGetUserById() {
        String id = "1";
        String name = "John Doe";
        String email = "john@gmail.com";
        User user = new User(name, email);
        user.setId(id);

        when(userRepository.findById(id)).thenReturn(Optional.of(user));

        User result = userServiceImpl.getUserById(id);
        assertNotNull(result);
        assertEquals(result.getName(), user.getName());

    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt;  Be sure to import the right &lt;em&gt;assertNotNull&lt;/em&gt; dependency. Importing &lt;strong&gt;import static org.junit.Assert.assertNotNull&lt;/strong&gt; will give a compile error during building your project's .jar file. I'm copying the compilation error for your reference. &lt;code&gt;src/test/java/com/example/MongoDemo/UserServiceTest.java:[3,24] cannot find symbol&lt;br&gt;
  symbol:   class Assert&lt;br&gt;
  location: package org.junit&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;UserControllerTest&lt;/em&gt; is designated to the User @RestController class.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.example.MongoDemo;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.log;
// Import for status(), jsonPath()
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import com.example.controller.UserController;
import com.example.entity.User;
import com.example.service.UserService;

@WebMvcTest(UserController.class)
public class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    void testGetUserById() throws Exception {
        when(userService.getUserById("1")).thenReturn(new User("1", "John Doe", "john@gmail.com"));

        mockMvc.perform(get("/users/1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.id").value(1))
               .andExpect(jsonPath("$.name").value("John Doe"))
               .andExpect(jsonPath("$.email").value("john@gmail.com"));
    }

    @Test
    void testCreateUser() throws Exception {
        String userJson = "{\"name\": \"Jane Doe\", \"email\": \"jane@gmail.com\"}";

        ResultActions resultActions = mockMvc.perform(post("/users/create")
                .contentType(MediaType.APPLICATION_JSON)
                .content(userJson))
                .andDo(print())
                .andDo(log())
               .andExpect(status().isCreated())
               .andExpect(jsonPath("$.name").value("Jane Doe"));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; In the &lt;em&gt;UserControllerTest&lt;/em&gt; file be sure to include the static imports. They are often not recommended by the IDE and you explicitly have to find the dependencies to be able to import them. Below are the static import used in this &lt;em&gt;UserControllerTest&lt;/em&gt; class.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.log;
// Import for status(), jsonPath()
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To log the HTTP req/res from the test methods add below properties in the application.properties file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Enable logging to a file
logging.file.name=logs/app.log  # Creates logs/app.log
# OR (alternative)
logging.file.path=logs  # Creates logs/spring.log

# Set log level (Optional)
logging.level.root=INFO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; To ensure log of the actual HTTP requests and responses use the &lt;em&gt;print()&lt;/em&gt; and &lt;em&gt;log()&lt;/em&gt; methods in the &lt;em&gt;mockMvc.perform()&lt;/em&gt; method.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.log;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the &lt;strong&gt;UserControllerTest.java&lt;/strong&gt; and &lt;strong&gt;UserServiceTest.java&lt;/strong&gt; separately to test the RESTApi methods and service methods in a mock environment. The actual HTTP req/res will be printed in the log file when you run &lt;strong&gt;UserControllerTest.java&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;HTTP Request and corresponding response printed by running the RestController &lt;strong&gt;UserControllerTest.java&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /users/create
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"47"]
             Body = {"name": "Jane Doe", "email": "jane@gmail.com"}
    Session Attrs = {}

Handler:
             Type = com.example.controller.UserController
           Method = com.example.controller.UserController#createUser(User)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"id":null,"name":"Jane Doe","email":"jane@gmail.com"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Deploy the User-microservice application and the MongoDb in Docker
&lt;/h2&gt;

&lt;p&gt;We will deploy our microservice app and the mongoDB in docker containers. Please install &lt;em&gt;Docker Desktop&lt;/em&gt; in your system. This example uses Docker Desktop on Mac (Apple Silicon chip). Follow the link for installation on Mac, &lt;a href="https://docs.docker.com/desktop/setup/install/mac-install/" rel="noopener noreferrer"&gt;https://docs.docker.com/desktop/setup/install/mac-install/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The steps we follow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Creating a docker image of the springboot microservice application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then upload the microservice image that we just created into Docker hub (Docker Hub is a cloud-based registry service provided by Docker for storing, sharing, and managing container images [ref. docker.com])&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write and execute a file named &lt;em&gt;docker-compose.yml&lt;/em&gt;. This fill will be responsible to pull both the microservice and mongodb images from the docker hub and also run both the containers. &lt;strong&gt;&amp;gt;Tips:&lt;/strong&gt; We don't need to create a docker image for mongoDB because its already up in the docker hub. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;1. Creating a docker image of the springboot microservice application.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:  Build the Spring Boot JAR&lt;/strong&gt;&lt;br&gt;
Navigate to your Spring Boot project directory and run below command in your terminal.(You can install maven in you system or you can use the IDE integrated maven. This example uses maven outside the IDE eclipse):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mvn clean package -DskipTests&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This generates a JAR file inside the &lt;strong&gt;target/&lt;/strong&gt; directory. My .jar file name is, &lt;strong&gt;MongoDemo-0.0.1-SNAPSHOT.jar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:  Create a Dockerfile:&lt;/strong&gt; Inside your project root directory, create a file named Dockerfile (without any extension).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use an official OpenJDK image as the base image
FROM openjdk:17-jdk-slim

# Set the working directory inside the container
WORKDIR /app

# Copy the JAR file from the host machine to the container
COPY target/MongoDemo-0.0.1-SNAPSHOT.jar app.jar

# Expose the application port
EXPOSE 8080

# Command to run the application
ENTRYPOINT ["java", "-jar", "app.jar"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3. Build the Docker Image&lt;/strong&gt;&lt;br&gt;
From the terminal run the following command in the directory where your Dockerfile is located. I've this file right under the application folder, &lt;em&gt;MongoDemo/dockerfile&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t my-user-microservice .&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;• -t my-microservice → Assigns a name (my-microservice) to the image.&lt;br&gt;
    • . → Tells Docker to look for the Dockerfile in the current directory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You will see below longs in your terminal upon executing the &lt;em&gt;docker build&lt;/em&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fu12yg4p5ddube0bpbj7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fu12yg4p5ddube0bpbj7z.png" alt="Docker build logs" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4. Verify the Docker Image&lt;/strong&gt;&lt;br&gt;
After building, check if the image is created:&lt;br&gt;
&lt;code&gt;docker images&lt;/code&gt; --You should see my-user-microservice in the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5. Run the Container&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker run -d --name microservice-container -p 8080:8080 my-user-microservice&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;• -d → Runs in detached mode (background).&lt;br&gt;
    • --name microservice-container → Assigns a name to the container.&lt;br&gt;
    • -p 8080:8080 → Maps container port 8080 to host port 8080.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After running this command a container Id will be returned similar to this one &lt;code&gt;695bd664bd94155b1d8640bcc2a74633110e0f11ce830796b72e4fb57bda9e4c&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Now, your microservice should be accessible at: &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6. Check Running Containers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To verify if your container is running: &lt;code&gt;docker ps&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you need logs: &lt;code&gt;docker logs microservice-container&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7. Stop &amp;amp; Remove a single Container (Optional)&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker stop microservice-container&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: To remove the container:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker rm microservice-container&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9.Stop &amp;amp; Remove all the Containers&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker-compose down&lt;/code&gt;. --This stops and removes all containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10. Restart Services&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker-compose restart&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11. Rebuild Images (If Needed)&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker-compose up --build -d&lt;/code&gt; --If you made changes to the Dockerfile or code and want to rebuild&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Then upload the microservice image that we just created into Docker hub&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 1: Login to Docker Hub using command: &lt;code&gt;docker login&lt;/code&gt;&lt;br&gt;
Enter your Docker Hub username and password.&lt;/p&gt;

&lt;p&gt;Step 2: Tag the Image.&lt;br&gt;
&lt;code&gt;docker tag my-user-microservice &amp;lt;your-dockerhub-username&amp;gt;/my-user-microservice:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;docker tag my-user-microservice johndoe/my-user-microservice:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Step 3: Push the Image.&lt;br&gt;
&lt;code&gt;docker push &amp;lt;your-dockerhub-username&amp;gt;/my-user-microservice:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F6rwd0q6hhz480zyglc0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6rwd0q6hhz480zyglc0x.png" alt="docker push logs" width="800" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, your image is available on Docker Hub and can be pulled from anywhere using: &lt;code&gt;docker pull johndoe/my-user-microservice:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can try this docker pull command just to verify. However, the docker-decompose.yml will pull the microservice image from the docker huband lunch a container for that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Now to write and execute a file names docker-compose.yml.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step1:&lt;/strong&gt; Our microservice needs to run alongside a MongoDB so we create create a docker-compose.yml file. We can use docker-compose when we have multiple containers for example for microservices, databases, and more, interacting with each other. docker-compose is used to manage multiple Docker containers as a single service. Follow these steps to run a docker-compose.yml file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step2:&lt;/strong&gt; Run Docker Compose &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Navigate to the Directory Containing docker-compose.yml, then run the command: &lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-d&lt;/code&gt;→ Runs the containers in detached mode (in the background).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In Docker, use container names/services instead of localhost.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Verify the MongoDB activity inside from its Docker Container&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can open the terminal in the docker container from the docker GUI by clicking the Terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7xsc36ardoc1nbunpons.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7xsc36ardoc1nbunpons.png" alt="terminal from inside the docker container" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the terminal is open run the below commands to see the &lt;strong&gt;users&lt;/strong&gt; entries.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker exec -it mongodb mongosh&lt;/code&gt;-- Run the MongoDB shell inside the container:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;-it → Interactive mode.&lt;br&gt;
    mongodb → Name of the running container.&lt;br&gt;
    mongosh → Starts the MongoDB shell.&lt;br&gt;
Now, you can run MongoDB queries:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;show dbs;&lt;br&gt;
use myFirstDB;&lt;br&gt;
db.users.find();&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fo9lp8vp5jiki0zzwyg9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fo9lp8vp5jiki0zzwyg9i.png" alt="mongo db entries" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To test the containerized microservice application including the DB interactions use Postman or any other RESTApi client for calling microservices. First make the api call from Postman, then access the Docker container terminal to look into the users collection. &lt;/p&gt;

&lt;p&gt;I've copied the "/users/create" API endpoint calling details below.&lt;/p&gt;

&lt;p&gt;_POST  &lt;a href="http://localhost:8080/users/create" rel="noopener noreferrer"&gt;http://localhost:8080/users/create&lt;/a&gt;&lt;br&gt;
Request headers: Content-Type: application/json&lt;br&gt;
Request Body (raw) : {"name": "mina", "email": "&lt;a href="mailto:mina@g.com"&gt;mina@g.com&lt;/a&gt;"}  &lt;/p&gt;

&lt;p&gt;Response headers:Content-Type: application/json&lt;br&gt;
Response Body: {"id":"67d351220527311ea262f733","name":"rina","email":"&lt;a href="mailto:rina@g.com"&gt;rina@g.com&lt;/a&gt;"}_&lt;/p&gt;




&lt;p&gt;This concludes the tutorial. I tried to create an entire lifecycle of a microservice based application from development to deployment. Hope this helps! &lt;/p&gt;

</description>
      <category>springboot</category>
      <category>microservices</category>
      <category>mongodb</category>
      <category>mockito</category>
    </item>
  </channel>
</rss>
