<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Vignesh Prabhu]]></title><description><![CDATA[Vignesh Prabhu]]></description><link>https://www.vigneshprabhu.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 23:48:09 GMT</lastBuildDate><atom:link href="https://www.vigneshprabhu.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[GameTracker Privacy Policy]]></title><description><![CDATA[Privacy Policy
Last updated: October 15, 2024
This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protect...]]></description><link>https://www.vigneshprabhu.dev/gametracker-privacy-policy</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/gametracker-privacy-policy</guid><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Tue, 15 Oct 2024 08:06:20 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-privacy-policy"><strong>Privacy Policy</strong></h1>
<p>Last updated: October 15, 2024</p>
<p>This Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your information when You use the Service and tells You about Your privacy rights and how the law protects You.</p>
<p>We use Your Personal data to provide and improve the Service. By using the Service, You agree to the collection and use of information in accordance with this Privacy Policy. This Privacy Policy has been created with the help of the <a target="_blank" href="https://www.termsfeed.com/privacy-policy-generator/">Privacy Policy Generator</a>.</p>
<h2 id="heading-interpretation-and-definitions"><strong>Interpretation and Definitions</strong></h2>
<h3 id="heading-interpretation"><strong>Interpretation</strong></h3>
<p>The words of which the initial letter is capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.</p>
<h3 id="heading-definitions"><strong>Definitions</strong></h3>
<p>For the purposes of this Privacy Policy:</p>
<ul>
<li><p><strong>Account</strong> means a unique account created for You to access our Service or parts of our Service.</p>
</li>
<li><p><strong>Affiliate</strong> means an entity that controls, is controlled by or is under common control with a party, where "control" means ownership of 50% or more of the shares, equity interest or other securities entitled to vote for election of directors or other managing authority.</p>
</li>
<li><p><strong>Application</strong> refers to GameTracker, the software program provided by the Company.</p>
</li>
<li><p><strong>Company</strong> (referred to as either "the Company", "We", "Us" or "Our" in this Agreement) refers to GameTracker.</p>
</li>
<li><p><strong>Country</strong> refers to: Karnataka, India</p>
</li>
<li><p><strong>Device</strong> means any device that can access the Service such as a computer, a cellphone or a digital tablet.</p>
</li>
<li><p><strong>Personal Data</strong> is any information that relates to an identified or identifiable individual.</p>
</li>
<li><p><strong>Service</strong> refers to the Application.</p>
</li>
<li><p><strong>Service Provider</strong> means any natural or legal person who processes the data on behalf of the Company. It refers to third-party companies or individuals employed by the Company to facilitate the Service, to provide the Service on behalf of the Company, to perform services related to the Service or to assist the Company in analyzing how the Service is used.</p>
</li>
<li><p><strong>Usage Data</strong> refers to data collected automatically, either generated by the use of the Service or from the Service infrastructure itself (for example, the duration of a page visit).</p>
</li>
<li><p><strong>You</strong> means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.</p>
</li>
</ul>
<h2 id="heading-collecting-and-using-your-personal-data"><strong>Collecting and Using Your Personal Data</strong></h2>
<h3 id="heading-types-of-data-collected"><strong>Types of Data Collected</strong></h3>
<h4 id="heading-personal-data"><strong>Personal Data</strong></h4>
<p>While using Our Service, We may ask You to provide Us with certain personally identifiable information that can be used to contact or identify You. Personally identifiable information may include, but is not limited to:</p>
<ul>
<li>Usage Data</li>
</ul>
<h4 id="heading-usage-data"><strong>Usage Data</strong></h4>
<p>Usage Data is collected automatically when using the Service.</p>
<p>Usage Data may include information such as Your Device's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that You visit, the time and date of Your visit, the time spent on those pages, unique device identifiers and other diagnostic data.</p>
<p>When You access the Service by or through a mobile device, We may collect certain information automatically, including, but not limited to, the type of mobile device You use, Your mobile device unique ID, the IP address of Your mobile device, Your mobile operating system, the type of mobile Internet browser You use, unique device identifiers and other diagnostic data.</p>
<p>We may also collect information that Your browser sends whenever You visit our Service or when You access the Service by or through a mobile device.</p>
<h3 id="heading-use-of-your-personal-data"><strong>Use of Your Personal Data</strong></h3>
<p>The Company may use Personal Data for the following purposes:</p>
<ul>
<li><p><strong>To provide and maintain our Service</strong>, including to monitor the usage of our Service.</p>
</li>
<li><p><strong>To manage Your Account:</strong> to manage Your registration as a user of the Service. The Personal Data You provide can give You access to different functionalities of the Service that are available to You as a registered user.</p>
</li>
<li><p><strong>For the performance of a contract:</strong> the development, compliance and undertaking of the purchase contract for the products, items or services You have purchased or of any other contract with Us through the Service.</p>
</li>
<li><p><strong>To contact You:</strong> To contact You by email, telephone calls, SMS, or other equivalent forms of electronic communication, such as a mobile application's push notifications regarding updates or informative communications related to the functionalities, products or contracted services, including the security updates, when necessary or reasonable for their implementation.</p>
</li>
<li><p><strong>To provide You</strong> with news, special offers and general information about other goods, services and events which we offer that are similar to those that you have already purchased or enquired about unless You have opted not to receive such information.</p>
</li>
<li><p><strong>To manage Your requests:</strong> To attend and manage Your requests to Us.</p>
</li>
<li><p><strong>For business transfers:</strong> We may use Your information to evaluate or conduct a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of Our assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which Personal Data held by Us about our Service users is among the assets transferred.</p>
</li>
<li><p><strong>For other purposes</strong>: We may use Your information for other purposes, such as data analysis, identifying usage trends, determining the effectiveness of our promotional campaigns and to evaluate and improve our Service, products, services, marketing and your experience.</p>
</li>
</ul>
<p>We may share Your personal information in the following situations:</p>
<ul>
<li><p><strong>With Service Providers:</strong> We may share Your personal information with Service Providers to monitor and analyze the use of our Service, to contact You.</p>
</li>
<li><p><strong>For business transfers:</strong> We may share or transfer Your personal information in connection with, or during negotiations of, any merger, sale of Company assets, financing, or acquisition of all or a portion of Our business to another company.</p>
</li>
<li><p><strong>With Affiliates:</strong> We may share Your information with Our affiliates, in which case we will require those affiliates to honor this Privacy Policy. Affiliates include Our parent company and any other subsidiaries, joint venture partners or other companies that We control or that are under common control with Us.</p>
</li>
<li><p><strong>With business partners:</strong> We may share Your information with Our business partners to offer You certain products, services or promotions.</p>
</li>
<li><p><strong>With other users:</strong> when You share personal information or otherwise interact in the public areas with other users, such information may be viewed by all users and may be publicly distributed outside.</p>
</li>
<li><p><strong>With Your consent</strong>: We may disclose Your personal information for any other purpose with Your consent.</p>
</li>
</ul>
<h3 id="heading-retention-of-your-personal-data"><strong>Retention of Your Personal Data</strong></h3>
<p>The Company will retain Your Personal Data only for as long as is necessary for the purposes set out in this Privacy Policy. We will retain and use Your Personal Data to the extent necessary to comply with our legal obligations (for example, if we are required to retain your data to comply with applicable laws), resolve disputes, and enforce our legal agreements and policies.</p>
<p>The Company will also retain Usage Data for internal analysis purposes. Usage Data is generally retained for a shorter period of time, except when this data is used to strengthen the security or to improve the functionality of Our Service, or We are legally obligated to retain this data for longer time periods.</p>
<h3 id="heading-transfer-of-your-personal-data"><strong>Transfer of Your Personal Data</strong></h3>
<p>Your information, including Personal Data, is processed at the Company's operating offices and in any other places where the parties involved in the processing are located. It means that this information may be transferred to — and maintained on — computers located outside of Your state, province, country or other governmental jurisdiction where the data protection laws may differ than those from Your jurisdiction.</p>
<p>Your consent to this Privacy Policy followed by Your submission of such information represents Your agreement to that transfer.</p>
<p>The Company will take all steps reasonably necessary to ensure that Your data is treated securely and in accordance with this Privacy Policy and no transfer of Your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of Your data and other personal information.</p>
<h3 id="heading-delete-your-personal-data"><strong>Delete Your Personal Data</strong></h3>
<p>You have the right to delete or request that We assist in deleting the Personal Data that We have collected about You.</p>
<p>Our Service may give You the ability to delete certain information about You from within the Service.</p>
<p>You may update, amend, or delete Your information at any time by signing in to Your Account, if you have one, and visiting the account settings section that allows you to manage Your personal information. You may also contact Us to request access to, correct, or delete any personal information that You have provided to Us.</p>
<p>Please note, however, that We may need to retain certain information when we have a legal obligation or lawful basis to do so.</p>
<h3 id="heading-disclosure-of-your-personal-data"><strong>Disclosure of Your Personal Data</strong></h3>
<h4 id="heading-business-transactions"><strong>Business Transactions</strong></h4>
<p>If the Company is involved in a merger, acquisition or asset sale, Your Personal Data may be transferred. We will provide notice before Your Personal Data is transferred and becomes subject to a different Privacy Policy.</p>
<h4 id="heading-law-enforcement"><strong>Law enforcement</strong></h4>
<p>Under certain circumstances, the Company may be required to disclose Your Personal Data if required to do so by law or in response to valid requests by public authorities (e.g. a court or a government agency).</p>
<h4 id="heading-other-legal-requirements"><strong>Other legal requirements</strong></h4>
<p>The Company may disclose Your Personal Data in the good faith belief that such action is necessary to:</p>
<ul>
<li><p>Comply with a legal obligation</p>
</li>
<li><p>Protect and defend the rights or property of the Company</p>
</li>
<li><p>Prevent or investigate possible wrongdoing in connection with the Service</p>
</li>
<li><p>Protect the personal safety of Users of the Service or the public</p>
</li>
<li><p>Protect against legal liability</p>
</li>
</ul>
<h3 id="heading-security-of-your-personal-data"><strong>Security of Your Personal Data</strong></h3>
<p>The security of Your Personal Data is important to Us, but remember that no method of transmission over the Internet, or method of electronic storage is 100% secure. While We strive to use commercially acceptable means to protect Your Personal Data, We cannot guarantee its absolute security.</p>
<h2 id="heading-childrens-privacy"><strong>Children's Privacy</strong></h2>
<p>Our Service does not address anyone under the age of 13. We do not knowingly collect personally identifiable information from anyone under the age of 13. If You are a parent or guardian and You are aware that Your child has provided Us with Personal Data, please contact Us. If We become aware that We have collected Personal Data from anyone under the age of 13 without verification of parental consent, We take steps to remove that information from Our servers.</p>
<p>If We need to rely on consent as a legal basis for processing Your information and Your country requires consent from a parent, We may require Your parent's consent before We collect and use that information.</p>
<h2 id="heading-links-to-other-websites"><strong>Links to Other Websites</strong></h2>
<p>Our Service may contain links to other websites that are not operated by Us. If You click on a third party link, You will be directed to that third party's site. We strongly advise You to review the Privacy Policy of every site You visit.</p>
<p>We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.</p>
<h2 id="heading-changes-to-this-privacy-policy"><strong>Changes to this Privacy Policy</strong></h2>
<p>We may update Our Privacy Policy from time to time. We will notify You of any changes by posting the new Privacy Policy on this page.</p>
<p>We will let You know via email and/or a prominent notice on Our Service, prior to the change becoming effective and update the "Last updated" date at the top of this Privacy Policy.</p>
<p>You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.</p>
<h2 id="heading-contact-us"><strong>Contact Us</strong></h2>
<p>If you have any questions about this Privacy Policy, You can contact us:</p>
<ul>
<li>By email: vpdevs88@gmail.com</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Shared Flow and State Flow]]></title><description><![CDATA[In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about State Flow and Shared Flow.
Shared Flow

shares emitted value to all collectors in a broadcast way

all collectors receives all emitted values...]]></description><link>https://www.vigneshprabhu.dev/shared-flow-and-state-flow</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/shared-flow-and-state-flow</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[kotlin coroutines]]></category><category><![CDATA[kotlin-flow]]></category><category><![CDATA[android apps]]></category><category><![CDATA[Android Studio]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Thu, 16 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725746717650/829dd934-1486-4278-8bdd-609980c616f2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about State Flow and Shared Flow.</p>
<h1 id="heading-shared-flow">Shared Flow</h1>
<ul>
<li><p>shares emitted value to all collectors in a broadcast way</p>
</li>
<li><p>all collectors receives all emitted values</p>
</li>
<li><p>This flow is active regardless of active collectors</p>
</li>
</ul>
<p>You can customize the <code>SharedFlow</code> behavior in the following ways:</p>
<ul>
<li><p><code>replay</code> lets you resend a number of previously-emitted values for new subscribers.</p>
</li>
<li><p><code>onBufferOverflow</code> lets you specify a policy for when the buffer is full of items to be sent. The default value is <code>BufferOverflow.SUSPEND</code>, which makes the caller suspend. Other options are <code>DROP_LATEST</code> or <code>DROP_OLDEST</code>.</p>
</li>
</ul>
<p>Code gist can be found in <a target="_blank" href="https://gist.github.com/vprabhu/adf153e7f3cbe6f5c39a4efe2c5d3400">https://gist.github.com/vprabhu/adf153e7f3cbe6f5c39a4efe2c5d3400</a></p>
<h1 id="heading-state-flows">State Flows</h1>
<ul>
<li><p>emits a single updated value to its collectors</p>
</li>
<li><p>current value can be accessed using <code>value</code> property</p>
</li>
</ul>
<h3 id="heading-update"><code>update{...}</code></h3>
<ul>
<li><p>thread safe function to change the state</p>
</li>
<li><p>excepts a block of code and this code block result is updated to <code>value</code> property which turns to be the updated value and this valueis emitted to all collectors</p>
</li>
</ul>
<p>Code gist can be found in <a target="_blank" href="https://gist.github.com/vprabhu/3473f8c69375ba6271b57d426fcfacfd">https://gist.github.com/vprabhu/3473f8c69375ba6271b57d426fcfacfd</a></p>
<p><strong>Please leave your comments to improve and discuss more</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Cold and Hot Flows]]></title><description><![CDATA[In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Cold and Hot Flows
Cold Flow

Flows created with flow builders are cold by default

Properties

Becomes active on terminal operators(like coll...]]></description><link>https://www.vigneshprabhu.dev/cold-and-hot-flows</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/cold-and-hot-flows</guid><category><![CDATA[Android]]></category><category><![CDATA[android app development]]></category><category><![CDATA[android apps]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[kotlin-flow]]></category><category><![CDATA[kotlin coroutines]]></category><category><![CDATA[coroutines]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Tue, 14 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725402587172/88db334f-012a-4ec4-8717-75887a84a1ee.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Cold and Hot Flows</p>
<h3 id="heading-cold-flow">Cold Flow</h3>
<ul>
<li>Flows created with flow builders are cold by default</li>
</ul>
<p><strong>Properties</strong></p>
<ul>
<li><p>Becomes active on terminal operators(like collect , first, last ....)</p>
</li>
<li><p>Becomes inactive when cancelling the collecting coroutine</p>
</li>
<li><p>They emit individual emissions to every collector</p>
</li>
<li><p>Emission and Collection are happening in same coroutines</p>
</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">suspend</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Unit</span> = coroutineScope {

    launch {
        println(<span class="hljs-string">"Collector 1 in <span class="hljs-subst">${Thread.currentThread().name}</span>"</span>)
        simpleFlow().collect { value -&gt;
            println(<span class="hljs-string">"Collecting from Collector 1 -&gt; <span class="hljs-variable">$value</span>"</span>)
        }
    }

    launch {
        println(<span class="hljs-string">"Collector 2 in <span class="hljs-subst">${Thread.currentThread().name}</span>"</span>)
        simpleFlow().collect { value -&gt;
            println(<span class="hljs-string">"Collecting from Collector 2 -&gt; <span class="hljs-variable">$value</span>"</span>)
        }
    }
}


<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">simpleFlow</span><span class="hljs-params">()</span></span> = flow {
    println(<span class="hljs-string">"Emission in <span class="hljs-subst">${Thread.currentThread().name}</span>"</span>)
    repeat(<span class="hljs-number">3</span>){
        kotlinx.coroutines.delay(<span class="hljs-number">250</span>)
        println(<span class="hljs-string">"Emitting <span class="hljs-variable">$it</span>"</span>)
        emit(it)
    }
}

<span class="hljs-comment">/**
 * output
 * Collector 1 in DefaultDispatcher-worker-2
 * Collector 2 in DefaultDispatcher-worker-1
 * Emission in DefaultDispatcher-worker-2
 * Emission in DefaultDispatcher-worker-1
 * Emitting 0
 * Emitting 0
 * Collecting from Collector 1 -&gt; 0
 * Collecting from Collector 2 -&gt; 0
 * Emitting 1
 * Emitting 1
 * Collecting from Collector 2 -&gt; 1
 * Collecting from Collector 1 -&gt; 1
 * Emitting 2
 * Emitting 2
 * Collecting from Collector 2 -&gt; 2
 * Collecting from Collector 1 -&gt; 2
 */</span>
</code></pre>
<p><strong>In above code , we can observe the following</strong></p>
<ul>
<li><p><strong>Emissions and collectors are running in same coroutine</strong></p>
</li>
<li><p><strong>Individual Emissions for every collectors</strong></p>
</li>
</ul>
<p>Code can be found in<a target="_blank" href="https://gist.github.com/vprabhu/69d912d7dfb8751badd26dff1d8eba1a">https://gist.github.com/vprabhu/69d912d7dfb8751badd26dff1d8eba1a</a></p>
<h3 id="heading-hot-flow">Hot Flow</h3>
<ul>
<li>are active regardless of existence of collectors</li>
</ul>
<p><strong>Properties</strong></p>
<ul>
<li><p>values that got emitted after we start collecting are the ones we will collect , it is possible to lose some emissions</p>
</li>
<li><p>stays active even when is no collectors</p>
</li>
<li><p>Emissions and collections are happening in different coroutines</p>
</li>
</ul>
<p><strong>Types of Hot Flow</strong></p>
<p>1.Shared Flow</p>
<p>2.State Flow</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">suspend</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Unit</span> = coroutineScope {

    <span class="hljs-keyword">val</span> sharedFlow = MutableSharedFlow&lt;<span class="hljs-built_in">Int</span>&gt;()

    launch {
        println(<span class="hljs-string">"Emitting in <span class="hljs-subst">${Thread.currentThread().name}</span>"</span>)
        repeat(<span class="hljs-number">3</span>) {
            kotlinx.coroutines.delay(<span class="hljs-number">250</span>)
            println(<span class="hljs-string">"Emitting <span class="hljs-variable">$it</span>"</span>)
            sharedFlow.emit(it)
        }
    }

    launch {
        println(<span class="hljs-string">"Collector 1 in <span class="hljs-subst">${Thread.currentThread().name}</span>"</span>)
        delay(<span class="hljs-number">550</span>)
        sharedFlow.collect { value -&gt;
            println(<span class="hljs-string">"Collecting from Collector 1 -&gt; <span class="hljs-variable">$value</span>"</span>)
        }
    }

    launch {
        println(<span class="hljs-string">"Collector 2 in <span class="hljs-subst">${Thread.currentThread().name}</span>"</span>)
        sharedFlow.collect { value -&gt;
            println(<span class="hljs-string">"Collecting from Collector 2 -&gt; <span class="hljs-variable">$value</span>"</span>)
        }
    }
}

<span class="hljs-comment">/**
 * output :
 * Emitting in DefaultDispatcher-worker-2
 * Collector 1 in DefaultDispatcher-worker-1
 * Collector 2 in DefaultDispatcher-worker-3
 * Emitting 0
 * Collecting from Collector 2 -&gt; 0
 * Emitting 1
 * Collecting from Collector 2 -&gt; 1
 * Emitting 2
 * Collecting from Collector 1 -&gt; 2
 * Collecting from Collector 2 -&gt; 2
 *
 *
 */</span>
</code></pre>
<p><strong>In above code , we can observe the following</strong></p>
<ul>
<li><p><strong>Emission and Collectors are happening in different coroutines</strong></p>
</li>
<li><p><strong>we can see in output where Collector 2 is the only one which collects all emissions and Collector 1 has missed emissions</strong></p>
</li>
</ul>
<p>Code can be found in <a target="_blank" href="https://gist.github.com/vprabhu/30f210ce4f9e8a3b89b2b92416e53493">https://gist.github.com/vprabhu/30f210ce4f9e8a3b89b2b92416e53493</a></p>
<p>In the next article , we will discuss about State Flow and Shared Flow.</p>
<p><strong>Please leave your comments to improve and discuss more</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Flow Cancellation]]></title><description><![CDATA[In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flow Cancellation.
There are 2 ways to cancel the flow
1.Cancel the coroutine job
    // cancel the job
    val job = launch {
        sampleF...]]></description><link>https://www.vigneshprabhu.dev/flow-cancellation</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/flow-cancellation</guid><category><![CDATA[Android]]></category><category><![CDATA[android app development]]></category><category><![CDATA[android apps]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin-flow]]></category><category><![CDATA[kotlin coroutines]]></category><category><![CDATA[KMM]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Sun, 12 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724993503296/9c8aeaf0-0841-4671-959e-2e496861d60e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flow Cancellation.</p>
<p>There are 2 ways to cancel the flow</p>
<h3 id="heading-1cancel-the-coroutine-job">1.Cancel the coroutine job</h3>
<pre><code class="lang-kotlin">    <span class="hljs-comment">// cancel the job</span>
    <span class="hljs-keyword">val</span> job = launch {
        sampleFlow()
            .onCompletion { cause -&gt;
                <span class="hljs-keyword">if</span> (cause <span class="hljs-keyword">is</span> CancellationException) {
                    println(<span class="hljs-string">"Flow cancelled Manually by job "</span>)
                }
            }
            .collect {
                println(<span class="hljs-string">"Type 1 Received <span class="hljs-variable">$it</span>"</span>)
            }
    }

    delay(<span class="hljs-number">550</span>)
    job.cancel()
<span class="hljs-comment">/**
     * Output :
     * Type 1 Received 1
     * Type 1 Received 3
     * Flow cancelled Manually by job
     */</span>
</code></pre>
<h3 id="heading-2cancel-in-scope">2.Cancel in scope</h3>
<pre><code class="lang-kotlin"><span class="hljs-comment">// cancel the code in scope</span>
launch {
    sampleFlow()
        .onCompletion { cause -&gt;
            <span class="hljs-keyword">if</span> (cause <span class="hljs-keyword">is</span> CancellationException) {
                println(<span class="hljs-string">"Flow cancelled Manually in scope"</span>)
            }
        }.collect {
            println(<span class="hljs-string">"Type 2 Received <span class="hljs-variable">$it</span>"</span>)
            <span class="hljs-keyword">if</span> (it == <span class="hljs-number">3</span>) {
                cancel()
            }
        }
}.join()
<span class="hljs-comment">/**
     * Output :
     * Type 2 Received 1
     * Type 2 Received 3
     * Flow cancelled Manually in scope
     */</span>
</code></pre>
<p>Code gist for 2 types of cancelling can be found in <a target="_blank" href="https://gist.github.com/vprabhu/ebce4cf922f50325f3f82b400681c0ac">https://gist.github.com/vprabhu/ebce4cf922f50325f3f82b400681c0ac</a></p>
<h3 id="heading-cooperative-cancellation">Cooperative Cancellation</h3>
<ul>
<li><p>All suspend function in coroutines are <code>cancellable</code></p>
</li>
<li><p>They check for coroutine cancellation internally and throw <code>CancellationException</code> when cancelled</p>
</li>
<li><p>But if a coroutine is not checking for cancellation when working on its job , then it is non-cancellable .</p>
</li>
</ul>
<h3 id="heading-behaviour-of-flowof-when-cancelling">Behaviour of flowOf() when cancelling</h3>
<p><code>flowOf()</code> doesn't check internally if the coroutine is active</p>
<ul>
<li><pre><code class="lang-kotlin">        launch {
            flowOf(<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>)
                .onCompletion { cause -&gt;
                    <span class="hljs-keyword">if</span> (cause <span class="hljs-keyword">is</span> CancellationException) {
                        println(<span class="hljs-string">"Flow cancelled <span class="hljs-variable">$cause</span>"</span>)
                    }
                }
                .collect {
                    println(<span class="hljs-string">"Received <span class="hljs-variable">$it</span>"</span>)
                    <span class="hljs-keyword">if</span> (it == <span class="hljs-number">3</span>) {
                        cancel()
                    }
                }
        }.join()

        <span class="hljs-comment">/**
         * output :
         * Received 1
         * Received 3
         * Received 5
         */</span>
</code></pre>
<p>  In the above code , even when you are cancelling the flow if the value is 3 inside the <code>collect{}</code> block , its not stopping the flow.</p>
<p>  There are 2 ways to check that</p>
</li>
</ul>
<p>1.<code>ensureActive()</code> in <code>onEach()</code> block</p>
<pre><code class="lang-kotlin"> launch {
        flowOf(<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>)
            .onCompletion { cause -&gt;
                <span class="hljs-keyword">if</span> (cause <span class="hljs-keyword">is</span> CancellationException) {
                    println(<span class="hljs-string">"Flow cancelled <span class="hljs-variable">$cause</span>"</span>)
                }
            }.onEach {
                ensureActive()
            }
            .collect {
                println(<span class="hljs-string">"Received <span class="hljs-variable">$it</span>"</span>)
                <span class="hljs-keyword">if</span> (it == <span class="hljs-number">3</span>) {
                    cancel()
                }
            }
    }.join()

    <span class="hljs-comment">/**
     * output : 
     * Received 1
     * Received 3
     * Flow cancelled kotlinx.coroutines.JobCancellationException:
     *   StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@635a732e
     */</span>
</code></pre>
<p>2.<code>cancellable()</code></p>
<pre><code class="lang-kotlin"> launch {
        flowOf(<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>)
            .onCompletion { cause -&gt;
                <span class="hljs-keyword">if</span> (cause <span class="hljs-keyword">is</span> CancellationException) {
                    println(<span class="hljs-string">"Flow cancelled <span class="hljs-variable">$cause</span>"</span>)
                }
            }
            .cancellable()
            .collect {
                println(<span class="hljs-string">"Received <span class="hljs-variable">$it</span>"</span>)
                <span class="hljs-keyword">if</span> (it == <span class="hljs-number">3</span>) {
                    cancel()
                }
            }
    }.join()

    <span class="hljs-comment">/**
     * output :
     * Received 1
     * Received 3
     * Flow cancelled kotlinx.coroutines.JobCancellationException:
     *   StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@635a732e
     */</span>
</code></pre>
<p>Code gist for 2 types of cancelling in the <code>flowOf()</code> can be found in <a target="_blank" href="https://gist.github.com/vprabhu/1a9defc5e8decffc619b5ed746b43d17">https://gist.github.com/vprabhu/1a9defc5e8decffc619b5ed746b43d17</a></p>
<blockquote>
<p>When the flow is working on something intensive , we can use <code>ensureActive()</code> inside the function to cancel it. Let me know if you need a sample code .</p>
</blockquote>
<p>In the next article , we will discuss about Cold Flow and Hot Flow.</p>
<p><strong>Please leave your comments to improve and discuss more</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Flow Intermediate Operator]]></title><description><![CDATA[In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flows Intermediate Operators
Code : https://gist.github.com/vprabhu/04cd8f6eaeecaf0d3de72049d023eddf
Sample Android App :
Code : https://githu...]]></description><link>https://www.vigneshprabhu.dev/flow-intermediate-operator</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/flow-intermediate-operator</guid><category><![CDATA[Android]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[kotlin coroutines]]></category><category><![CDATA[kotlin-flow]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Fri, 10 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724128883401/7a28174a-e4ab-430e-b25c-b30703c8fa67.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flows Intermediate Operators</p>
<p>Code : <a target="_blank" href="https://gist.github.com/vprabhu/04cd8f6eaeecaf0d3de72049d023eddf">https://gist.github.com/vprabhu/04cd8f6eaeecaf0d3de72049d023eddf</a></p>
<h3 id="heading-sample-android-app">Sample Android App :</h3>
<p>Code : <a target="_blank" href="https://github.com/vprabhu/FlowUpdateUI/">https://github.com/vprabhu/FlowUpdateUI/</a></p>
<p>This simple android app demos how to update compose UI ( Progress bar and result text) with the help of flow operators .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724130154892/8b927725-1432-464c-b520-b1671128aee4.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-what-is-intermediate-operators">What is Intermediate Operators?</h3>
<ul>
<li><p>These operators can transform the flow</p>
</li>
<li><p>These operators are applied to upstream flow and return a downstream flow</p>
</li>
<li><p>These operators are not suspending function means it executes instantly and return a new transformed flow.</p>
</li>
</ul>
<p>In this article ,we will learn about most used operators in Android app development.</p>
<h3 id="heading-onstart"><code>onStart()</code></h3>
<p><strong>Syntax:</strong></p>
<p><code>fun &lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-start.html"><code>T</code></a><code>&gt;</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html"><code>Flow</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-start.html"><code>T</code></a><code>&gt;.</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-start.html"><code>onStart</code></a><code>(action: suspend</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow-collector/index.html"><code>FlowCollector</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-start.html"><code>T</code></a><code>&gt;.() -&gt;</code> <a target="_blank" href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html"><code>Unit</code></a><code>):</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html"><code>Flow</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-start.html"><code>T</code></a><code>&gt;(</code><a target="_blank" href="https://github.com/kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators/Emitters.kt#L70"><code>source</code></a><code>)</code></p>
<p>As we can see from above syntax ,</p>
<p>The <code>action</code> block is executed before the collection of flow and this is called before the upstream starts</p>
<h3 id="heading-oneach"><code>onEach()</code></h3>
<p><strong>Syntax:</strong></p>
<p><code>fun &lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-each.html"><code>T</code></a><code>&gt;</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html"><code>Flow</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-each.html"><code>T</code></a><code>&gt;.</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-each.html"><code>onEach</code></a><code>(action: suspend (</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-each.html"><code>T</code></a><code>) -&gt;</code> <a target="_blank" href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html"><code>Unit</code></a><code>):</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html"><code>Flow</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-each.html"><code>T</code></a><code>&gt;(</code><a target="_blank" href="https://github.com/kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators/Transform.kt#L74"><code>source</code></a><code>)</code></p>
<ul>
<li><p>As the name implies , this operator is executed on emission of each value</p>
</li>
<li><p>returns a flow after executing the action on each value/item from the upstream flow to downstream flow</p>
</li>
</ul>
<h3 id="heading-oncompleted"><code>onCompleted()</code></h3>
<p><strong>Syntax:</strong></p>
<p><code>fun &lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-completion.html"><code>T</code></a><code>&gt;</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html"><code>Flow</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-completion.html"><code>T</code></a><code>&gt;.</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-completion.html"><code>onCompletion</code></a><code>(action: suspend</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow-collector/index.html"><code>FlowCollector</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-completion.html"><code>T</code></a><code>&gt;.(cause:</code> <a target="_blank" href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html"><code>Throwable</code></a><code>?) -&gt;</code> <a target="_blank" href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html"><code>Unit</code></a><code>):</code> <a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html"><code>Flow</code></a><code>&lt;</code><a target="_blank" href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/on-completion.html"><code>T</code></a><code>&gt;(</code><a target="_blank" href="https://github.com/kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-core/common/src/flow/operators/Emitters.kt#L140"><code>source</code></a><code>)</code></p>
<ul>
<li><p>As the name implies , this operator is executed after the flow is completed or cancelled.</p>
</li>
<li><p><code>cause:Throwable</code> -&gt; this return null when the flow is completed and the same will return exception if the flow is cancelled .</p>
</li>
</ul>
<p>In the next article , we will discuss about Flow Cancellation.</p>
<p><strong>Please leave your comments to improve and discuss more</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Flow Exception Handling]]></title><description><![CDATA[In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flows Exception handling
try/catch operator

We can simply enclose the collect block with try/catch as follows

suspend fun main(): Unit = cor...]]></description><link>https://www.vigneshprabhu.dev/flow-exception-handling</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/flow-exception-handling</guid><category><![CDATA[Android]]></category><category><![CDATA[android app development]]></category><category><![CDATA[android apps]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[kotlin-flow]]></category><category><![CDATA[kotlin coroutines]]></category><category><![CDATA[KMM]]></category><category><![CDATA[Kotlin Multiplatform]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Thu, 09 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723961138517/fbb10f8d-dd62-40a1-b745-49315dfff132.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flows Exception handling</p>
<h3 id="heading-trycatch-operator">try/catch operator</h3>
<ul>
<li>We can simply enclose the collect block with try/catch as follows</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">suspend</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Unit</span> = coroutineScope {

    launch {
        <span class="hljs-keyword">val</span> brandFlow = brandFlow()
        <span class="hljs-keyword">try</span> {
            brandFlow.collect { name -&gt;
                println(name)
            }
        } <span class="hljs-keyword">catch</span> (ex: Exception) {
            println(<span class="hljs-string">"Caught Exception <span class="hljs-variable">$ex</span>"</span>)
        }
    }
}


<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">brandFlow</span><span class="hljs-params">()</span></span> = flow {
    emit(<span class="hljs-string">"Google Pixel"</span>)
    emit(<span class="hljs-string">"Samsung"</span>)
    emit(<span class="hljs-string">"Apple"</span>)

    <span class="hljs-keyword">throw</span> Exception(<span class="hljs-string">"Anonymous Exception"</span>)
}
</code></pre>
<p>What happens if an exception is thrown in collect block , one option is to use try/catch block which might make the code more complex .</p>
<blockquote>
<p>Call to emit() internally leads to the execution of collect block (Flows under the hood)</p>
</blockquote>
<h3 id="heading-oneach">OnEach()</h3>
<ul>
<li><p>Returns a flow that invokes the given action before each value of the upstream flow is emitted downstream.</p>
</li>
<li><p>Adding this operator before catch{...} block ensures that all the exception are caught and the collect{...} will be empty as we see in the below code</p>
</li>
</ul>
<h3 id="heading-exception-transparency">Exception Transparency</h3>
<p>1.A Downstream exception must always be propagated to collector</p>
<p>2.Once an uncaught exception is thrown downstream , the flow isn't allowed to emit additional values</p>
<blockquote>
<p>use catch operator instead of try/catch block</p>
</blockquote>
<h3 id="heading-catch">catch()</h3>
<ul>
<li><p>only catches upstream exception and passes all downstream exceptions</p>
</li>
<li><p>use this operator to follow the exception transparency principle .</p>
</li>
<li><p>When flow builder throws exception , the applied operators will be stopped</p>
</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">suspend</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Unit</span> = coroutineScope {

    launch {
        <span class="hljs-keyword">val</span> brandFlow = brandFlow()
        brandFlow
            .onEach { name -&gt;
                println(name)
            }
            .<span class="hljs-keyword">catch</span> { cause -&gt;
                println(<span class="hljs-string">"Caught Exception : <span class="hljs-variable">$cause</span>"</span>)
            }
            .collect{}
    }
}


<span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">brandFlow</span><span class="hljs-params">()</span></span> = flow {
    emit(<span class="hljs-string">"Google Pixel"</span>)
    emit(<span class="hljs-string">"Samsung"</span>)
    <span class="hljs-keyword">throw</span> Exception(<span class="hljs-string">"Anonymous Exception"</span>)
    emit(<span class="hljs-string">"Apple"</span>)
}
</code></pre>
<p>Please run and play with above Kotlin codes to understand it in a better way .Just copy and paste it in a kotlin file .</p>
<p>In the next article , we will discuss about Flow intermediate operators .</p>
<p><strong>Please leave your comments to improve and discuss more</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Flow Terminal Operators]]></title><description><![CDATA[In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flows Terminal operators
Code gist can be found in https://gist.github.com/vprabhu/20bf26e73451ae9ea0876e3780537d4a
Whats is Terminal Operator...]]></description><link>https://www.vigneshprabhu.dev/flow-terminal-operators</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/flow-terminal-operators</guid><category><![CDATA[Terminal Operators]]></category><category><![CDATA[Android]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[flow]]></category><category><![CDATA[kotlin coroutines]]></category><category><![CDATA[kotlin-flow]]></category><category><![CDATA[compose multiplatform]]></category><category><![CDATA[android app development]]></category><category><![CDATA[android apps]]></category><category><![CDATA[Android Studio]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Tue, 07 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723739870870/51e6cf4e-1f89-4246-a893-816bdc3a32c2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this series of articles , we are discussing about Kotlin flows and in this article we will discuss about Flows Terminal operators</p>
<p>Code gist can be found in <a target="_blank" href="https://gist.github.com/vprabhu/20bf26e73451ae9ea0876e3780537d4a">https://gist.github.com/vprabhu/20bf26e73451ae9ea0876e3780537d4a</a></p>
<h2 id="heading-whats-is-terminal-operators">Whats is Terminal Operators?</h2>
<ul>
<li><p>Its a suspend function</p>
</li>
<li><p>Starts the flow's collection</p>
</li>
</ul>
<hr />
<h1 id="heading-terminal-operators-list">Terminal Operators List</h1>
<p>There are some terminal operators which we can used to start the collection of the flow</p>
<h3 id="heading-collect">Collect()</h3>
<ul>
<li><p>collects the given flow</p>
</li>
<li><p>commonly used with onEach() , onCompletion() and catch to collect all emitted values</p>
<pre><code class="lang-kotlin">  <span class="hljs-keyword">val</span> flow = flow {
      delay(<span class="hljs-number">200</span>)
      emit(<span class="hljs-number">1</span>)

      delay(<span class="hljs-number">200</span>)
      emit(<span class="hljs-number">2</span>)

      delay(<span class="hljs-number">200</span>)
      emit(<span class="hljs-number">2</span>)
  }

    flow.collect { receivedValue -&gt;
              println(<span class="hljs-string">"Collect Received value 1: <span class="hljs-variable">$receivedValue</span>"</span>)
              <span class="hljs-comment">/** Output :
               * Collect Received value 1: 1
               * Collect Received value 1: 2
               * Collect Received value 1: 2
               */</span>
    }
</code></pre>
</li>
</ul>
<h3 id="heading-first-and-last">first() and last()</h3>
<ul>
<li><p>first() returns the first element emitted by flow and cancels the flow's cancellation.</p>
</li>
<li><p>last() returns the last element emitted by the flow.</p>
</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> itemFirst = flow.first()
println(<span class="hljs-string">"first() flow : <span class="hljs-variable">$itemFirst</span>"</span>)
<span class="hljs-comment">/** Output :
 * first() flow : 1
 */</span>

<span class="hljs-keyword">val</span> itemLast = flow.last()
println(<span class="hljs-string">"last() flow : <span class="hljs-variable">$itemLast</span>"</span>)
<span class="hljs-comment">/**
 * last() flow : 2
 */</span>
</code></pre>
<h3 id="heading-single">single()</h3>
<ul>
<li><p>Collects the only and one value from flow</p>
</li>
<li><p>If flow emits multiple values , it throws the following error</p>
</li>
</ul>
<pre><code class="lang-kotlin">Exception <span class="hljs-keyword">in</span> thread <span class="hljs-string">"main"</span> java.lang.IllegalArgumentException: Flow has more than one element
</code></pre>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> singleFlow = flow {
        emit(<span class="hljs-string">"Single Emitted value"</span>)
    }

<span class="hljs-keyword">val</span> itemSingle = singleFlow.single()
println(<span class="hljs-string">"single() flow : <span class="hljs-variable">$itemSingle</span>"</span>) 
<span class="hljs-comment">/**
*  output : single() flow : Single Emitted value
*/</span>
</code></pre>
<h3 id="heading-toset">toSet()</h3>
<ul>
<li>converts the flow output to set</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> setFLow = flow.toSet()
println(<span class="hljs-string">"toSet() flow : <span class="hljs-variable">$setFLow</span>"</span>)
<span class="hljs-comment">/**
 * Output :  toSet() flow : [1, 2]
 */</span>
</code></pre>
<h3 id="heading-tolist">toList()</h3>
<ul>
<li>converts the flow to list</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> listFLow = flow.toList()
println(<span class="hljs-string">"toList() flow : <span class="hljs-variable">$listFLow</span>"</span>)
<span class="hljs-comment">/**
 * toList() flow : [1, 2, 2]
 */</span>
</code></pre>
<p>In the next article , we will discuss about Exception Handling in Flow.</p>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Handle Android Lifecycle methods inside composable function]]></title><description><![CDATA[Android Lifecycle
LifeCycle is a class from androidx.lifecycle package which helps us to get the information and observe on the lifecycle state of components like Activities and fragments
Two things to consider
1.State : Created,Started,Resumed,Destr...]]></description><link>https://www.vigneshprabhu.dev/handle-android-lifecycle-methods-inside-composable-function</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/handle-android-lifecycle-methods-inside-composable-function</guid><category><![CDATA[andriod]]></category><category><![CDATA[android app development]]></category><category><![CDATA[android apps]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[compose multiplatform]]></category><category><![CDATA[compose]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[Kotlin Multiplatform]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Mon, 06 May 2024 06:59:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1714978662298/3128162c-0a08-4a8d-99f1-548187b69532.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-android-lifecycle">Android Lifecycle</h2>
<p>LifeCycle is a class from androidx.lifecycle package which helps us to get the information and observe on the lifecycle state of components like Activities and fragments</p>
<p>Two things to consider</p>
<p>1.State : Created,Started,Resumed,Destroyed and Initialized</p>
<p>2.Event : ON_CREATE , ON_START, ON_RESUME,ON_PAUSE, ON_STOP and ON_DESTROY</p>
<p>As the legend diagram follows to explain the same</p>
<p><img src="https://developer.android.com/static/codelabs/android-fundamentals-02-2-activity-lifecycle-and-state/img/59d40f71d715436.png" alt="Diagram of the App Lifecycle" /></p>
<p>In Activities and fragments , there are methods expose from Activity() and Fragment() class to observe these lifecycle events to meet our requirements in UI. But in compose , there are no such methods to observe the lifecycle states and events which is in built with composable . In the following ways we can get to know the lifecycle state and events.</p>
<h2 id="heading-lifecycle-library">LifeCycle Library</h2>
<p><code>androidx.lifecycle</code> - includes APIs to observe and know the lifecycle state.</p>
<h2 id="heading-get-lifecycle-state-with-flows">Get Lifecycle State with Flows</h2>
<ul>
<li><p>Property from lifecycle which provides Lifecycle.State as a kotlin state flow</p>
</li>
<li><p>collect this flow as state</p>
</li>
<li><p>we can read these states during UI composition</p>
</li>
</ul>
<p>There are 2 ways to do this</p>
<p><code>1.currentStateFlow</code></p>
<ul>
<li>this is from <code>lifecycle-common</code> module</li>
</ul>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> stateFlow = LocalLifecycleOwner.current.lifecycle.currentStateFlow
 <span class="hljs-keyword">val</span> currentLifecycleState <span class="hljs-keyword">by</span> stateFlow.collectAsState()

 Log.d(<span class="hljs-string">"LifecycleScreen"</span>, <span class="hljs-string">"Lifecycle state: <span class="hljs-subst">${currentLifecycleState.name}</span>"</span>)
     <span class="hljs-comment">/*
     *  When launched -&gt;
     *                  LifecycleScreen: RESUMED
     *  When Back button tapped -&gt;
     *                  Lifecycle state: STARTED
     *  When Home button tapped -&gt;
     *                  Lifecycle state: STARTED
     *                  Lifecycle state: CREATED
     * When recent button tapped -&gt;
     *                  Lifecycle state: STARTED
     *                  Lifecycle state: CREATED
     *
     */</span>
</code></pre>
<p><code>2.currentStateAsState</code></p>
<ul>
<li><code>lifecycle-runtime-compose</code> - provides easy way to read current lifecycle state .</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> currentLifecycleState = LocalLifecycleOwner.current.lifecycle
                 .currentStateAsState()
Log.d(<span class="hljs-string">"LifecycleScreen"</span>, <span class="hljs-string">"Lifecycle state: <span class="hljs-subst">${currentLifecycleState.value}</span>"</span>)
    <span class="hljs-comment">/*
     *  When launched -&gt;
     *                  LifecycleScreen: RESUMED
     *  When Back button tapped -&gt;
     *                  Lifecycle state: STARTED
     *  When Home button tapped -&gt;
     *                  Lifecycle state: STARTED
     *                  Lifecycle state: CREATED
     * When recent button tapped -&gt;
     *                  Lifecycle state: STARTED
     *                  Lifecycle state: CREATED
     *
     */</span>
</code></pre>
<h2 id="heading-lifecycleeventeffect">LifecycleEventEffect</h2>
<ul>
<li>allows us to run a block of code when certain <code>Lifecycle.Event</code> occurs</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">LifecycleScreen</span><span class="hljs-params">()</span></span> {

    <span class="hljs-keyword">val</span> textValue = remember { mutableStateOf(<span class="hljs-string">""</span>) }

    Text(
        textValue.value,
        fontSize = <span class="hljs-number">32</span>.sp,
        modifier = Modifier.padding(<span class="hljs-number">32</span>.dp)
    )

    LifecycleEventEffect(Lifecycle.Event.ON_CREATE) {
        Log.d(<span class="hljs-string">"LifecycleScreen"</span>, <span class="hljs-string">"LifecycleScreen: The current state is ON_CREATE"</span>)
    }

    LifecycleEventEffect(Lifecycle.Event.ON_START) {
        Log.d(<span class="hljs-string">"LifecycleScreen"</span>, <span class="hljs-string">"LifecycleScreen: The current state is ON_START"</span>)
    }

    LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
        Log.d(<span class="hljs-string">"LifecycleScreen"</span>, <span class="hljs-string">"LifecycleScreen: The current state is ON_RESUME"</span>)
        textValue.value = <span class="hljs-string">"ON_RESUME"</span>
    }

    LifecycleEventEffect(Lifecycle.Event.ON_PAUSE) {
        Log.d(<span class="hljs-string">"LifecycleScreen"</span>, <span class="hljs-string">"LifecycleScreen: The current state is ON_PAUSE"</span>)
        textValue.value = <span class="hljs-string">"ON_PAUSE"</span>
    }

    LifecycleEventEffect(Lifecycle.Event.ON_STOP) {
        Log.d(<span class="hljs-string">"LifecycleScreen"</span>, <span class="hljs-string">"LifecycleScreen: The current state is ON_STOP"</span>)
    }

}
</code></pre>
<p>The logs are as follows</p>
<p>1.when the above compose is launched for first time ,</p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_CREATE</code></p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_START</code></p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_RESUME</code></p>
<p>2.When back button is pressed</p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_PAUSE</code></p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_STOP</code></p>
<p>3.When Home button is pressed</p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_PAUSE</code></p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_STOP</code></p>
<p>4.When Recent button is pressed</p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_PAUSE</code></p>
<p><code>LifecycleScreen D LifecycleScreen: The current state is ON_STOP</code></p>
<p>Whwn you add the following code and run the app</p>
<pre><code class="lang-kotlin">  LifecycleEventEffect(Lifecycle.Event.ON_DESTROY) {
        Log.d(
            <span class="hljs-string">"LifecycleScreen"</span>,
            <span class="hljs-string">"LifecycleScreen: The current state is ON_DESTROY"</span>
        )
    }
</code></pre>
<p>we will get this crash report</p>
<p>java.lang.IllegalArgumentException: LifecycleEventEffect cannot be used to listen for Lifecycle.Event.ON_DESTROY, since Compose disposes of the composition before ON_DESTROY observers are invoked.</p>
<h2 id="heading-lifecyclestarteffectamplifecycleresumeeffect">LifecycleStartEffect&amp;LifecycleResumeEffect</h2>
<ul>
<li><p>similar to LifecycleEventEffect but it runs only on ON_Start and ON_Resume Event</p>
</li>
<li><p>It takes key that behaves like any other compose keys i.e when key changes , it triggers the code block to run again</p>
</li>
<li><p>when the ON_Stop event triggered , it execute the onStopOrDispose block which helps us to clean up / free resource when this lifecycle event is triggered</p>
</li>
<li><p>when the ON_Pause event triggered , it execute the onPauseOrDispose block</p>
</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-meta">@Composable</span>
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">LifecycleScreen</span><span class="hljs-params">()</span></span> {

    LifecycleStartEffect() {
        Log.d(
            <span class="hljs-string">"LifecycleScreen"</span>,
            <span class="hljs-string">"LifecycleScreen: LifecycleStartEffect"</span>
        )
        onStopOrDispose {
            Log.d(
                <span class="hljs-string">"LifecycleScreen"</span>,
                <span class="hljs-string">"LifecycleScreen: onStopOrDispose"</span>
            )
        }
    }

    LifecycleResumeEffect() {
        Log.d(
            <span class="hljs-string">"LifecycleScreen"</span>,
            <span class="hljs-string">"LifecycleScreen: LifecycleResumeEffect"</span>
        )
        onPauseOrDispose {
            Log.d(
                <span class="hljs-string">"LifecycleScreen"</span>,
                <span class="hljs-string">"LifecycleScreen: onPauseOrDispose"</span>
            )
        }
    }
}
</code></pre>
<p>The Logs are as folows</p>
<p>1.When App launched for first time</p>
<p><code>LifecycleScreen D LifecycleScreen: LifecycleStartEffect</code></p>
<p><code>LifecycleScreen D LifecycleScreen: LifecycleResumeEffect</code></p>
<p>2.When Home Button is tapped</p>
<p><code>LifecycleScreen D LifecycleScreen: onPauseOrDispose</code></p>
<p><code>LifecycleScreen D LifecycleScreen: onStopOrDispose</code></p>
<p>3.When Recent button is tapped</p>
<p><code>LifecycleScreen D LifecycleScreen: onPauseOrDispose</code></p>
<p><code>LifecycleScreen D LifecycleScreen: onStopOrDispose</code></p>
<p>4.When back button is tapped</p>
<p><code>LifecycleScreen D LifecycleScreen: onPauseOrDispose</code></p>
<p><code>LifecycleScreen D LifecycleScreen: onStopOrDispose</code></p>
<p><code>LifecycleScreen D LifecycleScreen: onPauseOrDispose</code></p>
<p><code>LifecycleScreen D LifecycleScreen: onStopOrDispose</code></p>
<blockquote>
<p>As you can observe in the above log , when back button is pressed , the <code>onPauseOrDispose</code> and <code>onStopOrDispose</code> are executed twice(i think its a bug) in case of <code>LifecycleStartEffect</code> and <code>LifecycleResumeEffect</code> but this is not the case when we use <code>LifecycleEventEffect</code></p>
</blockquote>
<p>Please run the code once in each code block to get better understanding of this lifecycle events and states in compose .</p>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Kotlin Flow and Flow Builders]]></title><description><![CDATA[In this series of articles , we will discuss about Kotlin flows and in this article we will discuss about Flows and Flow Builders
Code gist can be found in https://gist.github.com/vprabhu/cf5f6407516f0bc97d764c7a9961e3cd
Whats is Flow ?
Already we kn...]]></description><link>https://www.vigneshprabhu.dev/kotlin-flow-and-flow-builders</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/kotlin-flow-and-flow-builders</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[android apps]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[kotlin coroutines]]></category><category><![CDATA[Flows]]></category><category><![CDATA[kotlin-flow]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Sun, 05 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723532430526/181ff175-388e-462c-bfa7-eed718a16c6e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this series of articles , we will discuss about Kotlin flows and in this article we will discuss about Flows and Flow Builders</p>
<p>Code gist can be found in <a target="_blank" href="https://gist.github.com/vprabhu/cf5f6407516f0bc97d764c7a9961e3cd">https://gist.github.com/vprabhu/cf5f6407516f0bc97d764c7a9961e3cd</a></p>
<h2 id="heading-whats-is-flow">Whats is Flow ?</h2>
<p>Already we know that suspend function asynchronously returns a single value .</p>
<p><strong>Flows can return multiple asynchronously computed values</strong></p>
<hr />
<h2 id="heading-flow-builders">Flow Builders</h2>
<p>we can build a flow using one of the following ways</p>
<ol>
<li><h3 id="heading-lttgt-flowofvalue-t"><strong>&lt;T&gt; flowOf(value : T)</strong></h3>
</li>
</ol>
<p>Creates a flow from fixed set of any values which is it can emit both a single type value and multiple data type values as follows</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
 * flowOf() -&gt; Create a flow from fixed set of values
 */</span>
<span class="hljs-keyword">val</span> singleValueFlow = flowOf&lt;<span class="hljs-built_in">Int</span>&gt;(<span class="hljs-number">578943</span>).collect { value -&gt;
    println(<span class="hljs-string">"Emitted Value : <span class="hljs-variable">$value</span>"</span>) <span class="hljs-comment">// output : 578943</span>
}

<span class="hljs-comment">/*
 * flowOf() -&gt; creating a flow with multiple data types
 */</span>
<span class="hljs-keyword">val</span> multiValueFlows = flowOf&lt;Any&gt;(<span class="hljs-number">23</span>, <span class="hljs-number">2.90</span>, <span class="hljs-literal">false</span>, <span class="hljs-string">"Android 1.0"</span>, <span class="hljs-number">09.2008</span>)

multiValueFlows.collect { value -&gt;
    println(<span class="hljs-string">"multiValueFlows -&gt;  Emitted Value : <span class="hljs-variable">$value</span>"</span>)
    <span class="hljs-comment">//output :</span>
    <span class="hljs-comment">//multiValueFlows -&gt;  Emitted Value : 23</span>
    <span class="hljs-comment">//multiValueFlows -&gt;  Emitted Value : 2.9</span>
    <span class="hljs-comment">//multiValueFlows -&gt;  Emitted Value : false</span>
    <span class="hljs-comment">//multiValueFlows -&gt;  Emitted Value : Android 1.0</span>
    <span class="hljs-comment">//multiValueFlows -&gt;  Emitted Value : 9.2008</span>
}
</code></pre>
<h3 id="heading-2lttgt-iterablelttgtasflow">2.&lt;T&gt; Iterable&lt;T&gt;.asFlow()</h3>
<p>Extension function for various types of iterators to convert them into flows and it cal also emit multiple data type values</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
 * asFlow() -&gt; extension function on various types to convert them into Flows
 */</span>
listOf(<span class="hljs-string">"A"</span>, <span class="hljs-string">"B"</span>, <span class="hljs-string">"C"</span>, <span class="hljs-number">4</span>, <span class="hljs-literal">true</span>, <span class="hljs-number">90.89</span>).asFlow().collect { value -&gt;
    println(<span class="hljs-string">"AsFlow Emitted Value : <span class="hljs-variable">$value</span>"</span>)
    <span class="hljs-comment">//output :</span>
    <span class="hljs-comment">//AsFlow Emitted Value : A</span>
    <span class="hljs-comment">//AsFlow Emitted Value : B</span>
    <span class="hljs-comment">//AsFlow Emitted Value : C</span>
    <span class="hljs-comment">//AsFlow Emitted Value : 4</span>
    <span class="hljs-comment">//AsFlow Emitted Value : true</span>
    <span class="hljs-comment">//AsFlow Emitted Value : 90.89</span>
}
</code></pre>
<h3 id="heading-3lttgt-flowblock-suspend-lttgt-gt-unit">3.&lt;T&gt; flow(block: suspend &lt;T&gt;.() -&gt; Unit)</h3>
<p>Creates a flow from suspendable code block given</p>
<pre><code class="lang-kotlin"><span class="hljs-comment">/**
 * flow {..} -&gt; creates a flow from the suspendable block given
 */</span>
flow {
    kotlinx.coroutines.delay(<span class="hljs-number">2000</span>)
    emit(<span class="hljs-number">890</span>)
    emit(returnSomething())
}.collect { value -&gt;
    println(<span class="hljs-string">"flow {} Emitted Value : <span class="hljs-variable">$value</span>"</span>)
    <span class="hljs-comment">// output :</span>
    <span class="hljs-comment">// flow {} Emitted Value : 890</span>
    <span class="hljs-comment">// flow {} Emitted Value : 340</span>
}

<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">returnSomething</span><span class="hljs-params">()</span></span>: <span class="hljs-built_in">Int</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-number">340</span>
}
</code></pre>
<p>Important Considerations:</p>
<p>Simply put</p>
<p><strong>collect{ .. } -&gt; T</strong>erminal flow operator that collects the given flow</p>
<p>emit() -&gt; Collects the value emitted by the upstream.</p>
<p>we will discuss this is further articles</p>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Compose - Bill of Materials(BOM)]]></title><description><![CDATA[In this article , lets discuss about Bill of Materials
Lets understand why we need BOM , then we will discuss what is BOM
Why BOM?

Compose libraries are version independently that is version number are maintained different for each library .

For de...]]></description><link>https://www.vigneshprabhu.dev/compose-bill-of-materialsbom</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/compose-bill-of-materialsbom</guid><category><![CDATA[compose]]></category><category><![CDATA[compose multiplatform]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[android development]]></category><category><![CDATA[Kotlin Multiplatform]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Thu, 07 Mar 2024 18:04:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709832171512/0f444bf9-889e-4115-8aa0-887cb64327ab.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , lets discuss about Bill of Materials</p>
<p>Lets understand why we need BOM , then we will discuss what is BOM</p>
<h2 id="heading-why-bom">Why BOM?</h2>
<ul>
<li><p>Compose libraries are version independently that is version number are maintained different for each library .</p>
</li>
<li><p>For developer , it is difficult to find the latest stable version for each library and add it in dependencies(module level gradle)</p>
<p>  <strong><em>Don't worry BOM is there to save us from this mess</em></strong></p>
</li>
</ul>
<h2 id="heading-what-is-bom">What is BOM?</h2>
<ul>
<li><p>Bill of Materials lets you manage all of our compose library versions by mentioning only the BOM version</p>
</li>
<li><p>BOM has link to all the stable version of different compose libraries to work well together</p>
</li>
<li><p>When we add BOM in our app , we don't have to mention version for any compose library</p>
</li>
<li><p>BOM just ensures that different compose library versions are compatible and it doesn't add any compose library in our app</p>
</li>
<li><p>When we update BOM version , all the compose library version mentioned in gradle are automatically updated to their newer/latest version</p>
</li>
</ul>
<h2 id="heading-bom-usage">BOM Usage</h2>
<pre><code class="lang-kotlin">    <span class="hljs-comment">// add BOM</span>
    implementation(platform(<span class="hljs-string">"androidx.compose:compose-bom:2024.02.01"</span>))
    <span class="hljs-comment">// add compose library without version number</span>
    implementation(<span class="hljs-string">"androidx.compose.ui:ui"</span>)
    implementation(<span class="hljs-string">"androidx.compose.ui:ui-graphics"</span>)
    implementation(<span class="hljs-string">"androidx.compose.ui:ui-tooling-preview"</span>)
    <span class="hljs-comment">// add a specific version which overrides BOM </span>
    implementation(<span class="hljs-string">"androidx.compose.material3:material3:1.2.1"</span>)
</code></pre>
<p>As we seen in above code , we can observe the following</p>
<ol>
<li><p><em>How to add compose-bom with version number</em></p>
</li>
<li><p><em>How to add compose library without version number</em></p>
</li>
<li><p><em>How to override desired compose library with our version</em></p>
</li>
</ol>
<h2 id="heading-bom-supported-compose-libraries">BOM supported compose libraries</h2>
<p>The following compose libraries and its group is linked to BOM</p>
<ul>
<li><p>compose.animation</p>
</li>
<li><p>compose.foundation</p>
</li>
<li><p>compose.material</p>
</li>
<li><p>compose.runtime</p>
</li>
<li><p>compose.ui</p>
  <div data-node-type="callout">
  <div data-node-type="callout-emoji">💡</div>
  <div data-node-type="callout-text">Kotlin complier externsion(androidx.compose.compiler) is not linked to BOM , as to make sure we use a version that is compatible to Kotlin version used in our app.</div>
  </div>


</li>
</ul>
<p>So finally, lets use the Compose - Bill of Materials<strong><em>(recommended not forced to use)</em></strong> and reduce our time to implement the latest versions of compose that work well together .</p>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Collections Part 5 : Retrieve Single Item from Collection]]></title><description><![CDATA[In this article , lets discuss about Kotlin Collections operation - retrieve single item from Collection using functions like elementAt() , first() , last() , random() , firstNotNullOf() and contains()

Foundation

List is an ordered collection which...]]></description><link>https://www.vigneshprabhu.dev/collections-part-5-retrieve-single-item-from-collection</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/collections-part-5-retrieve-single-item-from-collection</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[Android]]></category><category><![CDATA[android app development]]></category><category><![CDATA[android apps]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Sat, 11 Sep 2021 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1715067003433/70eb9aa4-4f85-4f63-848c-b509f4891bd7.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , lets discuss about Kotlin Collections operation - retrieve single item from Collection using functions like <code>elementAt() , first() , last() , random() , firstNotNullOf()</code> and <code>contains()</code></p>
<hr />
<h2 id="heading-foundation">Foundation</h2>
<ul>
<li><p>List is an ordered collection which means every item in has its position that you are referring</p>
</li>
<li><p>Set is an unordered collection which stores element in certain order based on <code>set</code> implementation which can be <code>LinkedHasSet</code> , <code>SortedSet</code> , etc . So results are predictable based on the set implementation used</p>
</li>
</ul>
<h2 id="heading-position">Position</h2>
<p><code>elementAt()</code></p>
<ul>
<li><p>retrieving item at specific position in given collection</p>
</li>
<li><p>called with <code>Int</code> argument</p>
</li>
<li><p>returns the collection item at given position</p>
</li>
</ul>
<p>useful for collections that don't provide indexed access</p>
<blockquote>
<p>In case of List , it has indexed access operator <code>get() / []</code></p>
</blockquote>
<p><code>first()</code> - returns first collection item</p>
<p><code>last()</code> - returns last collection item</p>
<p><code>elementAtOrNull()</code> - returns null when the given parameter position is out of bounds for collection</p>
<p><code>elementAtOrElse()</code></p>
<ul>
<li><p>takes lambda function that maps Int argument</p>
</li>
<li><p>returns one of the following</p>
<p>  1.returns <code>elementAt()</code> if the position passed is valid</p>
<p>  2.returns lambda function result if position is out of bounds</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> names = linkedSetOf(<span class="hljs-string">"Sam"</span>, <span class="hljs-string">"Dev"</span>, <span class="hljs-string">"David"</span>, <span class="hljs-string">"Katherine"</span>, <span class="hljs-string">"Anne"</span>, <span class="hljs-string">"Chris"</span>)
    println(names.elementAt(<span class="hljs-number">1</span>))
    <span class="hljs-comment">// output : Dev</span>

    println(names.first())
    <span class="hljs-comment">// output : Sam</span>
    println(names.last())
    <span class="hljs-comment">// output : Chris</span>

    println(names.elementAtOrNull(<span class="hljs-number">7</span>))
    <span class="hljs-comment">// output : null</span>

    <span class="hljs-keyword">val</span> result = names.elementAtOrElse(<span class="hljs-number">4</span>) { index -&gt;
        <span class="hljs-string">"The value at <span class="hljs-variable">$index</span> is invalid"</span>
    }
    println(result)
    <span class="hljs-comment">// output : Anne</span>
</code></pre>
<hr />
<h2 id="heading-condition">Condition</h2>
<p><code>first() with predicate</code> - returns the first item matching the predicate in given collection</p>
<p><code>last() with predicate</code> - returns the last item matching the predicate in given collection</p>
<p>if no items are matching the predicate , then both <code>first()</code> and <code>last()</code> throw exceptions</p>
<p>in those exception cases , we can use <code>firstOrNull()</code> and <code>lastOrNull()</code> which returns null if predicate is not matching with any items in given collection</p>
<p><code>find()</code> can be used instead of <code>firstOrNull()</code></p>
<p><code>findLast()</code> can be used instead of <code>lastOrNull()</code></p>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> names = linkedSetOf(<span class="hljs-string">"Sam"</span>, <span class="hljs-string">"Dev"</span>, <span class="hljs-string">"David"</span>, <span class="hljs-string">"Katherine"</span>, <span class="hljs-string">"Anne"</span>, <span class="hljs-string">"Chris"</span>)

    println(names.first {
        it.length &gt; <span class="hljs-number">5</span>
    })
    <span class="hljs-comment">// output : Katherine</span>

    println(names.last{
        it.endsWith(<span class="hljs-string">"id"</span>)
    })
    <span class="hljs-comment">// output : David</span>

    println(names.firstOrNull{
        it.contains(<span class="hljs-string">"Ae"</span>)
    })
    <span class="hljs-comment">// output : null</span>

    println(names.lastOrNull(){
        it.length&gt;<span class="hljs-number">15</span>
    })
    <span class="hljs-comment">// output : null</span>

    println(names.find {
        it.length &gt; <span class="hljs-number">6</span>
    })
    <span class="hljs-comment">// output : Katherine</span>

    println(names.findLast {
        it.endsWith(<span class="hljs-string">"is"</span>)
    })
    <span class="hljs-comment">// output : Chris</span>
</code></pre>
<hr />
<h2 id="heading-selection">Selection</h2>
<p><code>firstNotNullOf()</code></p>
<ul>
<li><p>maps the given collection with selector function</p>
</li>
<li><p>returns the first non null value of mapped collection</p>
</li>
</ul>
<p><code>firstNotNullOfOrNull()</code></p>
<ul>
<li><code>firstNotNullOf()</code> throws <code>NoSuchElementException</code> if the result is null</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> names = linkedSetOf(<span class="hljs-string">"Sam"</span>, <span class="hljs-string">"Dev"</span>, <span class="hljs-string">"David"</span>, <span class="hljs-string">"Katherine"</span>, <span class="hljs-string">"Anne"</span>, <span class="hljs-string">"Chris"</span>)

    <span class="hljs-keyword">val</span> resultOne = names.firstNotNullOf { item -&gt;
        item.length.takeIf { it &gt; <span class="hljs-number">6</span> }
    }
    println(resultOne)
    <span class="hljs-comment">// output : 9</span>

    <span class="hljs-keyword">val</span> resultTwo = names.firstNotNullOfOrNull { item -&gt;
        item.length.takeIf { it &gt; <span class="hljs-number">10</span> }
    }
    println(resultTwo)
    <span class="hljs-comment">// output : null</span>
</code></pre>
<hr />
<h2 id="heading-random">Random</h2>
<p><code>random()</code> - gets a random item in collection</p>
<p><code>randomOrNull()</code> - returns null if the given collection is empty</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> names = linkedSetOf(<span class="hljs-string">"Sam"</span>, <span class="hljs-string">"Dev"</span>, <span class="hljs-string">"David"</span>, <span class="hljs-string">"Katherine"</span>, <span class="hljs-string">"Anne"</span>, <span class="hljs-string">"Chris"</span>)

    println(names.random())

    <span class="hljs-keyword">val</span> empty = linkedSetOf&lt;String&gt;()
    <span class="hljs-comment">// println(empty.random())</span>
    <span class="hljs-comment">// output = Exception in thread </span>
    <span class="hljs-comment">// "main" java.util.NoSuchElementException:</span>
    <span class="hljs-comment">//  Collection is empty.</span>

    println(empty.randomOrNull())
    <span class="hljs-comment">// output : null</span>
</code></pre>
<h2 id="heading-contains">Contains</h2>
<p><code>contains()</code></p>
<ul>
<li><p>checks if the item is in collection</p>
</li>
<li><p>returns true if the item matches the function argument</p>
</li>
<li><p>use <code>in</code> keyword for operator form of <code>contains()</code></p>
</li>
</ul>
<p><code>containsAll()</code></p>
<ul>
<li>check multiple items together in given collection</li>
</ul>
<p><code>isEmpty()</code> / <code>isNotEmpty()</code></p>
<ul>
<li>to check if the collection contains any element</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> names = linkedSetOf(<span class="hljs-string">"Sam"</span>, <span class="hljs-string">"Dev"</span>, <span class="hljs-string">"David"</span>, <span class="hljs-string">"Katherine"</span>, <span class="hljs-string">"Anne"</span>, <span class="hljs-string">"Chris"</span>)

    println(names.contains(<span class="hljs-string">"Sam"</span>))
    <span class="hljs-comment">// output : true</span>

    println(<span class="hljs-string">"Anne"</span> <span class="hljs-keyword">in</span> names)
    <span class="hljs-comment">// output : true</span>

    println(names.containsAll(listOf(<span class="hljs-string">"David"</span>, <span class="hljs-string">"Bob"</span>)))
    <span class="hljs-comment">// output : false</span>
    println(names.containsAll(listOf(<span class="hljs-string">"David"</span>, <span class="hljs-string">"Chris"</span>)))
    <span class="hljs-comment">// output : true</span>

    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>)
    println(numbers.isEmpty())
    <span class="hljs-comment">// output : false</span>
    println(numbers.isNotEmpty())
    <span class="hljs-comment">// output : true</span>

    <span class="hljs-keyword">val</span> emptyList = emptyList&lt;String&gt;()
    println(emptyList.isEmpty())
    <span class="hljs-comment">// output : true</span>
    println(emptyList.isNotEmpty())
    <span class="hljs-comment">// output : false</span>
</code></pre>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Collections Operations - Part 4 : Retrieving  parts of Collection]]></title><description><![CDATA[In this article , lets discuss about Kotlin Collections operation - Retrieving parts of Collection using functions like slice , drop , take , windowed and chunked

Slice

returns the collection elements with the given indices in List<T>

we can slice...]]></description><link>https://www.vigneshprabhu.dev/collections-operations-part-4-retrieving-parts-of-collection</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/collections-operations-part-4-retrieving-parts-of-collection</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[compose]]></category><category><![CDATA[android apps]]></category><category><![CDATA[android development]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Fri, 10 Sep 2021 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1713532943040/f45e2a50-f725-4ef1-b984-91acf7ed3b97.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , lets discuss about Kotlin Collections operation - Retrieving parts of Collection using functions like <code>slice</code> , <code>drop</code> , <code>take</code> , <code>windowed</code> and <code>chunked</code></p>
<hr />
<h2 id="heading-slice">Slice</h2>
<ul>
<li>returns the collection elements with the given indices in <code>List&lt;T&gt;</code></li>
</ul>
<p>we can slice with range values , range values with step count and we can do <code>setOf()</code> and <code>listOf()</code> also as follows</p>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">9</span>)
    <span class="hljs-comment">// slice int range</span>
    println(numbers.slice(<span class="hljs-number">5</span>..<span class="hljs-number">7</span>))
    <span class="hljs-comment">// output : [6, 7, 8]</span>

    <span class="hljs-comment">// slice step int range</span>
    println(numbers.slice(<span class="hljs-number">0</span>..<span class="hljs-number">6</span> step <span class="hljs-number">2</span>))
    <span class="hljs-comment">//output : [1, 3, 5, 7]</span>

    <span class="hljs-comment">// slice setof</span>
    println(numbers.slice(setOf(<span class="hljs-number">4</span>,<span class="hljs-number">7</span>,<span class="hljs-number">2</span>,<span class="hljs-number">4</span>)))
    <span class="hljs-comment">// output : [5, 8, 3]</span>

    <span class="hljs-comment">// slice listOf</span>
    println(numbers.slice(listOf(<span class="hljs-number">1</span>,<span class="hljs-number">3</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">1</span>)))
    <span class="hljs-comment">//output: [2, 4, 6, 7, 2]</span>
</code></pre>
<hr />
<h2 id="heading-take">Take</h2>
<p><code>take()</code> - to get specified number of items from the beginning of input collection and returns <code>List&lt;T&gt;</code></p>
<p><code>takeLast()</code> - to get specified number/range of items from the end of input collection and returns <code>List&lt;T&gt;</code></p>
<p>When we specify the number parameter larger than collection size , it returns the entire collection</p>
<p><code>takeWhile()</code> - <code>take()</code> with predicate : it takes the items up to first item not matching predicate</p>
<p>takeLastWhile() - similar to <code>takeLast()</code> : first item of result is the next item to the last item not matching the predicate</p>
<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>)

    <span class="hljs-comment">//take</span>
    println(numbers.take(<span class="hljs-number">3</span>))
    <span class="hljs-comment">// output : [1, 2, 3]</span>

    <span class="hljs-comment">//takeLast</span>
    println(numbers.takeLast(<span class="hljs-number">3</span>))
    <span class="hljs-comment">// output : [7, 8, 9]</span>

    <span class="hljs-comment">//take with parameter more than collection size</span>
    println(numbers.take(<span class="hljs-number">11</span>))
    <span class="hljs-comment">// output : [1, 2, 3, 4, 5, 6, 7, 8, 9]</span>

    <span class="hljs-comment">// takeWhile</span>
    println(
        numbers.takeWhile {
            it &lt; <span class="hljs-number">4</span>
        }
    )
    <span class="hljs-comment">// output : [1, 2, 3]</span>

    <span class="hljs-comment">// takeLastWhile</span>
    println(
        numbers.takeLastWhile {
            it &gt; <span class="hljs-number">6</span>
        }
    )
    <span class="hljs-comment">//output : [6, 7, 8, 9]</span>
</code></pre>
<hr />
<h2 id="heading-drop">Drop</h2>
<p><code>drop() &amp; dropLast()</code></p>
<ul>
<li><p>drops the given number if items from the input collection and returns List&lt;T&gt;</p>
</li>
<li><p><code>drop()</code> - drops from beginning of input collection</p>
</li>
<li><p><code>dropLast()</code> - drops from end of input collection</p>
</li>
</ul>
<p><code>dropWhile()</code></p>
<ul>
<li><p>takes predicate</p>
</li>
<li><p>returns the elements from the first items not matching predicate to the end of input collection</p>
</li>
</ul>
<p><code>dropLastWhile()</code></p>
<ul>
<li><p>takes predicate</p>
</li>
<li><p>returns the elements from beginning of collection to last item not matching the predicate</p>
<pre><code class="lang-kotlin">     <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>)

     <span class="hljs-comment">// drop</span>
      println(numbers.drop(<span class="hljs-number">4</span>))
      <span class="hljs-comment">// output : [5, 6, 7, 8, 9]</span>

      <span class="hljs-comment">// dropLast</span>
      println(numbers.dropLast(<span class="hljs-number">6</span>))
      <span class="hljs-comment">// output : [1, 2, 3]</span>

      <span class="hljs-comment">//dropWhile</span>
      println(
          numbers.dropWhile {
              it &lt;= <span class="hljs-number">7</span>
          }
      )
      <span class="hljs-comment">//output : [8, 9]</span>

      <span class="hljs-comment">// dropLastWhile</span>
      println(
          numbers.dropLastWhile {
              it &gt;= <span class="hljs-number">6</span>
          }
      )
      <span class="hljs-comment">//output : [1, 2, 3, 4, 5]</span>
</code></pre>
</li>
</ul>
<hr />
<h2 id="heading-chunked">Chunked</h2>
<ul>
<li><p>breaks the collection into given size and returns list iof lists</p>
</li>
<li><p>first chunk start from first item in collection</p>
</li>
<li><p>last chunk may be of smaller size than given size</p>
</li>
<li><p>we can apply transformation to the chunked part right away</p>
</li>
<li><p>transformation lambda argument is chunk of collection and these chunked parts are scoped with lambda so we have to consume this with in lambda</p>
<pre><code class="lang-kotlin">      <span class="hljs-keyword">val</span> numbers = (<span class="hljs-number">0</span>..<span class="hljs-number">10</span>).toList()

      <span class="hljs-comment">// chunked</span>
      println(numbers.chunked(<span class="hljs-number">3</span>))
      <span class="hljs-comment">//output :[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]</span>

      <span class="hljs-comment">// chunked with transformation</span>
      <span class="hljs-keyword">val</span> list = numbers.chunked(<span class="hljs-number">3</span>) {
          it.average()
      }
      println(list)
      <span class="hljs-comment">//output : [1.0, 4.0, 7.0, 9.5]</span>
</code></pre>
</li>
</ul>
<hr />
<h2 id="heading-windowed">Windowed</h2>
<ul>
<li><p>retrieves all possible range of collection values/elements of given input size (window size)</p>
</li>
<li><p>returns list of items of the given size in a single list</p>
</li>
</ul>
<p>Lets call each individual list in returned list as windows</p>
<p><code>step()</code> - defines distance between first item of two adjacent windows and default step value is 1</p>
<p><code>partialWindows</code> - include window of smaller size of last items at input collection end</p>
<p>Eg: if input collection is [0,1,2,3,4]and window size is 3 then the result is [0,1,2] , [1,2,3], [2,3,4],[3,4]</p>
<p><code>zipWithNext()</code></p>
<ul>
<li><p>used to build two element windows</p>
</li>
<li><p>creates pair of adjacent items from input collection</p>
</li>
<li><p>it creates a <code>Pair</code> for <em>each</em> element except the last one like [1,2],[2,3],[3,4] and not [1,2], [3,4]</p>
<p>  we can apply transformation to the <code>windowed()</code> and <code>zipWithNext()</code></p>
</li>
<li><pre><code class="lang-kotlin">      <span class="hljs-keyword">val</span> numbers = (<span class="hljs-number">0</span>..<span class="hljs-number">10</span>).toList()

      <span class="hljs-comment">// windowed</span>
      println(numbers.windowed(<span class="hljs-number">3</span>))
      <span class="hljs-comment">// output : [[0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], </span>
      <span class="hljs-comment">//[4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10]]</span>

      <span class="hljs-comment">// windowed with stop and partialWindows</span>
      println(numbers.windowed(<span class="hljs-number">3</span>, step = <span class="hljs-number">3</span>, partialWindows = <span class="hljs-literal">true</span>))
      <span class="hljs-comment">// output : [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]</span>
      println(numbers.windowed(<span class="hljs-number">3</span>, step = <span class="hljs-number">3</span>, partialWindows = <span class="hljs-literal">false</span>))
      <span class="hljs-comment">// output : [[0, 1, 2], [3, 4, 5], [6, 7, 8]]</span>

      <span class="hljs-comment">// zipWithNext</span>
      println(numbers.zipWithNext())
      <span class="hljs-comment">// output : [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10)]</span>

      <span class="hljs-comment">// zipWithNext with transformation</span>
      println(numbers.zipWithNext() { i1, i2 -&gt;
          i1 + i2
      })
      <span class="hljs-comment">// output : [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]</span>
</code></pre>
</li>
</ul>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Collections Operations - Part 2 : Filter]]></title><description><![CDATA[In this article , lets discuss about Kotlin Collections operation - Filter functions

Filtering a collection is an everyday task in dev life. In Kotlin , Filtering conditions are defined by predicates
predicate

takes a collection value and returns a...]]></description><link>https://www.vigneshprabhu.dev/collections-operations-part-2-filter</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/collections-operations-part-2-filter</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[KMM]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[compose multiplatform]]></category><category><![CDATA[compose]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Wed, 08 Sep 2021 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1712277615302/9ddff103-f426-4d5a-b293-3be32647a3b7.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , lets discuss about Kotlin Collections operation - Filter functions</p>
<hr />
<p>Filtering a collection is an everyday task in dev life. In Kotlin , Filtering conditions are defined by predicates</p>
<h2 id="heading-predicate">predicate</h2>
<ul>
<li><p>takes a collection value and returns a <code>boolean</code> value</p>
<p>  if it returns <code>true</code> -&gt; given element matches predicate</p>
<p>  if it returns <code>false</code> -&gt; given element not matches predicate</p>
</li>
</ul>
<h2 id="heading-filter-by-predicate">Filter by predicate</h2>
<h3 id="heading-filter"><code>filter()</code></h3>
<ul>
<li><p>when called with predicate , <code>filter()</code> returns the list of elements that matches the condition</p>
</li>
<li><p>For both <code>List</code> and <code>Set</code> , the result is <code>List</code></p>
</li>
<li><p>For <code>Map</code> , the result is <code>Map</code></p>
</li>
</ul>
<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">62</span>, <span class="hljs-number">51</span>, <span class="hljs-number">67</span>, <span class="hljs-number">32</span>, <span class="hljs-number">45</span>, <span class="hljs-number">12</span>)

    <span class="hljs-comment">//filter for list and set</span>
    <span class="hljs-keyword">val</span> result = numbers.filter { it &gt; <span class="hljs-number">50</span> }
    println(result)
    <span class="hljs-comment">//output: [62, 51, 67]</span>
</code></pre>
<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> studentInfo = mapOf(
        <span class="hljs-string">"Student 1"</span> to <span class="hljs-number">18</span>,
        <span class="hljs-string">"Student 99"</span> to <span class="hljs-number">19</span>,
        <span class="hljs-string">"Student 101"</span> to <span class="hljs-number">21</span>,
        <span class="hljs-string">"Student 199"</span> to <span class="hljs-number">23</span>
    )
    <span class="hljs-comment">//filter for map</span>
    <span class="hljs-keyword">val</span> seniorStudent = studentInfo.filter { (student, age) -&gt;
        student.endsWith(<span class="hljs-string">"9"</span>) &amp;&amp; age &gt; <span class="hljs-number">20</span>
    }
    println(seniorStudent)
    <span class="hljs-comment">//output: {Student 199=23}</span>
</code></pre>
<h3 id="heading-filterindexed"><code>filterIndexed()</code></h3>
<ul>
<li><p>If we need the element position in filter we can use <code>filterIndexed()</code></p>
</li>
<li><p>It takes the predicate with two arguments : index and value</p>
</li>
</ul>
<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">62</span>, <span class="hljs-number">51</span>, <span class="hljs-number">67</span>, <span class="hljs-number">32</span>, <span class="hljs-number">45</span>, <span class="hljs-number">12</span>)

    <span class="hljs-comment">// filer indexed</span>
    <span class="hljs-keyword">val</span> filterIndexedResult = numbers.filterIndexed { index, i -&gt;
        index != <span class="hljs-number">0</span> &amp;&amp; i &gt; <span class="hljs-number">60</span>
    }
    println(filterIndexedResult)
    <span class="hljs-comment">//output : [67]</span>
</code></pre>
<h3 id="heading-filternot"><code>filterNot()</code></h3>
<ul>
<li><p>filter collections by negative conditions</p>
</li>
<li><p>returns the list of all elements that predicate returned false</p>
</li>
</ul>
<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">62</span>, <span class="hljs-number">51</span>, <span class="hljs-number">67</span>, <span class="hljs-number">32</span>, <span class="hljs-number">45</span>, <span class="hljs-number">12</span>)

   <span class="hljs-comment">//filterNot</span>
    <span class="hljs-keyword">val</span> filterNotResult = numbers.filterNot {
        it &gt; <span class="hljs-number">50</span>
    }
    println(filterNotResult)
    <span class="hljs-comment">//output : [32, 45, 12]</span>
</code></pre>
<h3 id="heading-filterisinstance"><code>filterIsInstance()</code></h3>
<ul>
<li><p>returns the collection of given type</p>
</li>
<li><p>if we call on <code>List&lt;Any&gt;</code> with <code>filterIsInstance&lt;String&gt;()</code> , the result is list of strings i.e <code>List&lt;String&gt;</code></p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> typesList = listOf(<span class="hljs-number">1</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">"one"</span>, <span class="hljs-string">'f'</span>, <span class="hljs-number">3</span>, <span class="hljs-literal">null</span>, <span class="hljs-number">4.56</span>, <span class="hljs-number">78.9087</span>, <span class="hljs-string">"twenty"</span>)

    <span class="hljs-comment">//filterIsInstance</span>
    <span class="hljs-keyword">val</span> filterInstanceResult = typesList.filterIsInstance&lt;<span class="hljs-built_in">Double</span>&gt;()
    println(filterInstanceResult)
    <span class="hljs-comment">//output : [4.56, 78.9087]</span>
</code></pre>
<h3 id="heading-filternotnull"><code>filterNotNull()</code></h3>
<ul>
<li><p>returns all non-nullable elements in the collection</p>
</li>
<li><p>if we call on <code>List&lt;T&gt;</code> , it returns <code>List&lt;T : Any&gt;</code></p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> typesList = listOf(<span class="hljs-number">1</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">"one"</span>, <span class="hljs-string">'f'</span>, <span class="hljs-number">3</span>, <span class="hljs-literal">null</span>, <span class="hljs-number">4.56</span>, <span class="hljs-number">78.9087</span>, <span class="hljs-string">"twenty"</span>)

    <span class="hljs-comment">// filterNotNull</span>
    <span class="hljs-keyword">val</span> filterNotNullResult = typesList.filterNotNull()
    println(filterNotNullResult)
    <span class="hljs-comment">//output: [1, one, f, 3, 4.56, 78.9087, twenty]</span>
</code></pre>
<h2 id="heading-partition">Partition</h2>
<h3 id="heading-partition-1"><code>partition()</code></h3>
<ul>
<li><p>filters the given collection by predicate and keeps the elements that does not match in a separate list</p>
</li>
<li><p>returns pair of list , first one containing the elements matching the predicate and the second one not matching the predicate</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">23</span>, <span class="hljs-number">56</span>, <span class="hljs-number">34</span>, <span class="hljs-number">67</span>, <span class="hljs-number">12</span>, <span class="hljs-number">73</span>, <span class="hljs-number">8</span>, <span class="hljs-number">82</span>, <span class="hljs-number">45</span>, <span class="hljs-number">90</span>)

    <span class="hljs-keyword">val</span> partition = numbers.partition {
        it &gt; <span class="hljs-number">50</span>
    }

    println(partition.first)
    <span class="hljs-comment">//output : [56, 67, 73, 82, 90]</span>
    println(partition.second)
    <span class="hljs-comment">//output : [23, 34, 12, 8, 45]</span>
</code></pre>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Collections Operations - Part 3 : Plus-Minus & Grouping]]></title><description><![CDATA[In this article , lets discuss about Kotlin Collections operation - Plus-Minus and grouping functions

Plus and Minus

In Kotlin , + and - operators are used in collection

The first operand is a collection where as second operand can either be an el...]]></description><link>https://www.vigneshprabhu.dev/collections-operations-part-3-plus-minus-grouping</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/collections-operations-part-3-plus-minus-grouping</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[compose multiplatform]]></category><category><![CDATA[compose]]></category><category><![CDATA[android app development]]></category><category><![CDATA[android apps]]></category><category><![CDATA[Android]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Wed, 08 Sep 2021 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1712301720752/5893e2ea-aa76-4ae9-bf52-743f30c76968.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , lets discuss about Kotlin Collections operation - Plus-Minus and grouping functions</p>
<hr />
<h2 id="heading-plus-and-minus">Plus and Minus</h2>
<ul>
<li><p>In Kotlin , + and - operators are used in collection</p>
</li>
<li><p>The first operand is a collection where as second operand can either be an element or another collection</p>
</li>
<li><p>returns a read only collection</p>
</li>
</ul>
<h3 id="heading-plus">Plus ( + )</h3>
<ul>
<li>return a collection containing elements from both first and second operand</li>
</ul>
<h3 id="heading-minus">Minus ( - )</h3>
<ul>
<li><p>returns a collection containing elements from original collection except the elements of second operand</p>
</li>
<li><p>If the second operand is</p>
<p>  an element , minus remove its first occurrence</p>
<p>  a collection , all occurrence of its elements are removed</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numberList = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>)
    <span class="hljs-keyword">val</span> numberOperand = listOf(<span class="hljs-number">3</span>, <span class="hljs-number">5</span>)

    <span class="hljs-keyword">val</span> plusResultList = numberList.plus(numberOperand)
    println(plusResultList)
    <span class="hljs-comment">// output : [1, 3, 5, 7, 9, 3, 5]</span>

    <span class="hljs-keyword">val</span> minusResultList = numberList.minus(numberOperand)
    println(minusResultList)
    <span class="hljs-comment">//output : [1, 7, 9]</span>

    <span class="hljs-keyword">val</span> number = <span class="hljs-number">7</span>
    <span class="hljs-keyword">val</span> resultList = numberList.minus(number)
    println(resultList)
    <span class="hljs-comment">//output : [1, 3, 5, 9]</span>
</code></pre>
<hr />
<h2 id="heading-grouping">Grouping</h2>
<h3 id="heading-groupby">groupBy(<code>)</code></h3>
<ul>
<li><p>takes a lambda function and returns a map</p>
</li>
<li><p>In the Result</p>
<p>  key - lambda result</p>
<p>  value- list of elements on which the lambda result is obtained</p>
<pre><code class="lang-kotlin">     <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">22</span>, <span class="hljs-number">56</span>, <span class="hljs-number">44</span>, <span class="hljs-number">67</span>, <span class="hljs-number">88</span>, <span class="hljs-number">45</span>, <span class="hljs-number">77</span>)

      <span class="hljs-comment">// groupBy</span>
      <span class="hljs-keyword">val</span> groupByResult = numbers.groupBy {
          it % <span class="hljs-number">11</span> == <span class="hljs-number">0</span>
      }
      println(groupByResult)
      <span class="hljs-comment">//output : {true=[22, 44, 88, 77], false=[56, 67, 45]}</span>
</code></pre>
</li>
</ul>
<h3 id="heading-groupby-2-lambda-argument"><code>groupBy()</code> - 2 Lambda argument</h3>
<ul>
<li><p>Second lambda argument is a value transformation function</p>
</li>
<li><p>In Result</p>
<p>  key - produced by <code>keySelector</code> function</p>
<p>  value - result of <code>valueTransform</code> function</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">22</span>, <span class="hljs-number">56</span>, <span class="hljs-number">44</span>, <span class="hljs-number">67</span>, <span class="hljs-number">88</span>, <span class="hljs-number">45</span>, <span class="hljs-number">77</span>)

    <span class="hljs-keyword">val</span> result = numbers.groupBy(
        keySelector = { it % <span class="hljs-number">2</span> == <span class="hljs-number">0</span> },
        valueTransform = {
            <span class="hljs-keyword">if</span> (it % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>) {
                <span class="hljs-string">"<span class="hljs-variable">$it</span> is an Even number"</span>
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-string">"<span class="hljs-variable">$it</span> is not an Even number"</span>
            }
        })
    println(result)
    <span class="hljs-comment">//output : {</span>
<span class="hljs-comment">//           true=[22 is an Even number,</span>
<span class="hljs-comment">//              56 is an Even number,</span>
<span class="hljs-comment">//              44 is an Even number,</span>
<span class="hljs-comment">//              88 is an Even number],</span>
<span class="hljs-comment">//           false=[67 is not an Even number,</span>
<span class="hljs-comment">//              45 is not an Even number,</span>
<span class="hljs-comment">//              77 is not an Even number]}</span>
</code></pre>
<h3 id="heading-groupingby"><code>groupingBy()</code></h3>
<ul>
<li><p>helps to group elements and apply an operation to all groups at one time</p>
</li>
<li><p>returns an instance of Grouping type</p>
</li>
<li><p>applies the operation in lazy manner : the groups are actually built right before the operation execution</p>
</li>
<li><p>supports the following execution</p>
<p>  1.<code>eachCount()</code> - counts the element in each group</p>
<p>  2.<code>fold()</code> &amp; <code>reduce()</code> - perform fold and reduce operations on each group as separate collection and return results</p>
<p>  3.<code>aggregate()</code> - applies a given operation subsequently to all elements in each group and return results</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> oddNumbers = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">7</span>, <span class="hljs-number">5</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>)
    <span class="hljs-keyword">val</span> groupingByResult = oddNumbers.groupingBy {
        it * <span class="hljs-number">2</span>
    }.eachCount()

    println(groupingByResult)
    <span class="hljs-comment">// output : {2=1, 14=2, 10=1, 18=1}</span>
</code></pre>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Collections Operations - Part 1 : Transformation]]></title><description><![CDATA[In this article , lets discuss about Kotlin Collections operation - transformation functions

Kotlin Transformation function builds a new collection based on the transformation rules passed in the function.
Map

Mapping transformation creates a colle...]]></description><link>https://www.vigneshprabhu.dev/collections-operations-part-1-transformation</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/collections-operations-part-1-transformation</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[android apps]]></category><category><![CDATA[Android Studio]]></category><category><![CDATA[android development]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[KMM]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Mon, 06 Sep 2021 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1711925179721/58f1dda0-5b1f-465c-93ff-973fa788b5cf.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , lets discuss about Kotlin Collections operation - transformation functions</p>
<hr />
<p>Kotlin Transformation function builds a new collection based on the transformation rules passed in the function.</p>
<h2 id="heading-map">Map</h2>
<ul>
<li>Mapping transformation creates a collection from the result of function on the another collection's element</li>
</ul>
<h3 id="heading-map-1"><code>map()</code></h3>
<ul>
<li><p>applies the given function to each element and returns the list of lambda result</p>
</li>
<li><p>order of elements is same as order of original elements collection's order</p>
</li>
</ul>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> numbers = setOf(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">5</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>, <span class="hljs-number">0</span>)
  <span class="hljs-comment">// map</span>
  println(numbers.map { it * <span class="hljs-number">3</span> })
  <span class="hljs-comment">//output ; [3, 9, 6, 15, 12, 18, 21, 27, 0]</span>
</code></pre>
<h3 id="heading-mapindexed"><code>mapIndexed()</code></h3>
<ul>
<li>Apply a <code>map()</code> transformation that additionally uses the element index as argument</li>
</ul>
<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> numbers = setOf(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">5</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>, <span class="hljs-number">0</span>) 
   <span class="hljs-comment">//map indexed</span>
    println(numbers.mapIndexed { index: <span class="hljs-built_in">Int</span>, i: <span class="hljs-built_in">Int</span> -&gt; <span class="hljs-string">"index:<span class="hljs-variable">$index</span> - value:<span class="hljs-variable">$i</span>"</span> })
    <span class="hljs-comment">// output : [index:0 - value:1, index:1 - value:3, index:2 - value:2, index:3 - value:5,</span>
    <span class="hljs-comment">// index:4 - value:4, index:5 - value:6, index:6 - value:7, index:7 - value:9,</span>
    <span class="hljs-comment">// index:8 - value:0]</span>
</code></pre>
<h3 id="heading-mapnotnull-amp-mapnotnullindexed"><code>mapNotNull() &amp; mapNotNullIndexed()</code></h3>
<ul>
<li>If the transformation produces null on certain element , we can filter out null from result collection</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = setOf(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">5</span>, <span class="hljs-number">4</span>, <span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">9</span>, <span class="hljs-number">0</span>) 
    <span class="hljs-comment">//map null</span>
    println(numbers.mapNotNull { <span class="hljs-keyword">if</span> (it == <span class="hljs-number">5</span>) <span class="hljs-literal">null</span> <span class="hljs-keyword">else</span> it * <span class="hljs-number">10</span> })
    <span class="hljs-comment">// output : [10, 30, 20, 40, 60, 70, 90, 0]</span>

    <span class="hljs-comment">//map indexed null</span>
    println(numbers.mapIndexedNotNull { index, i -&gt; <span class="hljs-keyword">if</span> (index == <span class="hljs-number">4</span>) <span class="hljs-literal">null</span> <span class="hljs-keyword">else</span> i * <span class="hljs-number">10</span> })
    <span class="hljs-comment">// output : [10, 30, 20, 50, 60, 70, 90, 0]</span>
</code></pre>
<p>When transforming maps , there are two options</p>
<ol>
<li><p><code>mapKeys()</code> -&gt; transform key leaving values unchanged</p>
</li>
<li><p><code>mapValues()</code> -&gt; transform values leaving keys unchanged</p>
</li>
</ol>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Both functionality takes map as an argument , so we can operate on both key and values</div>
</div>

<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> numbersMap = mapOf(<span class="hljs-string">"Key1"</span> to <span class="hljs-number">1</span>, <span class="hljs-string">"Key2"</span> to <span class="hljs-number">2</span>,
                <span class="hljs-string">"Key3"</span> to <span class="hljs-number">3</span>, <span class="hljs-string">"Key4"</span> to <span class="hljs-number">4</span>, <span class="hljs-string">"Key5"</span> to <span class="hljs-number">5</span>)

    <span class="hljs-comment">//map keys and map values</span>
    println(numbersMap.mapKeys { it.key.reversed() })
    <span class="hljs-comment">// output : {1yeK=1, 2yeK=2, 3yeK=3, 4yeK=4, 5yeK=5}</span>
    println(numbersMap.mapValues { <span class="hljs-string">"<span class="hljs-subst">${it.value}</span> + <span class="hljs-subst">${it.key.uppercase()}</span>"</span> })
    <span class="hljs-comment">// output : {Key1=1 + KEY1, Key2=2 + KEY2, Key3=3 + KEY3, </span>
    <span class="hljs-comment">// Key4=4 + KEY4, Key5=5 + KEY5}</span>
</code></pre>
<h2 id="heading-zip">Zip</h2>
<p>Zipping transformation is building pairs from elements with same positions in two collections</p>
<h3 id="heading-zip-1"><code>zip()</code></h3>
<ul>
<li><p>returns the list of pair object</p>
</li>
<li><p>if the collection have different sizes , then the result of <code>zip()</code> is smaller size collection size and the result will not contain the larger collection's last element</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> studentName = listOf(<span class="hljs-string">"stu 1"</span>, <span class="hljs-string">"stu 2"</span>, <span class="hljs-string">"stu 3"</span>, <span class="hljs-string">"stu 4"</span>)
    <span class="hljs-keyword">val</span> studentAge = listOf(<span class="hljs-number">20</span>, <span class="hljs-number">35</span>, <span class="hljs-number">5</span>, <span class="hljs-number">0</span>, <span class="hljs-number">30</span>)
    <span class="hljs-comment">// zip </span>
    println(studentName zip studentAge)
    <span class="hljs-comment">// output : [(stu 1, 20), (stu 2, 35), (stu 3, 5), (stu 4, 0)]</span>
</code></pre>
<ul>
<li><p>Zip with transformation function takes 2 parameters</p>
<p>  1.Receiver element</p>
<p>  2.Argument element</p>
</li>
<li><p>Transformation function called on pairs of receiver and argument element with same position</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> studentName = listOf(<span class="hljs-string">"stu 1"</span>, <span class="hljs-string">"stu 2"</span>, <span class="hljs-string">"stu 3"</span>, <span class="hljs-string">"stu 4"</span>)
    <span class="hljs-keyword">val</span> studentAge = listOf(<span class="hljs-number">20</span>, <span class="hljs-number">35</span>, <span class="hljs-number">5</span>, <span class="hljs-number">0</span>, <span class="hljs-number">30</span>)
    <span class="hljs-comment">//zip transformation</span>
    println(studentName.zip(studentAge) { name, age -&gt;
        <span class="hljs-string">"The Student name is <span class="hljs-variable">$name</span> amd the age is <span class="hljs-variable">$age</span>"</span>
    })
    <span class="hljs-comment">// output : [The Student name is stu 1 amd the age is 20, </span>
    <span class="hljs-comment">//The Student name is stu 2 amd the age is 35,</span>
    <span class="hljs-comment">// The Student name is stu 3 amd the age is 5, </span>
    <span class="hljs-comment">//The Student name is stu 4 amd the age is 0]</span>
</code></pre>
<h3 id="heading-unzip"><code>unzip()</code></h3>
<p>We can do the reverse transformation on the list of pairs and the result is of two lists</p>
<p>1.First list contains first element of each pair</p>
<p>2.Second list contains second element</p>
<pre><code class="lang-kotlin">    <span class="hljs-comment">// unzipping</span>
    <span class="hljs-keyword">val</span> studentInfo = listOf(
        <span class="hljs-string">"stu1"</span> to <span class="hljs-number">20</span>,
        <span class="hljs-string">"stu2"</span> to <span class="hljs-number">35</span>,
        <span class="hljs-string">"stu3"</span> to <span class="hljs-number">5</span>,
        <span class="hljs-string">"st4"</span> to <span class="hljs-number">0</span>
    )
    println(studentInfo.unzip())
    <span class="hljs-comment">// output : ([stu1, stu2, stu3, st4], [20, 35, 5, 0])</span>
</code></pre>
<h2 id="heading-associate">Associate</h2>
<ul>
<li>Allow building maps from collection elements and values associated from them</li>
</ul>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If the elements are equal , the last one remains in the result map</div>
</div>

<h3 id="heading-associatewith"><code>associateWith()</code></h3>
<ul>
<li>creates a map in which element of original collection are keys and values are result of given transformation function</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">7</span>)

    <span class="hljs-comment">// associateWith</span>
    println(numbers.associateWith { it * <span class="hljs-number">2</span> + <span class="hljs-number">1</span> })
    <span class="hljs-comment">// output : {1=2, 3=6, 5=10, 7=14}</span>
</code></pre>
<h3 id="heading-associateby"><code>associateBy()</code></h3>
<ul>
<li><p>creates a map with original collection as values</p>
</li>
<li><p>it takes a function that returns the key based on elements transformation function</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">7</span>)

    <span class="hljs-comment">// associateBy</span>
    println(numbers.associateBy { it * <span class="hljs-number">2</span> })
    <span class="hljs-comment">//output :{2=1, 6=3, 10=5, 14=7}</span>
</code></pre>
<h3 id="heading-associate-1"><code>associate()</code></h3>
<ul>
<li><p>For building maps where both keys and values are produced from the original collection elements</p>
</li>
<li><p>It takes a lambda function and returns a <code>Pair</code>: key and value of corresponding map entry</p>
</li>
</ul>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><code>associate() </code>produces short living pair objects which may affect performance</div>
</div>

<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>, <span class="hljs-number">3</span>, <span class="hljs-number">7</span>)
    <span class="hljs-comment">// associate</span>
    println(numbers.associate {
        it to (it * <span class="hljs-number">2</span> + <span class="hljs-number">3</span>)
       }
    )
    <span class="hljs-comment">//output : {1=5, 3=9, 5=13, 7=17}</span>
</code></pre>
<h2 id="heading-flatten">Flatten</h2>
<ul>
<li>operates on nested collection that provide flat access to nested collection elements</li>
</ul>
<h3 id="heading-flatten-1"><code>flatten()</code></h3>
<ul>
<li><p>call it on the collection of elements (list of sets)</p>
</li>
<li><p>returns the list of elements in the nested collection</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> sampleSetList = listOf(
        setOf(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>),
        setOf(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>),
        setOf(<span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>),
        setOf(<span class="hljs-number">6</span>, <span class="hljs-number">7</span>, <span class="hljs-number">8</span>)
    )

    <span class="hljs-comment">// flatten</span>
    println(sampleSetList.flatten())
    <span class="hljs-comment">//output : [3, 4, 5, 0, 1, 2, 7, 8, 9, 6, 7, 8]</span>
</code></pre>
<h3 id="heading-flatmap"><code>flatMap()</code></h3>
<ul>
<li><p>flexible way to process nested collection</p>
</li>
<li><p>takes a function that maps a collection element to another collection</p>
</li>
<li><p>returns a single list on its return values on all elements</p>
</li>
<li><p>so basically <code>flatMap()</code> is a mixture of both <code>map()</code> and <code>flatten()</code></p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> containers = listOf(
        listOf(<span class="hljs-string">"one"</span>, <span class="hljs-string">"two"</span>, <span class="hljs-string">"three"</span>),
        listOf(<span class="hljs-string">"four"</span>, <span class="hljs-string">"five"</span>, <span class="hljs-string">"six"</span>),
        listOf(<span class="hljs-string">"seven"</span>, <span class="hljs-string">"eight"</span>)
    )
   <span class="hljs-comment">// flatmap</span>
    println(containers.flatMap {
        it.asReversed()
    })
    <span class="hljs-comment">// output : [three, two, one, six, five, four, eight, seven]</span>
</code></pre>
<h2 id="heading-string-representation">String Representation</h2>
<ul>
<li>If we need collection in a readable format , use the transform function like <code>joinTostring(</code>) and <code>joinTo()</code></li>
</ul>
<h3 id="heading-jointostring"><code>joinToString()</code></h3>
<ul>
<li>builds a string string from the collection result based on provided argument</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-string">"one"</span>, <span class="hljs-number">1</span>, <span class="hljs-string">"two"</span>, <span class="hljs-number">2</span>, <span class="hljs-string">"three"</span>, <span class="hljs-number">3</span>)

    <span class="hljs-comment">// joinToString</span>
    println(numbers.joinToString())
    <span class="hljs-comment">// output : one, 1, two, 2, three, 3</span>
</code></pre>
<h3 id="heading-jointo"><code>joinTo()</code></h3>
<ul>
<li><p>builds a string from collection but appends the result to the given append able object</p>
</li>
<li><p>result is a string of collection elements separated by commas with spaces</p>
</li>
</ul>
<pre><code class="lang-kotlin">    <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-string">"one"</span>, <span class="hljs-number">1</span>, <span class="hljs-string">"two"</span>, <span class="hljs-number">2</span>, <span class="hljs-string">"three"</span>, <span class="hljs-number">3</span>)

    <span class="hljs-comment">// joinTo</span>
    <span class="hljs-keyword">val</span> listContents = StringBuffer(<span class="hljs-string">"The contents are -&gt; "</span>)
    numbers.joinTo(listContents)
    println(listContents)
    <span class="hljs-comment">//output :The contents are -&gt; one, 1, two, 2, three, 3</span>
</code></pre>
<h3 id="heading-jointostring-prefix-postfix-and-separator"><code>joinToString() - prefix, postfix and separator</code></h3>
<ul>
<li>To build a custom string representation , we can user the prefix, postfix and separator in the j<code>oinToString()</code></li>
</ul>
<pre><code class="lang-kotlin">   <span class="hljs-keyword">val</span> numbers = listOf(<span class="hljs-string">"one"</span>, <span class="hljs-number">1</span>, <span class="hljs-string">"two"</span>, <span class="hljs-number">2</span>, <span class="hljs-string">"three"</span>, <span class="hljs-number">3</span>)

   <span class="hljs-comment">// joinToString</span>
    println(
        numbers.joinToString(
            separator = <span class="hljs-string">" -- "</span>,
            prefix = <span class="hljs-string">"Begin: "</span>,
            postfix = <span class="hljs-string">" :End"</span>
        )
    )
    <span class="hljs-comment">//output: Begin: one -- 1 -- two -- 2 -- three -- 3 :End</span>
</code></pre>
<h3 id="heading-jointostring-limit-and-truncate"><code>joinToString() - limit and truncate</code></h3>
<ul>
<li><p>This limit and truncate parameter is used in <code>joinToString()</code> for bigger collections , this will limit the elements in result</p>
</li>
<li><p>if the limit is reached , truncated argument will replace the rest of all elements in the collection</p>
</li>
</ul>
<pre><code class="lang-kotlin">   <span class="hljs-comment">// limit and truncate </span>
    <span class="hljs-keyword">val</span> numbersList = (<span class="hljs-number">1</span>..<span class="hljs-number">100</span>).toList()
    println(
        numbersList.joinToString(
            limit = <span class="hljs-number">12</span>, truncated = <span class="hljs-string">" and so on"</span>
        )
    )
    <span class="hljs-comment">//output ; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,  and so on</span>
</code></pre>
<h3 id="heading-jointostring-transform"><code>joinToString() -</code> transform</h3>
<ul>
<li>To customize the elements in collections , we can use transform function as follows</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-comment">// transform</span>
    <span class="hljs-keyword">val</span> numbersString = listOf(<span class="hljs-string">"one"</span>, <span class="hljs-string">"two"</span>, <span class="hljs-string">"three"</span>)
    println(numbersString.joinToString { 
         <span class="hljs-string">"Element -&gt; <span class="hljs-subst">${it.reversed().uppercase()}</span>"</span> 
      }
    )
    <span class="hljs-comment">//output: Element -&gt; ENO, Element -&gt; OWT, Element -&gt; EERHT</span>
</code></pre>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Kotlin Collections]]></title><description><![CDATA[In this article , lets discuss about Kotlin Collections
Collections are used to store and manipulate group of objects or data
Ordered Collection is the collection in which the position of each item is fixed Eg: Lists , Array , etc
Unordered Collectio...]]></description><link>https://www.vigneshprabhu.dev/kotlin-collections</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/kotlin-collections</guid><category><![CDATA[android app development]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[android development]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Fri, 03 Sep 2021 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709396258634/e81ac6c6-3a5c-4e59-996b-5ca6d1e584c6.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , lets discuss about Kotlin Collections</p>
<p>Collections are used to store and manipulate group of objects or data</p>
<p><strong>Ordered Collection</strong> is the collection in which the position of each item is fixed Eg: Lists , Array , etc</p>
<p><strong>Unordered Collection</strong> is the collection in which the position of each item is not fixed which means order of all elements are not maintained. Eg: Set</p>
<h2 id="heading-collection-types">Collection Types</h2>
<h2 id="heading-immutable-collection">Immutable Collection</h2>
<p>This collection supports read only functionality and we cannot modify its elements</p>
<h3 id="heading-list">List</h3>
<ul>
<li><p>This is an ordered collection in which elements can be accessed using indices</p>
</li>
<li><p>Elements can be repeated in list for any number of times</p>
</li>
<li><p>We cannot perform add/remove operations in this immutable list</p>
<p>  <strong>listOf() , listOf&lt;T&gt;()</strong></p>
</li>
</ul>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> androidOsName = listOf(
        <span class="hljs-string">"Upside Down Cake"</span>,
        <span class="hljs-string">"Vanilla Ice Cream"</span>,
        <span class="hljs-string">"Tiramisu"</span>,
        <span class="hljs-string">"Snow Cone"</span>,
        <span class="hljs-string">"Red Velvet Cake"</span>
    )

    <span class="hljs-keyword">for</span> (name <span class="hljs-keyword">in</span> androidOsName){
        println(name)
    }
</code></pre>
<h3 id="heading-set">Set</h3>
<ul>
<li><p>This is an unordered collection in which elements cannot be duplicated</p>
</li>
<li><p>Set is collection of unique elements</p>
</li>
<li><p>We cannot perform add/remove operations because of immutable collection <strong>setOf()</strong></p>
</li>
</ul>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> android14Info  = setOf(
        <span class="hljs-string">"Android 14"</span> ,
        <span class="hljs-string">"Upside Down Cake"</span> ,
        <span class="hljs-number">14</span> ,
        <span class="hljs-number">34</span> ,
        <span class="hljs-string">"October 4 2023 "</span>
    )

    <span class="hljs-keyword">for</span> (name <span class="hljs-keyword">in</span> android14Info){
        println(name)
    }
</code></pre>
<h3 id="heading-map">Map</h3>
<ul>
<li><p>Maps are unordered collection of set of key/value pairs</p>
</li>
<li><p>Map key are unique and can hold only one value for each key</p>
</li>
<li><p>Keys are unique but values are duplicated</p>
</li>
<li><p>Map is used to store logical collection between two objects</p>
</li>
<li><p>As it is immutable , size is fixed and supports read only access .</p>
<p>  <strong>mapOf()</strong></p>
</li>
</ul>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> androidOsInfo = mapOf(
        <span class="hljs-number">13</span> to <span class="hljs-string">"Android 13 - Tiramisu - 13 - 33 - August 15, 2022 "</span> ,
        <span class="hljs-number">12</span> to <span class="hljs-string">"Android 12 - Snow Cone - 12 - 31 - October 4, 2021 "</span> ,
        <span class="hljs-number">11</span> to <span class="hljs-string">"Android 11 - Red Velvet Cake[24] - 11 - 30 tSeptember 8, 2020 "</span>
    )

    <span class="hljs-keyword">for</span> (info <span class="hljs-keyword">in</span> androidOsInfo) {
        println(<span class="hljs-string">"<span class="hljs-subst">${info.key}</span> -&gt; <span class="hljs-subst">${info.value}</span>"</span>)
    }
</code></pre>
<h2 id="heading-mutable-collection">Mutable Collection</h2>
<p>This collection supports both read and write functionality.</p>
<h3 id="heading-list-1">List</h3>
<ul>
<li><p>This mutable list supports both read and write operation</p>
</li>
<li><p>The declared elements in list can be either removed or added</p>
<p>  <strong>mutableListOf() , arrayListOf&lt;T&gt;() , ArrayList</strong></p>
</li>
</ul>
<pre><code class="lang-kotlin"> <span class="hljs-keyword">val</span> androidOsName = mutableListOf(
        <span class="hljs-string">"Upside Down Cake"</span>,
        <span class="hljs-string">"Vanilla Ice Cream"</span>,
        <span class="hljs-string">"Tiramisu"</span>
    )

    <span class="hljs-comment">// modify item</span>
    androidOsName[<span class="hljs-number">0</span>] = <span class="hljs-string">"Pistachio Ice Cream"</span>

    <span class="hljs-comment">// add item</span>
    androidOsName.add(<span class="hljs-string">"Snow Cone"</span>)

    <span class="hljs-keyword">for</span> (name <span class="hljs-keyword">in</span> androidOsName){
        println(name)
    }
</code></pre>
<h3 id="heading-set-1">Set</h3>
<ul>
<li><p>This set supports both read and write</p>
</li>
<li><p>Set allows us to easily to add/remove elements</p>
</li>
<li><p>Order of elements are preserved</p>
<p>  <strong>mutableSetOf() , hashSetOf()</strong></p>
</li>
</ul>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> androidOsName = mutableSetOf&lt;String&gt;(
        <span class="hljs-string">"Upside Down Cake"</span>,
        <span class="hljs-string">"Vanilla Ice Cream"</span>,
        <span class="hljs-string">"Tiramisu"</span>
    )

    <span class="hljs-comment">// add item</span>
    androidOsName.add(<span class="hljs-string">"Snow Cone"</span>)

    <span class="hljs-comment">// remove item</span>
    androidOsName.remove(<span class="hljs-string">"Upside Down Cake"</span>)

    <span class="hljs-keyword">for</span> (name <span class="hljs-keyword">in</span> androidOsName){
        println(name)
    }
</code></pre>
<h3 id="heading-map-1">Map</h3>
<p>Since this Map is mutable and this supports operations like put, remove , clear ,etc</p>
<p>mutableMapOf() , hashMapOf() and HashMap</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">val</span> androidOsInfo = mutableMapOf(
        <span class="hljs-number">13</span> to <span class="hljs-string">"Android 13 - Tiramisu - 13 - 33 - August 15, 2022 "</span>,
        <span class="hljs-number">12</span> to <span class="hljs-string">"Android 12 - Snow Cone - 12 - 31 - October 4, 2021 "</span>,
        <span class="hljs-number">11</span> to <span class="hljs-string">"Android 11 - Red Velvet Cake[24] - 11 - 30 tSeptember 8, 2020 "</span>
    )

    <span class="hljs-comment">// add item</span>
    androidOsInfo.put(<span class="hljs-number">10</span>, <span class="hljs-string">"Android 10 - Quince Tart[24] - 10 - 29 - September 3, 2019 "</span>)

    <span class="hljs-comment">// remove item</span>
    androidOsInfo.remove(<span class="hljs-number">12</span>)

    <span class="hljs-keyword">for</span> (info <span class="hljs-keyword">in</span> androidOsInfo) {
        println(<span class="hljs-string">"<span class="hljs-subst">${info.key}</span> -&gt; <span class="hljs-subst">${info.value}</span>"</span>)
    }
</code></pre>
<p>So finally, I hope I made somebody understand the basics of kotlin collections</p>
<p><strong>Please leave your comments to improve.</strong></p>
<blockquote>
<p>Happy and Enjoy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Kotlin Basics - Property]]></title><description><![CDATA[In this article , Lets understand how to use property getters and setters in kotlin 
A simple student class as follows 
class Student(var studentFirstName: String,
                                  var studentLastName: String = "No Name") {

    fun ...]]></description><link>https://www.vigneshprabhu.dev/kotlin-basics-property</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/kotlin-basics-property</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[Programming Tips]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Sat, 07 Aug 2021 13:44:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1634044106598/JFDLqqyyJ.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article , Lets understand how to use property getters and setters in kotlin </p>
<p>A simple student class as follows </p>
<pre><code>class Student(var studentFirstName: String,
                                  var studentLastName: String = <span class="hljs-string">"No Name"</span>) {

    fun getStudentName(): String {
        <span class="hljs-built_in">return</span> <span class="hljs-string">"<span class="hljs-variable">$studentFirstName</span> <span class="hljs-variable">$studentLastName</span>"</span>
    }

    fun <span class="hljs-function"><span class="hljs-title">printStudentName</span></span>() {
        println(<span class="hljs-string">"<span class="hljs-variable">$studentFirstName</span> <span class="hljs-variable">$studentLastName</span>"</span>)
    }

    fun <span class="hljs-function"><span class="hljs-title">printStudentInfo</span></span>() {
        println(<span class="hljs-string">"Name:<span class="hljs-variable">$studentFirstName</span> <span class="hljs-variable">$studentLastName</span>)
    }

}</span>
</code></pre><p>Now lets add a property to this class and understand the getters and setters behavior </p>
<h2 id="add-a-property">Add a Property</h2>
<p>Lets add a property <code>age</code> to the above class</p>
<pre><code><span class="hljs-keyword">var</span> age : <span class="hljs-keyword">String</span>= <span class="hljs-string">"0"</span>
</code></pre><p>Now lets modify and print the <code>age</code> property from the main class </p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">val</span> student = Student(<span class="hljs-string">"Vignesh"</span>, <span class="hljs-string">"Prabhu"</span>)
 println(student.age)
}
Console O/P:
<span class="hljs-number">0</span>
</code></pre><h2 id="property-getter">Property Getter</h2>
<p>Now lets add getter to this <code>age</code> property as follows </p>
<pre><code> <span class="hljs-keyword">var</span> age = <span class="hljs-string">"0"</span>
      <span class="hljs-keyword">get</span>() {
            <span class="hljs-keyword">return</span> <span class="hljs-string">"<span class="hljs-subst">${getStudentName()}</span>'s age is <span class="hljs-variable">$field</span>"</span>
       }
</code></pre><p> In the above code  ,  get() is called whenever we access this field . So we have manipulated the value of the property in a way that if we access the property <code>age</code> , then it will return as follows </p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
<span class="hljs-keyword">val</span> student = Student(<span class="hljs-string">"Vignesh"</span>, <span class="hljs-string">"Prabhu"</span>)
println(student.age)
}
Console O/P:
Vignesh Prabhu<span class="hljs-string">'s age is 0</span>
</code></pre><p>In the above code we can observe that ,  we we accessed the property <code>age</code> and printed in the console shows <strong> Vignesh Prabhu's age is 0</strong> because in the get method we have added the code <code>return "${getStudentName()}'s age is $field"</code>.</p>
<blockquote>
<p>Here <code>$field</code> is called backing field since the contains the value of property <code>age</code></p>
</blockquote>
<h2 id="property-setter">Property Setter</h2>
<p>Now lets add setter to this <code>age</code> property as follows </p>
<pre><code> <span class="hljs-keyword">var</span> age = <span class="hljs-string">"0"</span>
  <span class="hljs-keyword">get</span>() {...}
 <span class="hljs-keyword">set</span>(<span class="hljs-keyword">value</span>) {
            field = <span class="hljs-keyword">if</span> (<span class="hljs-keyword">value</span> == <span class="hljs-string">"0"</span>) {
                <span class="hljs-string">"unknown"</span>
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">value</span>
            }
        }
</code></pre><p>In the above code , <code>set(value)</code> is called whenever we want to modify the property in our own way . <code>value</code> is nothing but the passed value in the runtime. So lets see how it changes the property if we use this </p>
<pre><code>fun main(){
  val student = StudentProperty(<span class="hljs-string">"Vignesh"</span>, <span class="hljs-string">"Prabhu"</span>)
  println(student.age)
  student.age = <span class="hljs-string">"0"</span>
  println(student.age)
}
Console O/P:
Vignesh Prabh<span class="hljs-string">u's age is 0
Vignesh Prabhu'</span>s age <span class="hljs-keyword">is</span> unknown
</code></pre><p>As we can observe that when the value 0 is passed to <code>age</code> property , the set method takes over and manipulates the value wrt to the logic used.</p>
<p>Updated Student class:</p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span></span>(<span class="hljs-keyword">var</span> studentFirstName: String,
                                  <span class="hljs-keyword">var</span> studentLastName: String = <span class="hljs-string">"No Name"</span>) {

    <span class="hljs-keyword">var</span> age = <span class="hljs-string">"0"</span>
        <span class="hljs-keyword">get</span>() {
            <span class="hljs-keyword">return</span> <span class="hljs-string">"<span class="hljs-subst">${getStudentName()}</span>'s age is <span class="hljs-variable">$field</span>"</span>
        }
        <span class="hljs-keyword">set</span>(value) {
            field = <span class="hljs-keyword">if</span> (value == <span class="hljs-string">"0"</span>) {
                <span class="hljs-string">"unknown"</span>
            } <span class="hljs-keyword">else</span> {
                value
            }
        }


    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getStudentName</span><span class="hljs-params">()</span></span>: String {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"<span class="hljs-variable">$studentFirstName</span> <span class="hljs-variable">$studentLastName</span>"</span>
    }

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">printStudentName</span><span class="hljs-params">()</span></span> {
        println(<span class="hljs-string">"<span class="hljs-variable">$studentFirstName</span> <span class="hljs-variable">$studentLastName</span>"</span>)
    }

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">printStudentInfo</span><span class="hljs-params">()</span></span> {
        println(<span class="hljs-string">"Name:<span class="hljs-variable">$studentFirstName</span> <span class="hljs-variable">$studentLastName</span> -------- Age:<span class="hljs-variable">$age</span>"</span>)
    }

}
</code></pre><p>So finally , I hope i made you understand property getter and setter in Kotlin.</p>
<h1 id="please-leave-your-comments-to-improve">Please leave your comments to improve.</h1>
<blockquote>
<p>Enjoy coding </p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Kotlin Basics - object aka Singleton]]></title><description><![CDATA[A singleton class is a user-defined class in a way that only one instance of the class can be created and used everywhere.
Without a singleton, creating two different objects allocates two different object memories
In Kotlin, Singelton is made by usi...]]></description><link>https://www.vigneshprabhu.dev/kotlin-basics-object-aka-singleton</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/kotlin-basics-object-aka-singleton</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[Android]]></category><category><![CDATA[android development]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Sat, 07 Aug 2021 12:28:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1685622330647/8fa24a07-95ac-45bf-9d9e-701942862ba6.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A singleton class is a user-defined class in a way that only one instance of the class can be created and used everywhere.</p>
<p>Without a singleton, creating two different objects allocates two different object memories</p>
<p>In Kotlin, Singelton is made by using object keyword as follows</p>
<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{

    println(Database) <span class="hljs-comment">// prints Database@1c20c684</span>
    <span class="hljs-keyword">val</span> db = Database.getDatabaseName()
    println(db) <span class="hljs-comment">// prints info.db</span>
    println(Database) <span class="hljs-comment">// prints Database@1c20c684</span>
}

<span class="hljs-keyword">object</span> Database{

    <span class="hljs-keyword">init</span> {
        println(<span class="hljs-string">"Database created"</span>)
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">val</span> DATABASE_NAME = <span class="hljs-string">"info.db"</span>

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getDatabaseName</span><span class="hljs-params">()</span></span> = DATABASE_NAME

}
</code></pre>
<p>As you can see, the Database address is the same for two different calls in the above code</p>
<p>Things to note :</p>
<ul>
<li><p>an object class can have functions, properties and an init block</p>
</li>
<li><p>the constructor method is not allowed</p>
</li>
<li><p>properties and functions are called using the class name as we do in the companion object</p>
</li>
</ul>
<h1 id="heading-please-leave-your-comments-to-improve">Please leave your comments to improve.</h1>
<blockquote>
<p>Enjoy and happy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Kotlin Basics - Lazy initialization]]></title><description><![CDATA[In Kotlin, an object can only be created when it is called, otherwise no object creation
The lazy () block

fun main() {

    val bookInstance1 = Book(
        "Rogue Lawyer", "John Grisham", 2015
    ) // prints Book Rogue Lawyer class is called


 ...]]></description><link>https://www.vigneshprabhu.dev/kotlin-basics-lazy-initialization</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/kotlin-basics-lazy-initialization</guid><category><![CDATA[kotlin beginner]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[Kotlin Multiplatform]]></category><category><![CDATA[Android]]></category><category><![CDATA[androi]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Sat, 07 Aug 2021 11:46:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1685626393801/223b846f-a6b0-4dd0-afea-ef2a3ed08a69.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Kotlin, an object can only be created when it is called, otherwise no object creation</p>
<p><strong>The lazy () block</strong></p>
<pre><code class="lang-kotlin">
<span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {

    <span class="hljs-keyword">val</span> bookInstance1 = Book(
        <span class="hljs-string">"Rogue Lawyer"</span>, <span class="hljs-string">"John Grisham"</span>, <span class="hljs-number">2015</span>
    ) <span class="hljs-comment">// prints Book Rogue Lawyer class is called</span>


    <span class="hljs-keyword">val</span> bookInstance2 <span class="hljs-keyword">by</span> lazy {
        Book(
            <span class="hljs-string">"The Rain maker"</span>, <span class="hljs-string">"John Grisham"</span>, <span class="hljs-number">1995</span>
        )
    }

    <span class="hljs-comment">/*println(bookInstance2.getBookDetails())
    println(bookInstance1.getBookDetails())*/</span>

}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Book</span></span>(
    <span class="hljs-keyword">var</span> name: String,
    <span class="hljs-keyword">var</span> author: String,
    <span class="hljs-keyword">var</span> year: <span class="hljs-built_in">Int</span>
) {

    <span class="hljs-keyword">init</span> {
        println(<span class="hljs-string">"Book <span class="hljs-variable">$name</span> class is called"</span>)
    }

    <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getBookDetails</span><span class="hljs-params">()</span></span> {
        println(
            <span class="hljs-string">"-------------------------- \n"</span> +
                    <span class="hljs-string">"Book Name : <span class="hljs-variable">$name</span> \n"</span> +
                    <span class="hljs-string">"Author Name : <span class="hljs-variable">$author</span> \n"</span> +
                    <span class="hljs-string">"Published Year :<span class="hljs-variable">$year</span> \n"</span> +
                    <span class="hljs-string">"--------------------------"</span>
        )
    }
}
</code></pre>
<p>In the above code, the <code>bookInstance1</code> object is created when the object is initialized and <code>bookInstance2</code> object is not created because the <code>bookInstance2</code> is inside the lazy block which means <code>bookInstance2</code> will be created only when <code>bookInstance2.getBookDetails()</code> is called</p>
<p>Things to note</p>
<ul>
<li><p>the lazy function takes a lambda and returns the lazy instance</p>
</li>
<li><p>It can be used only with non-null variables</p>
</li>
<li><p>val is allowed: var is not allowed</p>
</li>
<li><p>object will be initialized only once and return the same values from the cache memory</p>
</li>
<li><p>prevents unnecessary initialization of objects</p>
</li>
</ul>
<h3 id="heading-please-leave-your-comments-to-improve">Please leave your comments to improve.</h3>
<blockquote>
<p>Enjoy and happy coding</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Kotlin Basics - Companion Object]]></title><description><![CDATA[fun main(){
    println(Car.getInfo())
}

class Car(){

    companion object{
        fun getInfo() : String {
            return "Mahindra XUV 300"
        }
    }

}

As observed from the above example,

Members of companion object can be called si...]]></description><link>https://www.vigneshprabhu.dev/kotlin-basics-companion-object</link><guid isPermaLink="true">https://www.vigneshprabhu.dev/kotlin-basics-companion-object</guid><category><![CDATA[Kotlin]]></category><category><![CDATA[kotlin beginner]]></category><category><![CDATA[android app development]]></category><category><![CDATA[Android]]></category><category><![CDATA[Kotlin Multiplatform]]></category><dc:creator><![CDATA[Vignesh Prabhu]]></dc:creator><pubDate>Sat, 07 Aug 2021 11:20:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1685616775433/6c19f9e0-7098-479d-97a6-a528d129bd9a.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<pre><code class="lang-kotlin"><span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>{
    println(Car.getInfo())
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span></span>(){

    <span class="hljs-keyword">companion</span> <span class="hljs-keyword">object</span>{
        <span class="hljs-function"><span class="hljs-keyword">fun</span> <span class="hljs-title">getInfo</span><span class="hljs-params">()</span></span> : String {
            <span class="hljs-keyword">return</span> <span class="hljs-string">"Mahindra XUV 300"</span>
        }
    }

}
</code></pre>
<p>As observed from the above example,</p>
<ul>
<li><p>Members of companion object can be called simply by using the class name as a qualifier</p>
</li>
<li><p>function inside companion object are called class variables or class functions because they don't belong to a specific object that you create with that class</p>
</li>
<li><p>companion objects look like static members in other languages but in run time those are still instance members of real objects</p>
</li>
<li><p>the members of companion object <strong>can be generated as real static methods</strong> or variables if you use the <strong>@ JVMStatic</strong> annotation</p>
</li>
</ul>
<h1 id="heading-please-leave-your-comments-to-improve">Please leave your comments to improve.</h1>
<blockquote>
<p>Enjoy and Happy coding</p>
</blockquote>
]]></content:encoded></item></channel></rss>