<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://feeds.feedblitz.com/feedblitz_rss.xslt"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:webfeeds="http://webfeeds.org/rss/1.0"  xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
<channel>
	<title>Baeldung - Kotlin</title>
	<atom:link href="https://www.baeldung.com/kotlin/feed" rel="self" type="application/rss+xml" />
	<link>https://www.baeldung.com/kotlin</link>
	<description>Learn about Kotlin in practice</description>
	<lastBuildDate>Fri, 18 Apr 2025 07:09:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/function-reference-ambiguity</feedburner:origLink>
		<title>Removing Ambiguity in Kotlin Function by Reference</title>
		<link>https://feeds.feedblitz.com/~/915016007/0/baeldung/kotlin~Removing-Ambiguity-in-Kotlin-Function-by-Reference</link>
		
		<dc:creator><![CDATA[Albert Ache]]></dc:creator>
		<pubDate>Tue, 18 Mar 2025 11:27:10 +0000</pubDate>
				<category><![CDATA[Kotlin Functions]]></category>
		<category><![CDATA[Lambda Expressions]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/function-reference-ambiguity</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" fetchpriority="high" /><p>A quick tutorial on dealing with ambiguous function references in Kotlin.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/915016007/0/baeldung/kotlin~Removing-Ambiguity-in-Kotlin-Function-by-Reference">Removing Ambiguity in Kotlin Function by Reference</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/915016007/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-04-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/function-parameter-high-order">Pass a Function as Parameter to Another in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/compile-error-type-mismatch-unit-void-expected-fix">Resolving Type Mismatch Inferred Type is Unit But Void Was Expected in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/context-receivers">A Guide to Kotlin Context Receivers</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04.jpg 1200w" sizes="(max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p>In Kotlin, functions are first-class citizens, meaning we can store them in variables, pass them as parameters, or even return them. This flexibility enhances code reuse and modularity. However, dealing with overloaded functions—functions sharing the same name but differing in parameters—can lead to ambiguity when referencing them.</p>
<p>When referencing an overloaded function, the Kotlin compiler may not be able to infer which specific function we intend to use, resulting in a compilation error. This ambiguity can be frustrating, but Kotlin provides several techniques to resolve it.</p>
<p>In this tutorial, we&#8217;ll explore techniques for explicitly specifying function types, using lambdas, leveraging extension functions, and employing higher-order functions.</p>
<h2 id="bd-overloaded-functions-example" data-id="overloaded-functions-example">2. Overloaded Functions Example</h2>
<div class="bd-anchor" id="overloaded-functions-example"></div>
<p>To illustrate the problem, let’s consider a <em>Calculator</em> class with overloaded <em>compute()</em> methods:</p>
<pre><code class="language-kotlin">class Calculator(val base: Int) {
    fun compute(value: Int): Int = base + value  
    fun compute(value: String): String = "$base$value"  
}</code></pre>
<p>The overloaded <em>compute()</em> methods either sum or concatenate our <em>base</em> value with another <em>Int</em> or <em>String</em>.</p>
<p>If we try to reference the <em>compute()</em> method directly without the input type, the compiler can&#8217;t determine which version to use:</p>
<pre><code class="language-kotlin">fun main() {
    val calculator = Calculator(10)
    val compute = calculator::compute
}</code></pre>
<p>This results in a compilation error because the compiler can&#8217;t infer which <em>compute()</em> method to reference. In the following sections, we’ll explore techniques to resolve this ambiguity.</p>
<h2 id="bd-explicitly-specifying-the-function-type" data-id="explicitly-specifying-the-function-type">3. Explicitly Specifying the Function Type</h2>
<div class="bd-anchor" id="explicitly-specifying-the-function-type"></div>
<p>One way to resolve the ambiguity is by explicitly defining the function type when referencing the overloaded function. <strong>This makes it clear to the compiler which version of the function we intend to use</strong>:</p>
<pre><code class="language-kotlin">private val calculator = Calculator(10)
@Test
fun `Should compute with int function`() {
    val computeInt: (Int) -&gt; Int = calculator::compute
    assertEquals(15, computeInt(5))
}
@Test
fun `Should compute with int function`() {
    val computeString: (String) -&gt; String = calculator::compute
    assertEquals("105", computeString("5"))
}</code></pre>
<p>By explicitly specifying the function types <em>(Int) -&gt; Int</em> and <em>(String) -&gt; String</em>, we disambiguate the overloaded functions, allowing the compiler to identify the intended version. This approach is straightforward and leverages Kotlin&#8217;s type inference system effectively.</p>
<h3 id="bd-1-using-type-aliases-for-clarity" data-id="1-using-type-aliases-for-clarity">3.1. Using Type Aliases for Clarity</h3>
<div class="bd-anchor" id="1-using-type-aliases-for-clarity"></div>
<p><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/type-aliases">Type aliases</a> can also resolve ambiguity by providing descriptive names for function types:</p>
<pre><code class="language-kotlin">typealias IntComputer = (Int) -&gt; Int
typealias StringComputer = (String) -&gt; String
private val calculator = Calculator(10)
@Test
fun `should convert int with type alias`() {
    val computeInt: IntComputer = calculator::compute
    assertEquals(15, computeInt(5))
}
@Test
fun `should convert string with type alias`() {
    val computeString: StringComputer = calculator::compute
    assertEquals("105", computeString("5"))
}</code></pre>
<p>By defining type aliases <em>IntComputer</em> and <em>StringComputer</em>, we provide descriptive names for the method types. <strong>This not only resolves function ambiguity but also improves code readability by making the intent clear</strong>.</p>
<p>The <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/junit-5-kotlin">tests</a> ensure the type aliases correctly reference the intended <em>compute()</em> method. In general, the type alias is the same concept as assigning a type to the ambiguous function reference but simplifies referencing a complex function type.</p>
<h2 id="bd-using-lambdas" data-id="using-lambdas">4. Using Lambdas</h2>
<div class="bd-anchor" id="using-lambdas"></div>
<p>Instead of directly referencing the function, we can define typed <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/lambda-expressions">lambdas</a> to call the desired function explicitly. This provides clear context for the compiler:</p>
<pre><code class="language-kotlin">private val calculator = Calculator(10)
@Test
fun `should compute int with lambda`() {
    val computeInt = { value: Int -&gt; calculator.compute(value) }
    assertEquals(15, computeInt(5))
}
@Test
fun `should compute string with lambda`() {
    val computeString = { value: String -&gt; calculator.compute(value) }
    assertEquals("105", computeString("5"))
}</code></pre>
<p><strong>These lambdas work by assigning types to their input type and providing the compiler with context to bypass the</strong> <strong>ambiguity</strong>. The tests ensure that the lambdas correctly invoke the intended compute method.</p>
<h2 id="bd-leveraging-extension-functions" data-id="leveraging-extension-functions">5. Leveraging Extension Functions</h2>
<div class="bd-anchor" id="leveraging-extension-functions"></div>
<p>Another effective way to resolve ambiguity is using non-ambiguous <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/extension-methods#introduction">extension functions</a> to provide clear context for overloaded behavior. Instead of creating a new class, we can define extension functions on the existing <em>Calculator</em> class. These extension functions have unique names to eliminate ambiguity when referencing them:</p>
<pre><code class="language-kotlin">fun Calculator.computeInt(value: Int): Int = compute(value)
fun Calculator.computeString(value: String): String = compute(value)
private val calculator= Calculator(10)
@Test
fun `should compute int with extension function`() {
    val computeInt = calculator::computeInt
    assertEquals(15, computeInt(5))
}
@Test
fun `should compute string with extension function`() {
    val computeString = calculator::computeString
    assertEquals("105", computeString("5"))
}</code></pre>
<p>We define two non-ambiguous extension functions on the <em>Calculator</em> class: <em>computeInt()</em> and <em>computeString()</em>. <strong>These functions internally call the appropriate overloaded <em>compute()</em> method but provide unique names, eliminating ambiguity when referencing them</strong>. Using unique names ensures the compiler can always determine which function to use.</p>
<h2 id="bd-conclusion" data-id="conclusion">6. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we&#8217;ve explored several techniques to resolve ambiguity in overloaded functions.</p>
<p>By explicitly specifying function types, using lambdas, leveraging extension functions, and employing type aliases, we can provide the compiler with the necessary context to determine the correct function. These techniques help avoid compiler errors and also enhance code clarity and maintainability.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/function-reference-ambiguity">Removing Ambiguity in Kotlin Function by Reference</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/915016007/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/915016007/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-04-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/915016007/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/function-parameter-high-order">Pass a Function as Parameter to Another in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/compile-error-type-mismatch-unit-void-expected-fix">Resolving Type Mismatch Inferred Type is Unit But Void Was Expected in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/context-receivers">A Guide to Kotlin Context Receivers</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/format-number-thousand-separator</feedburner:origLink>
		<title>Format Number With Thousand Separator in Kotlin</title>
		<link>https://feeds.feedblitz.com/~/913558097/0/baeldung/kotlin~Format-Number-With-Thousand-Separator-in-Kotlin</link>
		
		<dc:creator><![CDATA[Leo Helfferich]]></dc:creator>
		<pubDate>Sat, 22 Feb 2025 14:44:57 +0000</pubDate>
				<category><![CDATA[Kotlin Numbers]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/?p=56486</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" /><p>Learn different ways to use a thousand separator in Kotlin.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/913558097/0/baeldung/kotlin~Format-Number-With-Thousand-Separator-in-Kotlin">Format Number With Thousand Separator in Kotlin</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/913558097/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-07-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/convert-int-float">Convert Int to Float in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/string-parse-thousands-separator">Parse String With Thousands Separator in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/string-extract-numeric-value">Extract Numbers From a String in Kotlin</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-overview" data-id="overview">1. Overview</h2>
<div class="bd-anchor" id="overview"></div>
<p>In this quick article, we’ll learn about the different approaches to format a number with a thousand separators and how to implement them.</p>
<h2 id="bd-setup" data-id="setup">2. Setup</h2>
<div class="bd-anchor" id="setup"></div>
<p>First, let&#8217;s define our method signature, which we&#8217;ll use for our implementations:</p>
<pre><code class="language-kotlin">fun formatted(number: Int): String</code></pre>
<p>Our function will accept an <em>Int</em> as input and return a <em>String</em>. <strong>The output is a <em>String</em> representation of the input, formatted with a dot separator after each three-character sequence.</strong></p>
<p>For example, putting <em>1000</em> into the function should result in a <em>&#8216;1.000&#8217;</em> s<em>tring</em>; and inserting <em>0</em> should result in <em>&#8216;0&#8217;</em>.</p>
<p>Now, let&#8217;s look at a few approaches.</p>
<h2 id="bd-using-string-format" data-id="using-string-format">3. Using String Format</h2>
<div class="bd-anchor" id="using-string-format"></div>
<p>In our first implementation, we&#8217;ll use <em><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/string/format">String.format</a></em>:</p>
<pre><code class="language-kotlin">String.format(Locale.GERMANY, "%,d", number)
</code></pre>
<p>We use here the following parameters:</p>
<ul>
<li><em><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/java-8-localization#4-constants">Locale.GERMANY</a> </em>makes formatting locale-sensitive. In the case of Germany, the dot character is used.</li>
<li><em>&#8220;%,d&#8221;</em> follows the format convention of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/java-string-formatter"><em>java.util.Formatter</em></a>, which, in this case, adds a thousand separator.</li>
<li><em>number</em> is the input parameter of our function.</li>
</ul>
<p><strong>Using this implementation,</strong> <strong>we take full advantage of a long-established functionality in Kotlin &amp; Java and the adaptability to region-specific settings</strong>.</p>
<p>It is also a very concise, single-line expression, which brings benefits to simplicity and readability.</p>
<h2 id="bd-using-decimalformat" data-id="using-decimalformat">4. Using DecimalFormat</h2>
<div class="bd-anchor" id="using-decimalformat"></div>
<p>The second implementation will make use of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/java-decimalformat">DecimalFormat</a>:</p>
<pre><code class="language-kotlin">DecimalFormat("#,###")
    .format(number)
    .replace(",", ".")
</code></pre>
<p><strong>The <em>&#8220;#,###&#8221;</em> pattern will format our number to a thousand-separated <em>String</em>, but with a comma separator</strong>. That&#8217;s why we need to replace them with a dot.</p>
<p>We could design it even simpler by using the locale-sensitive approach:</p>
<pre><code class="language-kotlin">DecimalFormat("#,###", DecimalFormatSymbols(Locale.GERMANY)).format(number)</code></pre>
<p>Just like the implementation with <em>String.format</em>, the parameter<em> DecimalFormatSymbols(Locale.GERMANY)</em> will produce the dot separator in the formatted <em>String</em>.</p>
<h2 id="bd-using-chunking" data-id="using-chunking">5. Using Chunking</h2>
<div class="bd-anchor" id="using-chunking"></div>
<p>In our last implementation, <strong>we&#8217;ll get creative with the use of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/string-chunking"><em>String</em> chunking</a>:</strong></p>
<pre><code class="language-kotlin">number.toString()
    .reversed() // 15000 -&gt; 00051
    .chunked(3) // [000] [51]
    .joinToString(".") // 000.51
    .reversed() // 15.000</code></pre>
<p>The number as a <em>String</em> is reversed at first because the character sequences must be read from right to left. Then, we chunk it into three-character <em>Strings</em> and join the list with a dot separator. As the last step, the <em>String</em> is reversed again, back to the original order.</p>
<p>Notably, this method lacks localization and adds more complexity, which makes other approaches more desirable.</p>
<h2 id="bd-validation" data-id="validation">6. Validation</h2>
<div class="bd-anchor" id="validation"></div>
<p>Now that we&#8217;ve seen all our different implementations, let&#8217;s test each one for correctness.</p>
<p>We&#8217;ll use the Kotlin native framework <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/kotest">Kotest</a> with the writing style <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://kotest.io/docs/framework/testing-styles.html#should-spec">ShouldSpec</a>. <strong>Its features to write dynamic <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/parameterized-tests-junit-5">parameterized tests</a> will help us greatly.</strong></p>
<p>Here is what our parameterized test would look like:</p>
<pre><code class="language-kotlin">should("return '$expectedString' for $givenNumber with $name implementation") {
    assertThat(function(givenNumber)).isEqualTo(expectedString)
}</code></pre>
<p>As we can notice, there are four parameters:</p>
<ul>
<li><em>$givenNumber</em> is the given integer to test</li>
<li><em>$expectedString</em> is the expected output to test against</li>
<li><em>function</em> is the implementation we test</li>
<li><em>$name</em> is the approach name</li>
</ul>
<p>The assertion checks whether the output of our implementing function is equal to the expected output. The parameter data to iterate through would be:</p>
<pre><code class="language-kotlin">private val givenToExpectedPairs = listOf(
    0 to "0",
    12 to "12",
    456 to "456",
    100_000 to "100.000",
    1_234_567 to "1.234.567"
).forEach { (givenNumber , expectedString) -&gt; /* execute test here */ }</code></pre>
<p><strong>With these pairs, we cover multiple examples, which should be valid for all of the approaches.</strong></p>
<h2 id="bd-conclusion" data-id="conclusion">7. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we&#8217;ve learned how to produce a <em>String</em> representation of an <em>Integer</em> with a thousands separator, including the adaptation to locale-sensitive formatting. In the end, we wrote a dynamic parameterized test to get a good coverage.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/format-number-thousand-separator">Format Number With Thousand Separator in Kotlin</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/913558097/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/913558097/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-07-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/913558097/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/convert-int-float">Convert Int to Float in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/string-parse-thousands-separator">Parse String With Thousands Separator in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/string-extract-numeric-value">Extract Numbers From a String in Kotlin</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/apache-log4j-introduction</feedburner:origLink>
		<title>Introduction to Apache Log4j Kotlin</title>
		<link>https://feeds.feedblitz.com/~/913254527/0/baeldung/kotlin~Introduction-to-Apache-Logj-Kotlin</link>
		
		<dc:creator><![CDATA[Daniel Fintinariu]]></dc:creator>
		<pubDate>Tue, 18 Feb 2025 13:19:33 +0000</pubDate>
				<category><![CDATA[Libraries]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/apache-log4j-introduction</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn to create and use loggers with the Kotlin Log4j library.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/913254527/0/baeldung/kotlin~Introduction-to-Apache-Logj-Kotlin">Introduction to Apache Log4j Kotlin</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/913254527/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-06-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/gradle-exclude-library-all-dependencies">Excluding a Library from All Dependencies in Kotlin DSL in Gradle</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/redis-messaging">PubSub Messaging With Kotlin Redis</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/kandy">Plotting Charts in Kotlin With Kandy</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-overview" data-id="overview">1. Overview</h2>
<div class="bd-anchor" id="overview"></div>
<p>In this article, we&#8217;ll explore how to <strong>integrate and use the Apache Log4j Kotlin library</strong>. Log4j is a robust logging framework widely used in the Java ecosystem composed of an API, its implementation, and components that assist the deployment of various use cases. The library provides a Kotlin-friendly interface to the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/java-logging-intro">Log4j API</a>.</p>
<h2 id="bd-why-log4j" data-id="why-log4j">2. Why Log4j?</h2>
<div class="bd-anchor" id="why-log4j"></div>
<p>Although the discovery of the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://en.wikipedia.org/wiki/Log4Shell">Log4Shell vulnerability (CVE-2021-44228)</a> has shaken its reputation, it remains widely adopted, providing powerful features such as asynchronous logging, JSON support, and a highly configurable architecture.</p>
<p>Using the Log4j framework allows us to <strong>filter logs based on configurable levels such as DEBUG, INFO, or ERROR</strong> without needing to change our code.</p>
<p>It also provides the flexibility to direct logs to various outputs like files, databases, or remote systems rather than being limited to the console.</p>
<h2 id="bd-dependencies" data-id="dependencies">3. Dependencies</h2>
<div class="bd-anchor" id="dependencies"></div>
<p>To set up Log4j in a Kotlin project, we need to <strong>include the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api-kotlin">dependencies</a> for both the API and the Log4j backend:</strong></p>
<pre><code class="language-kotlin">&lt;dependency&gt;
    &lt;groupId&gt;org.apache.logging.log4j&lt;/groupId&gt;
    &lt;artifactId&gt;log4j-api-kotlin&lt;/artifactId&gt;
     &lt;version&gt;1.5.0&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.apache.logging.log4j&lt;/groupId&gt;
    &lt;artifactId&gt;log4j-core&lt;/artifactId&gt;
    &lt;version&gt;2.20.0&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
<h2 id="bd-creating-loggers" data-id="creating-loggers">4. Creating Loggers</h2>
<div class="bd-anchor" id="creating-loggers"></div>
<p>With the library imported, let&#8217;s look at some common ways to create loggers.</p>
<h3 id="bd-1-logger-in-companion-objects" data-id="1-logger-in-companion-objects">4.1. Logger in Companion Objects</h3>
<div class="bd-anchor" id="1-logger-in-companion-objects"></div>
<p><strong>The traditional approach is to use a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/companion-object"><em>companion object</em></a></strong> that all instances of the class can share:</p>
<pre><code class="language-kotlin">class Game {
    companion object {
        private val logger = logger()
    }
    fun startGame() {
        logger.info { "Game is starting..." }
    }
}</code></pre>
<p>An alternative would be to <strong>extend the <em>companion object</em> from the <em>Logging</em> class</strong>:</p>
<pre><code class="language-kotlin">class Game {
    companion object: Logging
    fun startGame() {
        logger.info { "Game is starting..." }
    }
}</code></pre>
<p>While both methods are straightforward, <strong>the traditional approach is more efficient as the logger lookup is performed once</strong>. The alternative, which extends the class, adds extra overhead due to the logger lookup involved at runtime.</p>
<p>When we run the code, we&#8217;ll notice that there&#8217;s no output, and that&#8217;s because we need to specify the log level:</p>
<pre><code class="language-kotlin">Configurator.setRootLevel(Level.DEBUG)</code></pre>
<p>In the next chapter, we&#8217;ll expand on this topic and the common way to set up an external configuration file, allowing us to keep our code free from hardcoded log-level management.</p>
<h3 id="bd-2-logger-in-class" data-id="2-logger-in-class">4.2. Logger in Class</h3>
<div class="bd-anchor" id="2-logger-in-class"></div>
<p>Alternatively, we can <strong>define the logger within the class</strong>:</p>
<pre><code class="language-kotlin">class Player(val name: String) {
    private val logger = logger()
    fun joinGame() {
        logger.info { "Player '$name' has joined the game." }
    }
    fun takeDamage(amount: Int) {
        logger.warn { "Player '$name' took $amount damage!" }
    }
}</code></pre>
<p>Although not recommended, this approach creates a logger instance for each class instance, which may be suitable in certain scenarios.</p>
<p>When creating the logger in the class, <strong>we can pass it a <em>name</em> parameter</strong>, ensuring that when the code is run, we&#8217;ll know exactly which logger was used:</p>
<pre><code class="language-kotlin">val logger = logger("Player Action")
</code></pre>
<p>In this case, the output will contain our defined name instead of the class name.</p>
<h3 id="bd-3-using-the-logging-interface" data-id="3-using-the-logging-interface">4.3. Using the Logging Interface</h3>
<div class="bd-anchor" id="3-using-the-logging-interface"></div>
<p>We could also use the <em>Logging</em> <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/interfaces">interface</a>, offering us a quick and convenient way to access the logger.</p>
<p>Let&#8217;s create a utility class that implements it:</p>
<pre><code class="language-kotlin">class GameUtil : Logging {
    fun logEvent(event: String) {
        logger.info { "Game Event: $event" }
    }
}</code></pre>
<p>When using this method, we effectively create a single <em>Logger</em> instance that is exclusively associated with the class instance and not shared among other instances.</p>
<p>Let&#8217;s look at a usage example:</p>
<pre><code class="language-kotlin">val util = GameUtil()
util.logEvent("Level 1 Loaded")</code></pre>
<h3 id="bd-4-using-the-logger-extension-property" data-id="4-using-the-logger-extension-property">4.4. Using the Logger Extension Property</h3>
<div class="bd-anchor" id="4-using-the-logger-extension-property"></div>
<p>As a substitute, we can <strong>use the <em>logger</em> <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/extension-fields">extension</a> property to dynamically inject a logger on the spot</strong>:</p>
<pre><code class="language-kotlin">class Enemy {
    fun shoot() {
        logger.warn { "Enemy shoots the player" }
    }
}</code></pre>
<p>In this case, the logger will look up the associated <em>Logger</em> instance for the encapsulating class, adding extra overhead at runtime.</p>
<h2 id="bd-logger-configuration" data-id="logger-configuration">5. Logger Configuration</h2>
<div class="bd-anchor" id="logger-configuration"></div>
<p>Now that we&#8217;ve looked at the most common ways to use Log4j for Kotlin let&#8217;s check out<strong> how to configure it for our needs</strong>.</p>
<p>As mentioned in the previous chapter, the log level has been set to <em>debug</em> by hardcoding it. Now,<strong> we can create a configuration file named <em>log4j2.xml</em> in our <em>resources </em>folder</strong>, which the logger can use:</p>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;Configuration status="WARN"&gt;
    &lt;Appenders&gt;
        &lt;Console name="ConsoleAppender" target="SYSTEM_OUT"&gt;
            &lt;PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/&gt;
        &lt;/Console&gt;
    &lt;/Appenders&gt;
    &lt;Loggers&gt;
        &lt;Root level="info"&gt;
            &lt;AppenderRef ref="ConsoleAppender"/&gt;
        &lt;/Root&gt;
    &lt;/Loggers&gt;
&lt;/Configuration&gt;</code></pre>
<p>This configuration defines a console appender with a specific pattern layout, ensuring that all log messages are output with a timestamp, thread information, log level, and message.</p>
<p>Additionally, we&#8217;re setting the log level to <em>info. Therefore,</em> the output will display only the messages of log level <em>info</em>, <em>warn</em>, <em>error,</em> and <em>fatal</em>, omitting the <em>debug </em>and<em> trace </em>levels.</p>
<p>The seven log levels provided help us separate the type of events that occur when our program is running, thus resulting in a hierarchy.</p>
<p>When set to <em>all</em>, for example, the log level will output all logger messages, while setting it to <em>error</em> will only display logged errors and fatals. Log level <em>all</em> is a special marker that&#8217;s rarely used in application code.</p>
<h2 id="bd-best-practices" data-id="best-practices">6. Best Practices</h2>
<div class="bd-anchor" id="best-practices"></div>
<p>To maximize the effectiveness of logging in our Kotlin applications, we should follow these best practices consistently.</p>
<p>In most applications, <strong>we should create a single logger per class definition rather than per instance</strong>. This approach prevents redundant fields and clearly conveys the static binding to the class.</p>
<p><strong>We should use the appropriate log level that corresponds to the severity of the events</strong>, such as:</p>
<ul>
<li><em>trace </em> to capture detailed information about the application&#8217;s behavior</li>
<li><em>debug</em> for detailed information during debugging<em>; </em></li>
<li><em>info</em> for general operational messages<em>;
<br>
</em></li>
<li><em>warn</em> for indication of potential issues<em>; </em></li>
<li><em>error</em> for error events that might still allow the application to continue running<em>;</em></li>
<li><em>fatal</em> for severe errors causing premature termination.</li>
</ul>
<p>Additionally, <strong>we must ensure that sensitive data, such as passwords, personal information, or tokens, is never logged to prevent <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/cs/vulnerability-pen-testing">security vulnerabilities</a></strong>.</p>
<p>Our codebase should <strong>maintain a consistent log format across applications</strong>, which is essential for easier parsing and analysis. To achieve this, we define a standard pattern in the configuration and consistently follow it throughout.</p>
<h2 id="bd-conclusion" data-id="conclusion">7. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we&#8217;ve explored multiple ways of creating loggers using the Kotlin Log4j library.</p>
<p>To begin, we tackled the differences between creating class-based loggers versus instance-based ones, as well as using the <em>Logging</em> interface and extension property.</p>
<p>Moving forward, we went through the configuration file, avoiding hardcoded log-level settings, and checked out some of the best practices when working with loggers.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/apache-log4j-introduction">Introduction to Apache Log4j Kotlin</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/913254527/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/913254527/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-06-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/913254527/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/gradle-exclude-library-all-dependencies">Excluding a Library from All Dependencies in Kotlin DSL in Gradle</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/redis-messaging">PubSub Messaging With Kotlin Redis</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/kandy">Plotting Charts in Kotlin With Kandy</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/flow-catch-operator</feedburner:origLink>
		<title>Kotlin Flow catch() Operator</title>
		<link>https://feeds.feedblitz.com/~/912932663/0/baeldung/kotlin~Kotlin-Flow-catch-Operator</link>
		
		<dc:creator><![CDATA[Albert Ache]]></dc:creator>
		<pubDate>Thu, 13 Feb 2025 22:26:48 +0000</pubDate>
				<category><![CDATA[Kotlin Concurrency]]></category>
		<category><![CDATA[Coroutines]]></category>
		<category><![CDATA[Flows]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/flow-catch-operator</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>A quick tutorial on using the catch() operator with Kotlin coroutines.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/912932663/0/baeldung/kotlin~Kotlin-Flow-catch-Operator">Kotlin Flow catch() Operator</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912932663/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-06-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-testing">Testing Flow in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-current-previous-value">Get Current and Previous Value in Kotlin Flow&#8217;s collect</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/combine-state-flows">Combine 2 Kotlin State Flows Into a Single State Flow</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p><span style="margin: 0px;padding: 0px">Handling exceptions is critical to building resilient applications, and Kotlin <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/flow-intro"><em>Flow</em></a> simplifies this with the <em>catch()</em> operator. This allows us to handle exceptions gracefully during a <em>Flow</em>&#8216;s emission of values. Whether we want to log errors, emit fallback values, or implement retry logic, <em>catch()</em> helps maintain a flow&#8217;s lifecycle without abrupt termination. </span></p>
<p>This tutorial explores various ways to use the <em>catch()</em> operator effectively, illustrated with clear examples and unit tests.</p>
<h2 id="bd-basic-usage-of-the-catch-operator" data-id="basic-usage-of-the-catch-operator">2. Basic Usage of the <em>catch()</em> Operator</h2>
<div class="bd-anchor" id="basic-usage-of-the-catch-operator"></div>
<p>The <em>catch()</em> operator lets us capture and handle exceptions upstream in a <em>Flow</em>. <strong>Instead of terminating the <em>Flow</em> abruptly on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/functional-error-handling">error</a>, we can intercept it and decide how to proceed</strong>:</p>
<pre><code class="language-kotlin">@Test
fun `catch operator logs exception`() = runTest {
    val emittedValues = mutableListOf&lt;Int&gt;()
    val flow = flow {
        emit(1)
        emit(2)
        throw IllegalStateException("Test exception")
    }
    flow.catch { e -&gt;
        assertEquals("Test exception", e.message)
    }.collect {
        emittedValues.add(it)
    }
    assertEquals(listOf(1, 2), emittedValues)
}</code></pre>
<p>In this <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/junit-5-kotlin">test</a>, the <em>Flow</em> emits two integers before throwing an exception. The <em>catch()</em> block captures the exception and verifies its message. Then we collect the emitted values to a <em>List</em> to confirm that the <em>Flow</em> still completes successfully. This ensures that the <em>Flow</em> handles errors gracefully without crashing.</p>
<h2 id="bd-emitting-a-fallback-value-in-catch" data-id="emitting-a-fallback-value-in-catch">3. Emitting a Fallback Value in <em>catch()</em></h2>
<div class="bd-anchor" id="emitting-a-fallback-value-in-catch"></div>
<p>Sometimes we might want to <em>emit()</em> a fallback value instead of terminating the <em>Flow</em> when an error occurs:</p>
<pre><code class="language-kotlin">@Test
fun `catch operator emits fallback value`() = runTest {
    val emittedValues = mutableListOf&lt;Int&gt;()
    val flow = flow {
        emit(1)
        throw IllegalArgumentException("Simulated error")
    }
    flow.catch {
        emit(-1) 
    }.collect {
        emittedValues.add(it)
    }
    assertEquals(listOf(1, -1), emittedValues)
}</code></pre>
<p>The <em>Flow</em> emits a single value before throwing an exception. <strong>The <em>catch()</em> block also emits a value</strong>. Then we ensure that the collector still receives both emissions. This approach is ideal for providing default data when the flow fails.</p>
<h2 id="bd-combining-catch-with-retry-logic" data-id="combining-catch-with-retry-logic">4. Combining <em>catch()</em> With Retry Logic</h2>
<div class="bd-anchor" id="combining-catch-with-retry-logic"></div>
<p>Transient errors such as network issues can sometimes be resolved with retries. <strong>Kotlin <em>Flow</em> allows us to combine the <em>catch()</em> operator with retry mechanisms to handle these situations elegantly</strong>:</p>
<pre><code class="language-kotlin">@Test
fun `catch operator works with retries`() = runTest {
    var attempt = 0
    val emittedValues = mutableListOf&lt;Int&gt;()
    val flow = flow {
        if (attempt++ &lt; 3){
            throw RuntimeException("Network error")
        }
        emit(1)
    }
    flow.retry(3) { it is RuntimeException }
        .catch { 
            emit(-1)
        }
        .collect {
            emittedValues.add(it)
        }
    assertEquals(listOf(1), emittedValues)
}</code></pre>
<p>This test simulates a <em>Flow </em>that fails three times before successfully emitting a value. The <em>retry()</em> operator ensures that the <em>Flow</em> is re-executed up to three times whenever a <em>RuntimeException</em> occurs.</p>
<p>If the error persists beyond three attempts, it propagates to the <em>catch()</em> block, which emits a negative one. <strong>However, because our retry succeeds, the exception never reaches <em>catch()</em>, as the error is effectively &#8220;swallowed&#8221; during the retry process</strong>. This means that<em> catch()</em> will only execute if all retry attempts fail, ensuring that the <em>Flow</em> either recovers from transient failures or gracefully handles an unrecoverable error.</p>
<h2 id="bd-handling-specific-exceptions-with-conditional-logic" data-id="handling-specific-exceptions-with-conditional-logic">5. Handling Specific Exceptions With Conditional Logic</h2>
<div class="bd-anchor" id="handling-specific-exceptions-with-conditional-logic"></div>
<p>Sometimes, we may want to handle specific types of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/exception-handling">exceptions</a> differently. We can also inspect the exception in the <em>catch()</em> and handle errors differently:</p>
<pre><code class="language-kotlin">@Test
fun `catch operator handles specific exceptions`() = runTest {
    val emittedValues = mutableListOf&lt;Int&gt;()
    val flow = flow {
        emit(1)
        throw IllegalStateException("Recoverable error")
    }
    flow.catch { e -&gt;
        if (e is IllegalArgumentException) {
            emit(-1)
        } else {
            throw e
        }
    }.collect {
        emittedValues.add(it)
    }
    assertEquals(listOf(1, -1), emittedValues)
}</code></pre>
<p><span style="margin: 0px;padding: 0px">The <em>Flow</em> emits a value before throwing an exception. Then this test demonstrates how the <em>catch()</em> operator can selectively handle specific exceptions, such as an <em>IllegalArgumentException</em>.</span></p>
<p>The <em>IllegalArgumentException</em> is treated as recoverable and we emit a value when handling it. All other exceptions are rethrown to avoid suppressing critical issues. <strong>This ensures a balance between error recovery and transparency, allowing the collector to continue when encountering recoverable errors</strong>.</p>
<h2 id="bd-benefits-of-using-the-catch-operator" data-id="benefits-of-using-the-catch-operator">6. Benefits of Using the <em>catch()</em> Operator</h2>
<div class="bd-anchor" id="benefits-of-using-the-catch-operator"></div>
<p>The <em>catch()</em> operator enhances error handling in Kotlin <em>Flow</em> by providing a structured and readable approach to managing exceptions:</p>
<ul>
<li><strong>Smooth Error Management</strong>: It prevents crashes by handling exceptions gracefully, ensuring data flows continue without disruption.</li>
<li><strong>Targeted Exception Handling</strong>: <em>catch()</em> only intercepts upstream errors, allowing downstream exceptions to propagate naturally, maintaining precise control over error handling.</li>
<li><strong>Flexible Responses</strong>: Developers can log errors, provide alternative values, or rethrow exceptions, adapting to various application needs.</li>
<li><strong>Improved Readability</strong>: By reducing scattered try-catch blocks, <em>catch()</em> keeps the codebase clean and maintainable.</li>
<li><strong>Seamless Integration</strong>: It works well with other <em>Flow</em> operators, enabling robust, composable, and resilient data pipelines.</li>
</ul>
<h2 id="bd-conclusion" data-id="conclusion">7. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we explored the <em>catch()</em> operator of the Kotlin <em>Flow</em>, highlighting its role in managing exceptions gracefully without disrupting data processing. We also demonstrated how to log errors, emit fallback values, and handle specific exceptions while maintaining clean and readable code.</p>
<p><span style="margin: 0px;padding: 0px">The <em>catch()</em> operator enhances error handling and integrates seamlessly with other <em>Flow</em> operators like <em>retry()</em>, making it indispensable for building resilient, fault-tolerant applications. It also provides uninterrupted data flows and maintains robust application performance.</span></p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/flow-catch-operator">Kotlin Flow catch() Operator</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/912932663/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912932663/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-06-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912932663/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-testing">Testing Flow in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-current-previous-value">Get Current and Previous Value in Kotlin Flow&#8217;s collect</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/combine-state-flows">Combine 2 Kotlin State Flows Into a Single State Flow</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/stateflows-testing</feedburner:origLink>
		<title>Testing StateFlows in Kotlin</title>
		<link>https://feeds.feedblitz.com/~/911563871/0/baeldung/kotlin~Testing-StateFlows-in-Kotlin</link>
		
		<dc:creator><![CDATA[Vinay Wadhwa]]></dc:creator>
		<pubDate>Thu, 23 Jan 2025 19:24:12 +0000</pubDate>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[Flows]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/?p=56435</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Explore the best practices of unit testing StateFlows: the cases with single and continuous state updates, as well as converting a regular Flow into a StateFlow.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/911563871/0/baeldung/kotlin~Testing-StateFlows-in-Kotlin">Testing StateFlows in Kotlin</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/911563871/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-05-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-catch-operator">Kotlin Flow catch() Operator</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-testing">Testing Flow in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/kluent">Introduction to Kluent Assertion Library</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p class="p1"><span class="s1"><em>StateFlow</em>s are an integral part of modern Kotlin applications. They are part of the Kotlin Coroutines library and provide a way to manage and observe state changes reactively. Testing these flows ensures that our applications behave as expected under various conditions. </span></p>
<p class="p1"><span class="s1">In this article, we&#8217;ll explore multiple approaches and best practices to effectively unit test <em>StateFlow</em>s<em>.</em></span></p>
<h2 id="bd-understanding-stateflow-fundamentals" data-id="understanding-stateflow-fundamentals">2. Understanding <em>StateFlow</em> Fundamentals</h2>
<div class="bd-anchor" id="understanding-stateflow-fundamentals"></div>
<p>When working with state management in Kotlin, we often encounter various approaches. This might include simple variables to reactive streams. <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-state-flow/"><em>StateFlow</em></a> sits at a sweet spot between these approaches. <strong>It combines the reactive nature of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/flow-intro">Flows</a> with state-holding abilities.</strong></p>
<p class="p1"><span class="s1">Let&#8217;s look at a basic implementation of <em>StateFlow</em>:</span></p>
<pre><code class="language-kotlin">class StateFlowExample {
    private val _state = MutableStateFlow("Initial State")
    private val state: StateFlow&lt;String&gt; = _state.asStateFlow()
    fun getCurrentState() = state.value
    fun updateState(newValue: String) {
        _state.value = newValue
    }
}</code></pre>
<p>In this example, we create a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-mutable-state-flow/"><em>MutableStateFlow</em></a> with an initial value. The state is exposed as an immutable <em>StateFlow</em> to prevent external modifications.</p>
<p><span class="s1"><em>StateFlow</em> maintains a current value that can be accessed synchronously while providing a way to observe changes over time. Also, unlike regular Flows, <em>StateFlow</em> is &#8220;hot&#8221;. This means it&#8217;s always active and maintains its current state regardless of collectors. </span></p>
<p><span class="s1">These characteristics make it suitable for managing the application state, where we need both the current value and updates to that value. When a new collector starts observing a <em>StateFlow</em>, it immediately receives the current state and subsequently receives any new state updates.</span></p>
<h2 id="bd-setting-up-for-stateflow-testing" data-id="setting-up-for-stateflow-testing">3. Setting Up for <em>StateFlow</em> Testing</h2>
<div class="bd-anchor" id="setting-up-for-stateflow-testing"></div>
<p>Testing <em>StateFlow</em>s requires careful setup of the testing environment. The key is creating a controlled environment where we can predictably emit states and verify our flow&#8217;s behavior.</p>
<p><strong>The <em><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-test/">kotlinx-coroutines-test</a></em> library provides essential tools for testing coroutines and flows.</strong> It offers utilities to control coroutine execution and manage test scopes.</p>
<p>Let&#8217;s build on our previous <em>StateExample</em> class and create a proper test environment. First, we&#8217;ll set up a basic test class:</p>
<pre><code class="language-kotlin">class StateFlowUnitTest {
    private lateinit var stateFlowExample: StateFlowExample
    @Test
    fun `initial state is correct`() = runTest {
        stateFlowExample = StateFlowExample()
        // Initial state verification
        assertEquals("Initial State", stateFlowExample.getCurrentState())
    }
}</code></pre>
<p>In our example, we create a new instance of the <em>StateFlowExample</em> class and verify that the initial state is as expected.</p>
<p><span class="s1">To test this state holder effectively, we need a controlled environment. The </span><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/run-test.html"><em><span class="s2">runTest</span></em></a><span class="s1"> builder from the <em>kotlinx-coroutines-test</em> library is crucial for that. </span></p>
<p><span class="s1">The <em>runTest</em> builder creates a coroutine scope specifically designed for testing. This scope uses a special test dispatcher that gives us control over virtual time, which helps make our tests both reliable and fast.</span></p>
<p>With this testing environment in place, let&#8217;s explore how to test different <em>StateFlow</em> scenarios, starting with the simplest case: single-state emissions.</p>
<h2 id="bd-testing-single-emissions" data-id="testing-single-emissions">4. Testing Single Emissions</h2>
<div class="bd-anchor" id="testing-single-emissions"></div>
<p>Let&#8217;s start with the simplest case: testing what happens when we update our state once. <strong>We want to verify that when we update the state, the new value is correctly reflected in our <em>StateFlow</em>.</strong></p>
<p>Let&#8217;s expand our previous test class to include state change verification:</p>
<pre><code class="language-kotlin">@Test
fun `state updates properly`() = runTest {
    stateFlowExample = StateFlowExample()
    stateFlowExample.updateState("New State")
    assertEquals("New State", stateFlowExample.getCurrentState())
}</code></pre>
<p>In this test, we&#8217;re verifying two important aspects of <em>StateFlow</em> behavior. First, we verify that the update correctly overrides the initial value. Second, we confirm that updating the state changes the current value.</p>
<p>While testing single updates is straightforward, real-world applications often need to handle a stream of updates. Let&#8217;s explore how to test these continuous state changes.</p>
<h2 id="bd-testing-continuous-state-updates" data-id="testing-continuous-state-updates">5. Testing Continuous State Updates</h2>
<div class="bd-anchor" id="testing-continuous-state-updates"></div>
<p class="p1"><strong>When working with <em>StateFlow</em> in real applications, we rarely deal with a single state update.</strong></p>
<p class="p1">Let&#8217;s think about a typical user session: a user logs in, performs various actions, updates their profile, and logs out. Each of these actions might trigger state changes our application needs to handle. We need to verify not just that each state update works, but that our <em>StateFlow</em> correctly manages this entire sequence of changes. This becomes especially important when multiple parts of our application are observing these state changes and need to react to them reliably.</p>
<p class="p1">The following test demonstrates how to verify a sequence of state updates by collecting and asserting multiple state changes:</p>
<pre><code class="language-kotlin">@Test
fun `collects all state updates`() = runTest {
    stateFlowExample = StateFlowExample()
    val collectedStates = mutableListOf&lt;String&gt;()
    val collectJob = launch {
        stateFlowExample.state.collect { state -&gt;
          collectedStates.add(state)
        }
    }
    // Advance the time to make the initial state available for collection
    advanceUntilIdle()
    stateFlowExample.updateState("First Update")
    advanceUntilIdle() // Advance the time to make the first update available
    stateFlowExample.updateState("Second Update")
    advanceUntilIdle() // Advance the time to make the second update available
    stateFlowExample.updateState("Third Update")
    advanceUntilIdle() // Advance the time to make the third update available
    assertEquals(4, collectedStates.size) // Initial state + 3 updates
    assertEquals("Initial State", collectedStates[0])
    assertEquals("First Update", collectedStates[1])
    assertEquals("Second Update", collectedStates[2])
    assertEquals("Third Update", collectedStates[3])
    // Cancel the job to stop collecting states and let the test finish
    collectJob.cancel()
}</code></pre>
<p>Let&#8217;s break down what&#8217;s happening in this test. We start by collecting states from our <em>StateFlow</em> into a list &#8211; this lets us verify both the sequence and content of state changes.</p>
<p class="p1"><span class="s1">The </span><em><span class="s2">launch</span></em><span class="s1"> coroutine builder creates a new coroutine that collects states throughout our test. The </span><em><span class="s2">collect</span></em><span class="s1"> function observes all state changes and adds each new state to our list as it is collected.</span></p>
<p>Each time we update the state, we need to ensure the update has been processed before moving forward. The testing library gives us a few ways to handle this timing. In this example, we&#8217;re using <em>advanceUntilIdle(),</em> but we could also use <em>yield()</em> or <em>advanceTimeBy(timeMillis)</em>. Each approach has its use cases, but <strong><em>advanceUntilIdle()</em> is often the simplest choice as it ensures all pending work is completed before continuing.</strong></p>
<p>Now that we understand how to test both single updates and continuous state changes, let&#8217;s explore how to test <em>StateFlows</em> created using the <em>stateIn</em> operator, which introduces its own set of testing considerations.</p>
<h2 class="p1" id="bd-testing-statein-transformations" data-id="testing-statein-transformations"><span class="s1">6. Testing <em>stateIn</em> Transformations</span></h2>
<div class="bd-anchor" id="testing-statein-transformations"></div>
<p>The <em><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/state-in.html">stateIn</a> </em>operator converts a regular <em>Flow</em> into a <em>StateFlow</em>. <strong>We can use this transformation when we need to combine the reactive nature of Flows with the state-holding capabilities of <em>StateFlow</em>s</strong>. However, testing these transformations requires some additional considerations.</p>
<p>Let&#8217;s look at a simple example that mirrors how we might transform data from a repository or database in a real application:</p>
<pre><code class="language-kotlin">class DataTransformer(scope: CoroutineScope) {
    private val _dataFlow = MutableSharedFlow&lt;String&gt;()  // Simulates a repository stream
    val transformedData = _dataFlow
      .map { it.uppercase() }
      .stateIn(
        scope = scope,
        started = SharingStarted.Eagerly,
        initialValue = "INITIAL"
      )
    suspend fun emit(value: String) {
        _dataFlow.emit(value)
    }
}
</code></pre>
<p class="p1"><span class="s1">Here&#8217;s how we can test these transformations:</span></p>
<pre><code class="language-kotlin">@Test
fun `transforms to uppercase states`() = runTest {
    val testScope = TestScope(UnconfinedTestDispatcher())
    val transformer = DataTransformer(testScope)
    val collectedStates = mutableListOf&lt;String&gt;()
    val collectJob = launch {
        transformer.transformedData.collect { state -&gt;
          collectedStates.add(state)
        }
    }
    advanceUntilIdle() // Wait for initial collection
    transformer.emit("first")
    advanceUntilIdle() // Wait for first emission
    transformer.emit("second")
    advanceUntilIdle() // Wait for second emission
    assertEquals(3, collectedStates.size)
    assertEquals("INITIAL", collectedStates[0])
    assertEquals("FIRST", collectedStates[1])
    assertEquals("SECOND", collectedStates[2])
    collectJob.cancel()
    testScope.cancel()
}</code></pre>
<p>Each sharing strategy serves different use cases, and our tests need to reflect these differences. The key is understanding when transformations begin and how they respond to collectors.</p>
<p><strong>The use of <em>UnconfinedTestDispatcher</em> here is notable. It executes coroutines eagerly and immediately in the same thread, rather than dispatching or queuing them.</strong> This means that when we emit a value, its transformation (uppercase) and collection happen immediately one after the other. This makes our tests more predictable.</p>
<h2 id="bd-conclusion" data-id="conclusion">7. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this tutorial, we&#8217;ve explored different testing scenarios in this article. These range from simple state updates to continuous emissions and <em>StateFlow</em> transformations.</p>
<p>We also explored some tools from the <em>kotlinx-coroutines-test</em> library. We can use them to write reliable tests for our <em>StateFlow</em> implementations.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/stateflows-testing">Testing StateFlows in Kotlin</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/911563871/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/911563871/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-05-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/911563871/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-catch-operator">Kotlin Flow catch() Operator</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-testing">Testing Flow in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/kluent">Introduction to Kluent Assertion Library</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-05-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/mono-empty-check</feedburner:origLink>
		<title>Check if Mono Is Empty With Kotlin</title>
		<link>https://feeds.feedblitz.com/~/911563874/0/baeldung/kotlin~Check-if-Mono-Is-Empty-With-Kotlin</link>
		
		<dc:creator><![CDATA[Leonardo Colman Lopes]]></dc:creator>
		<pubDate>Thu, 23 Jan 2025 19:16:10 +0000</pubDate>
				<category><![CDATA[Asynchronous Programming]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/mono-empty-check</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn to check if a Mono is empty in Kotlin and define static and dynamic fallback values to create robust reactive flows.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/911563874/0/baeldung/kotlin~Check-if-Mono-Is-Empty-With-Kotlin">Check if Mono Is Empty With Kotlin</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/911563874/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-04-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/coroutine-continuation">Kotlin Coroutine Continuation</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flows-sequential-concatenation">Sequentially Concatenate 2 Kotlin Flows</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p>The <em>Mono</em> is a reactive type provided by <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/reactor-core">Project Reactor</a>, representing either a single asynchronous value or no value. When working with <span style="margin: 0px;padding: 0px"><em>Mono</em>, determining whether it</span> is empty helps with correct application behavior.</p>
<p>In this tutorial, we&#8217;ll explore how to check if a <em>Mono</em> is empty in Kotlin, leveraging <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/junit-5">JUnit</a> test cases for demonstration.</p>
<h2 id="bd-understanding-mono-emptiness-and-mapping-behavior" data-id="understanding-mono-emptiness-and-mapping-behavior">2. Understanding <em>Mono</em> Emptiness and Mapping Behavior</h2>
<div class="bd-anchor" id="understanding-mono-emptiness-and-mapping-behavior"></div>
<p><strong>A <em>Mono</em> represents either a single asynchronous value or no value (empty)</strong>. When working with monos, it&#8217;s crucial to understand how they behave when empty:</p>
<ul>
<li><strong>Mapping Behavior:</strong> When a <em>Mono</em> is empty, any mapping function (<em>flatMap()</em>, <em>map()</em>, or similar) applied to it will not execute. This means that if we chain operations on a <em>Mono</em>, those operations will only run if the <em>Mono</em> emits a value.</li>
<li><strong>Default or Fallback Handling:</strong> To handle cases where a <em>Mono</em> is empty, methods like <em>defaultIfEmpty()</em> or <em>switchIfEmpty()</em> allow us to define alternative behavior.</li>
</ul>
<p>For example:</p>
<pre><code class="language-kotlin">@Test
fun `mapping function is skipped for empty Mono`() {
    <span class="hljs-keyword">val</span> callCount = AtomicInteger(<span class="hljs-number">0</span>)
    val emptyMono = Mono.empty&lt;String&gt;()
    val resultMono = emptyMono.map { 
        callCount.incrementAndGet()
        it.uppercase() 
    }
    StepVerifier.create(resultMono)
        .verifyComplete() // No value emitted, Mono completes directly
    assertEquals(0, callCount.get())
}
</code></pre>
<p>This fundamental behavior ensures efficient handling of empty states and provides the foundation for more advanced techniques, such as defining default values or fallbacks.</p>
<p><strong>When a <em>Mono</em> completes without emitting a value, it implicitly means that any mapping or transformation functions in the chain were skipped</strong>. While verifying completeness does not directly prove the mapper wasn’t called, combining it with additional tracking mechanisms like a counter or logging provides concrete evidence.</p>
<h2 id="bd-checking-mono-emptiness-with-haselement" data-id="checking-mono-emptiness-with-haselement">3. Checking <em>Mono</em> Emptiness with <em>hasElement()</em></h2>
<div class="bd-anchor" id="checking-mono-emptiness-with-haselement"></div>
<p><strong>Using <em>hasElement()</em> allows us to determine whether a <em>Mono</em> emits a value</strong>. This method is useful when checking whether the <em>Mono</em> contains any value before proceeding with further operations.</p>
<p>First, let&#8217;s verify this function on an empty <em>Mono</em>:</p>
<pre><code class="language-kotlin">@Test
fun `should detect empty Mono using hasElement`() {
    val emptyMono = Mono.empty&lt;String&gt;()
    StepVerifier.create(emptyMono.hasElement())
        .expectNext(false)
        .verifyComplete()
}</code></pre>
<p>We created an empty <em>Mono</em> with <em>Mono.empty()</em> and verified that <em>hasElement()</em> emits <em>false</em>.</p>
<p>Now, let&#8217;s try with a <em>Mono</em> that has a value. We&#8217;ll use <em>Mono.just()</em> to start with a basic value:</p>
<pre><code class="language-kotlin">@Test
fun `should detect non-empty Mono using hasElement`() {
    val nonEmptyMono = Mono.just("Hello, World!")
    StepVerifier.create(nonEmptyMono.hasElement())
        .expectNext(true)
        .verifyComplete()
}</code></pre>
<p>Now, we see that <em>hasElement()</em> emits <em>true</em> when a value is present.</p>
<p><strong>Calling the <em>hasElement()</em> method on a <em>Mono</em> creates a new <em>Mono</em> that emits a boolean</strong><span style="margin: 0px;padding: 0px"><strong> indicating if the original </strong><em><strong>Mono</strong></em><strong> is empty</strong>. We can use <em>StepVerifier</em> to check the value emitted from our <em>Mono</em> and ensure</span> it completes as expected.</p>
<h2 id="bd-providing-a-default-value-with-defaultifempty" data-id="providing-a-default-value-with-defaultifempty">4. Providing a Default Value with <em>defaultIfEmpty()</em></h2>
<div class="bd-anchor" id="providing-a-default-value-with-defaultifempty"></div>
<p><strong>The <em>defaultIfEmpty()</em> method provides a default value if the <em>Mono</em> is empty</strong>. This method is useful when we need a static fallback value rather than another <em>Mono</em> source. Again, we&#8217;ll test this with an empty <em>Mono</em> first:</p>
<pre><code class="language-kotlin">@Test
fun `should provide default value for empty Mono`() {
    val emptyMono = Mono.empty&lt;String&gt;()
    val resultMono = emptyMono.defaultIfEmpty("Default Value")
    StepVerifier.create(resultMono)
        .expectNext("Default Value")
        .verifyComplete()
}
</code></pre>
<p>We created an empty <em>Mono</em> again with <em>Mono.empty() </em>and verified that <em>resultMono</em> emits our &#8220;Default Value&#8221;.</p>
<p>Let&#8217;s see what happens when we try with a <em>Mono</em> that has a value:</p>
<pre><code class="language-kotlin">@Test
fun `should not override value for non-empty Mono`() {
    val nonEmptyMono = Mono.just("Actual Value")
    val resultMono = nonEmptyMono.defaultIfEmpty("Default Value")
    StepVerifier.create(resultMono)
        .expectNext("Actual Value")
        .verifyComplete()
}
</code></pre>
<p>Using <em>defaultIfEmpty()</em>, we can ensure that a predefined fallback value is only emitted when the <em>Mono</em> is empty.</p>
<h2 id="bd-providing-a-fallback-with-switchifempty" data-id="providing-a-fallback-with-switchifempty">5. Providing a Fallback with <em>switchIfEmpty()</em></h2>
<div class="bd-anchor" id="providing-a-fallback-with-switchifempty"></div>
<p>While <em>defaultIfEmpty()</em> is useful for providing static fallback values, <strong><em>switchIfEmpty()</em> is more powerful and allows us to provide another <em>Mono</em> as a fallback source</strong>. This can be useful when the fallback value needs to be dynamically generated or involves asynchronous computation.</p>
<p>Let&#8217;s start by looking at handling an empty <em>Mono</em> with <em>switchIfEmpty()</em>:</p>
<pre><code class="language-kotlin">@Test
fun `should provide fallback value for empty Mono`() {
    val emptyMono = Mono.empty&lt;String&gt;()
    val fallbackMono = emptyMono.switchIfEmpty(Mono.just("Fallback Value"))
    StepVerifier.create(fallbackMono)
        .expectNext("Fallback Value")
        .verifyComplete()
}
</code></pre>
<p>First, we create an empty <em>Mono</em> with <em>Mono.empty()</em>. <strong>The <em>switchIfEmpty()</em> method provides a fallback <em>Mono</em> that emits the string <em>&#8220;Fallback Value&#8221;</em></strong>. When the original <em>Mono</em> is empty, the fallback <em>Mono</em> is the source for the resulting stream.</p>
<p>Finally, let&#8217;s understand how <em>switchIfEmpty()</em> works with a <em>Mono</em> that has a value:</p>
<pre><code class="language-kotlin">@Test
fun `should not invoke fallback for non-empty Mono`() {
    val nonEmptyMono = Mono.just("Hello, World!")
    val resultMono = nonEmptyMono.switchIfEmpty(Mono.just("Fallback Value"))
    StepVerifier.create(resultMono)
        .expectNext("Hello, World!")
        .verifyComplete()
}
</code></pre>
<p>This time, our fallback value isn&#8217;t used, which is as we expected.</p>
<p>The <em>switchIfEmpty()</em> approach ensures that a meaningful default value is always available when the source <em>Mono</em> doesn&#8217;t emit data.</p>
<h2 id="bd-conclusion" data-id="conclusion">6. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>Handling empty <em>Mono</em>s is a key aspect of reactive programming. Since <em>Mono</em>s skip all mapping operations when empty, developers need explicit strategies to manage such cases. Methods like <em>defaultIfEmpty()</em> provide simple fallback values, while <em>switchIfEmpty()</em> enables more dynamic and reactive alternatives.</p>
<p>By mastering these techniques, we can design robust and efficient reactive flows that gracefully handle missing data.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/mono-empty-check">Check if Mono Is Empty With Kotlin</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/911563874/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/911563874/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-04-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/911563874/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/coroutine-continuation">Kotlin Coroutine Continuation</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flows-sequential-concatenation">Sequentially Concatenate 2 Kotlin Flows</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/generics-star-vs-any</feedburner:origLink>
		<title>Difference Between “*” and “Any” in Kotlin Generics</title>
		<link>https://feeds.feedblitz.com/~/910174880/0/baeldung/kotlin~Difference-Between-%e2%80%9c%e2%80%9d-and-%e2%80%9cAny%e2%80%9d-in-Kotlin-Generics</link>
					<comments>https://feeds.feedblitz.com/~/910174880/0/baeldung/kotlin~Difference-Between-%e2%80%9c%e2%80%9d-and-%e2%80%9cAny%e2%80%9d-in-Kotlin-Generics#comments</comments>
		
		<dc:creator><![CDATA[Sudi Mandyam]]></dc:creator>
		<pubDate>Mon, 30 Dec 2024 16:30:45 +0000</pubDate>
				<category><![CDATA[Kotlin Collections]]></category>
		<category><![CDATA[Generics]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/generics-star-vs-any</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Find out the differences between Any and * when using Kotlin generics and understand how to utilize them effectively.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/910174880/0/baeldung/kotlin~Difference-Between-%e2%80%9c%e2%80%9d-and-%e2%80%9cAny%e2%80%9d-in-Kotlin-Generics">Difference Between “*” and “Any” in Kotlin Generics</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910174880/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-08-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a rel="NOFOLLOW" title="View Comments" href="https://www.baeldung.com/kotlin/generics-star-vs-any#comments"><img height="20" style="border:0;margin:0;padding:0;" src="https://assets.feedblitz.com/i/comments20.png"></a>&#160;<a title="Follow Comments via RSS" href="https://www.baeldung.com/kotlin/generics-star-vs-any/feed"><img height="20" style="border:0;margin:0;padding:0;" src="https://assets.feedblitz.com/i/commentsrss20.png"></a>&nbsp;
<div style="clear:left;"><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/generics-star-vs-any#comments"><h3>Comments</h3></a><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/generics-star-vs-any#comment-198">I think nullability has nothing to do with ...</a> <i>by fantaman</i></ul></div><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-to-list">Create a List From Kotlin Flow</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/concurrent-modification-exception">Avoiding the ConcurrentModificationException in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/collections-parallel-operations">Parallel Operations on Kotlin Collections</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction"><b>1. Introduction</b></h2>
<div class="bd-anchor" id="introduction"></div>
<p>One of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/intro">Kotlin&#8217;s</a> most versatile abilities is that it allows us to express code syntax concisely yet powerfully to maximize developer productivity. It provides us with a powerful <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/generics#:~:text=As%20with%20Java%2C%20Kotlin's%20generics,see%20it%20as%20a%20Set.">generics</a> system for building reusable and type-safe code.</p>
<p><strong>By understanding <em>Any</em> and <em>*</em>, we can harness the full potential of Kotlin generics and write more robust and flexible code</strong>.</p>
<p>Let&#8217;s now examine their differences and understand how to utilize them effectively.</p>
<h2  data-id="define-our-use-case" id="bd-bd-define-our-use-case" data-id="bd-define-our-use-case">2. Define Use Case</h2>
<div class="bd-anchor" id="bd-define-our-use-case"></div>
<p data-sourcepos="3:1-3:122">Let&#8217;s imagine we&#8217;re building a treat dispenser for a Halloween haunted house. This dispenser needs to handle various types of treats:</p>
<ul data-sourcepos="5:1-8:0">
<li data-sourcepos="5:1-5:51">Candy<strong>:</strong> Chocolate bars, lollipops, etc.</li>
<li data-sourcepos="6:1-6:68">Spooky trinkets<strong>:</strong> Fake spiders, vampire fangs, etc.</li>
</ul>
<p data-sourcepos="9:1-9:163">Using separate containers for each treat type would be cumbersome and inefficient. Instead, let&#8217;s leverage generics to create a versatile <em>TreatDispenser&lt;T&gt;</em>:</p>
<pre><code class="language-kotlin">class TreatDispenser&lt;T&gt;(private val treats: MutableList&lt;T&gt; = mutableListOf()) {
    fun dispenseTreat(): T? {
        return if (treats.isNotEmpty()) treats.removeFirst() else null
    }
    fun peekNextTreat(): T? {
        return treats.firstOrNull()
    }
    fun addTreat(treat: T) {
        treats.add(treat)
    }
}</code></pre>
<p>With the above implementation, we now have the flexibility of creating dispensers for each category:</p>
<pre><code class="language-kotlin">val candyDispenser = TreatDispenser&lt;Candy&gt;()
val trinketDispenser = TreatDispenser&lt;SpookyTrinket&gt;()
</code></pre>
<p>The advantages of this approach are:</p>
<ul>
<li>Flexibility:<strong> </strong>A single <em>TreatDispenser </em>class manages all treat types</li>
<li>Type safety: The compiler prevents mixing different treats (no gummy bears in the potion dispenser!)</li>
<li>Extensibility: Adding new treat types is simple; we&#8217;ll create a new class and use it with the <em>TreatDispenser</em></li>
</ul>
<h2 data-sourcepos="1:1-1:62" id="bd-understanding-star-projections-" data-id="understanding-star-projections-">3. Understanding Star Projections (*)</h2>
<div class="bd-anchor" id="understanding-star-projections-"></div>
<p>While our <em>TreatDispenser&lt;T&gt;  </em>works wonders for managing specific treat types, let&#8217;s imagine a scenario where we need a function to inspect the next treat in any dispenser, regardless of its type. This is where star projections (<em>*</em>) come into play.</p>
<p><strong>A star projection (<em>*</em>) essentially represents an unknown type. It allows us to work with generic types without knowing the concrete type argument &#8211; it&#8217;s a wildcard that matches any type.</strong></p>
<p>Let&#8217;s introduce a function to peek at the next treat in any <em>TreatDispenser</em>:</p>
<pre><code class="language-kotlin">fun peekAtNextTreat(dispenser: TreatDispenser&lt;*&gt;) {
    val nextTreat = dispenser.peekNextTreat()
    println("The next treat is: $nextTreat")
}</code></pre>
<p>The above code has now given us the magical ability to peek into any type of <em>TreatDispenser</em>.</p>
<h2 data-sourcepos="1:1-1:62" id="bd-understanding-any" data-id="understanding-any">4. Understanding <em>Any</em></h2>
<div class="bd-anchor" id="understanding-any"></div>
<p>Although star projections offer great flexibility, they aren&#8217;t always the perfect solution.</p>
<p>Enter <em>Any</em>, the root of Kotlin&#8217;s type hierarchy. Unlike <em><strong>*</strong></em>, which represents an unknown type, <em>Any</em> specifically represents any non-nullable type. This distinction leads to some crucial differences.</p>
<p>Let&#8217;s revisit our <em>peekAtNextTreat()</em> function, but this time, we&#8217;ll try to use <em>Any</em> instead of <em>*</em>:</p>
<pre><code class="language-kotlin">fun peekAtNextTreatAny(dispenser: TreatDispenser&lt;Any&gt;) { 
    val nextTreat = dispenser.peekNextTreat()
    println("The next treat is: $nextTreat")
}</code></pre>
<p>Invoking the above function for our <em>candyDispenser</em> instance results in a type mismatch error:</p>
<pre><code class="language-kotlin">peekAtNextTreatAny(candyDispenser) // Error: Type mismatch</code></pre>
<p>This is because <em>candyDispenser</em> is of type <em>TreatDispenser&lt;Candy&gt;</em>, and <em>Candy</em> isn&#8217;t <em>Any</em>. Even though <em>Candy</em> inherits from <em>Any</em>, the compiler enforces strict type matching when using <em>Any</em> in generics.</p>
<p><strong>This highlights a key difference: <em>Any</em> is restrictive and only accepts non-nullable types. Hence, this function call would fail if our <em>Candy</em> class allowed null values (<em>Candy?</em>).</strong></p>
<h2 id="bd-comparison-summary" data-id="comparison-summary"><b>5. Comparison Summary</b></h2>
<div class="bd-anchor" id="comparison-summary"></div>
<p><strong>In the below table, let&#8217;s summarize the usage of <em>Any</em> vs. <em>*</em> as per various criteria:</strong></p>
<table class="table-styled">
<thead>
<tr>
<th style="width: 25.5758%"><strong>Criteria</strong></th>
<th style="width: 41.0909%"><strong>Use </strong><em><strong>Any?</strong></em></th>
<th style="width: 33.3333%">Use <i>*?</i></th>
</tr>
<tr style="height: 24px">
<td style="width: 25.5758%;height: 24px;text-align: center">Is our type known and Non-Nullable?</td>
<td style="width: 41.0909%;height: 24px;text-align: center">Yes</td>
<td style="width: 33.3333%;height: 24px;text-align: center">No</td>
</tr>
<tr>
<td style="width: 25.5758%;text-align: center">Is our type unknown or potentially nullable?</td>
<td style="width: 41.0909%;text-align: center">No</td>
<td style="width: 33.3333%;text-align: center">Yes</td>
</tr>
<tr>
<td style="width: 25.5758%;text-align: center">Are we performing read-only operations on a generic type?</td>
<td style="width: 41.0909%;text-align: center">No</td>
<td style="width: 33.3333%;text-align: center">Yes</td>
</tr>
</thead>
</table>
<h2 id="bd-conclusion" data-id="conclusion"><b>6. Conclusion</b></h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In essence, <em>Any</em> represents any non-nullable type, allowing for flexibility but potentially sacrificing type safety. Star projections (<em>*</em>), on the other hand, represent an unknown type, offering greater type safety but limiting flexibility.</p>
<p><strong>To summarise, we must always choose between <em>Any</em> and <em>*</em> projections in Kotlin depending on our specific needs. Let&#8217;s remember that selecting the right tool ensures our code&#8217;s effectiveness.</strong></p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/generics-star-vs-any">Difference Between “*” and “Any” in Kotlin Generics</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/910174880/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910174880/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-08-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910174880/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a rel="NOFOLLOW" title="View Comments" href="https://www.baeldung.com/kotlin/generics-star-vs-any#comments"><img height="20" style="border:0;margin:0;padding:0;" src="https://assets.feedblitz.com/i/comments20.png"></a>&#160;<a title="Follow Comments via RSS" href="https://www.baeldung.com/kotlin/generics-star-vs-any/feed"><img height="20" style="border:0;margin:0;padding:0;" src="https://assets.feedblitz.com/i/commentsrss20.png"></a>&nbsp;
<div style="clear:left;"><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/generics-star-vs-any#comments"><h3>Comments</h3></a><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/generics-star-vs-any#comment-198">I think nullability has nothing to do with ...</a> <i>by fantaman</i></ul></div><h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-to-list">Create a List From Kotlin Flow</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/concurrent-modification-exception">Avoiding the ConcurrentModificationException in Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/collections-parallel-operations">Parallel Operations on Kotlin Collections</a></li></ul>&#160;</div>]]>
</content:encoded>
					
					<wfw:commentRss>https://feeds.feedblitz.com/~/910174880/0/baeldung/kotlin~Difference-Between-%e2%80%9c%e2%80%9d-and-%e2%80%9cAny%e2%80%9d-in-Kotlin-Generics/feed</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-08-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/redis-messaging</feedburner:origLink>
		<title>PubSub Messaging With Kotlin Redis</title>
		<link>https://feeds.feedblitz.com/~/910111523/0/baeldung/kotlin~PubSub-Messaging-With-Kotlin-Redis</link>
		
		<dc:creator><![CDATA[Abhinav Pandey]]></dc:creator>
		<pubDate>Sun, 29 Dec 2024 09:39:47 +0000</pubDate>
				<category><![CDATA[Libraries]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/redis-messaging</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>A quick tutorial on messaging with Redis in Kotlin.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/910111523/0/baeldung/kotlin~PubSub-Messaging-With-Kotlin-Redis">PubSub Messaging With Kotlin Redis</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910111523/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-04-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/apache-log4j-introduction">Introduction to Apache Log4j Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/gradle-exclude-library-all-dependencies">Excluding a Library from All Dependencies in Kotlin DSL in Gradle</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/kandy">Plotting Charts in Kotlin With Kandy</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2  id="bd-1-overview" data-id="1-overview">1. Overview</h2>
<div class="bd-anchor" id="1-overview"></div>
<p>Publish-subscribe (PubSub) is a messaging pattern in which publishers send messages to a channel and subscribers listen to messages on that channel. Redis is a popular in-memory data store that also supports messaging.</p>
<p>In this tutorial, we&#8217;ll explore implementing a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/spring-data-redis-pub-sub">publish-subscribe</a> messaging system using Kotlin and Redis. To do this, we&#8217;ll build a small application in which a publisher sends messages to a Redis channel and a subscriber listens to messages on that channel.</p>
<h2  id="bd-2-code-setup" data-id="2-code-setup">2. Code Setup</h2>
<div class="bd-anchor" id="2-code-setup"></div>
<p>Let&#8217;s start by setting up our Kotlin project and adding the building blocks for our messaging system.</p>
<h3  id="bd-21-dependencies" data-id="21-dependencies">2.1. Dependencies</h3>
<div class="bd-anchor" id="21-dependencies"></div>
<p>We&#8217;ll use the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://mvnrepository.com/artifact/io.lettuce/lettuce-core"><em>lettuce-core</em></a> library to interact with Redis in our Kotlin application:<img class="code-fence-highlighter-copy-button-icon" /></p>
<pre class="code-fence"><code class="language-xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;io.lettuce.core&lt;/groupId&gt;
        &lt;artifactId&gt;lettuce-core&lt;/artifactId&gt;
        &lt;version&gt;6.5.0.RELEASE&lt;/version&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;
</code></pre>
<p>Additionally, we&#8217;ll use an <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://mvnrepository.com/artifact/com.github.codemonstur/embedded-redis">embedded Redis server</a> for testing purposes to avoid using an external Redis server:</p>
<pre><code class="language-xml">&lt;dependency&gt; 
    &lt;groupId&gt;com.github.kstyrc&lt;/groupId&gt; 
    &lt;artifactId&gt;embedded-redis&lt;/artifactId&gt; 
    &lt;version&gt;1.4.3&lt;/version&gt; 
&lt;/dependency&gt;</code></pre>
<h3  id="bd-22-connecting-to-redis" data-id="22-connecting-to-redis">2.2. Connecting to Redis</h3>
<div class="bd-anchor" id="22-connecting-to-redis"></div>
<p>Next, we&#8217;ll create a Redis connection using <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/java-redis-lettuce">Lettuce</a>:</p>
<pre class="code-fence"><code class="language-kotlin">object RedisConnectionManager: AutoCloseable {
    private val redisClient: RedisClient = RedisClient.create("redis://localhost:6379")
    private val connection: StatefulRedisConnection&lt;String, String&gt; = redisClient.connect()
    override fun close() {
        connection.close()
        redisClient.shutdown()
    }
}
</code></pre>
<p>We create a singleton object <em>RedisConnectionManager</em> that manages the Redis connection. In this class, we instantiate a <em>RedisClient</em> instance using the <em>create()</em> method and then <em>connect()</em> to the embedded Redis server.</p>
<p>Additionally, we define a <em>close()</em> method to close the connection. <strong>If not called explicitly, the connection closes when the object is garbage collected as we implement the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/try-with-resources#closeable"><em>AutoCloseable</em></a> interface</strong>.</p>
<h3 id="bd-3-sync-and-async-commands" data-id="3-sync-and-async-commands">2.3. Sync and Async Commands</h3>
<div class="bd-anchor" id="3-sync-and-async-commands"></div>
<p>Additionally, let&#8217;s define methods to expose Redis&#8217; <em>sync()</em> and <em>async()</em> commands. Specifically, we&#8217;ll use the sync methods to publish messages to Redis. Conversely, async commands are required to create a subscriber and listen to a channel.</p>
<p>First, we&#8217;ll manage the sync commands:</p>
<pre><code class="language-java">fun redisSyncCommands(): RedisCommands&lt;String, String&gt;? {
    return connection.sync()
}</code></pre>
<p>Significantly, the <em>redisSyncCommands() </em>method gets the synchronous operations from the connection and returns an object encapsulating them.</p>
<p>Next, we&#8217;ll look at the async commands:</p>
<pre><code class="language-java">fun redisPubSubAsyncCommands(messageListener: MessageListener): RedisPubSubAsyncCommands&lt;String, String&gt; {
    val pubSubConnection = redisClient.connectPubSub()
    pubSubConnection.addListener(messageListener)
    return pubSubConnection.async()
}</code></pre>
<p>The <em>redisPubSubAsyncCommands() </em>method creates a pub-sub connection to the server, adds a listener, and finally returns the async commands for the connection.</p>
<h3  id="bd-23-message-dto" data-id="23-message-dto">2.4. Message DTO</h3>
<div class="bd-anchor" id="23-message-dto"></div>
<p>To represent our message, let&#8217;s define a simple data class. This class holds the message content:</p>
<pre class="code-fence"><code class="language-kotlin">data class Message(val content: String)
</code></pre>
<p>Here, we define a <em>Message</em> data class with a single <em>content</em> property. This class encapsulates the messages that we&#8217;ll send through Redis.</p>
<h2  id="bd-3-consumer" data-id="3-consumer">3. Consumer</h2>
<div class="bd-anchor" id="3-consumer"></div>
<p>Now we can create a consumer that listens to messages on a specific channel. This requires a subscription to the channel and a listener to handle incoming messages.</p>
<h3  id="bd-31-listener" data-id="31-listener">3.1. Listener</h3>
<div class="bd-anchor" id="31-listener"></div>
<p>First, let&#8217;s create a class that handles incoming messages. One of the simplest ways to achieve this is by extending the <em>RedisPubSubAdapter</em> class provided by Lettuce. It&#8217;s an abstract class that implements the <em>RedisMessageListener</em> interface:<img class="code-fence-highlighter-copy-button-icon" /></p>
<pre class="code-fence"><code class="language-kotlin">class MessageListener : RedisPubSubAdapter&lt;String, String&gt;() {
    var latch: CountDownLatch = CountDownLatch(1)
    var messagesReceived: List&lt;String&gt; = emptyList()
    override fun message(channel: String?, message: String?) {
        println("Received message: $message from channel: $channel")
        messagesReceived = messagesReceived.plus(message!!)
        latch.countDown()
    }
}
</code></pre>
<p>The <em>message()</em> method is called whenever a message is received on the subscribed channel. In this method, we log the received message and the channel name.</p>
<p>For testing purposes, we also use a <em>CountDownLatch</em> to wait for messages. We&#8217;ll store any messages received by the listener in <em>messagesReceived </em>so that we can verify them later.</p>
<h3  id="bd-32-subscribing-to-a-channel" data-id="32-subscribing-to-a-channel">3.2. Subscribing to a Channel</h3>
<div class="bd-anchor" id="32-subscribing-to-a-channel"></div>
<p>Furthermore, we need to connect our listener to a Redis channel. For this, we&#8217;ll also create a subscriber that subscribes to a specific channel and listens for messages.</p>
<p>Let&#8217;s create a method to subscribe to a channel:<img class="code-fence-highlighter-copy-button-icon" /></p>
<pre><code class="language-java">class RedisSubscriber(private val messageListener: MessageListener) {
    fun subscribeToChannel(channel: String) {
        RedisConnectionManager.redisPubSubAsyncCommands(messageListener).subscribe(channel)
    }
}</code></pre>
<p>Here are a few key points about the <em>RedisSubscriber</em> class:</p>
<ul>
<li>It takes a <em>MessageListener</em> instance as a parameter in the constructor.</li>
<li>The <em>subscribeToChannel()</em> method calls the <em>redisPubSubAsyncCommands()</em> to create a pub-sub connection.</li>
<li>The connection will also add the <em>MessageListener </em>to the specified channel.</li>
<li>We then subscribe to the specified channel using the <em>subscribe()</em> method.</li>
</ul>
<p>When a message is received on the channel, the <em>message()</em> method of the <em>MessageListener</em> class is called, and the message content is logged.</p>
<div>
<p><strong>It&#8217;s important to note that Redis doesn&#8217;t guarantee message delivery. If the subscriber isn&#8217;t listening when the publisher publishes, it won&#8217;t receive the message</strong>.</p>
</div>
<h2  id="bd-4-publisher" data-id="4-publisher">4. Publisher</h2>
<div class="bd-anchor" id="4-publisher"></div>
<p>Now that we have a consumer listening to messages, let&#8217;s create a publisher that sends messages to a Redis channel.</p>
<p>We&#8217;ll create a method that publishes a message to a specific channel:</p>
<pre><code class="language-java">class RedisPublisher {
    fun publishMessage(channel: String, message: Message) {
        RedisConnectionManager.redisCommands()?.publish(channel, message.content)
        println("Message published: $message")
    }
}</code></pre>
<p>This method takes a channel name and a <em>Message</em> object as parameters. Using the commands from the <em>RedisConnectionManager</em>, it publishes the message content to the specified channel using the <em>publish()</em> method.</p>
<h2  id="bd-5-testing" data-id="5-testing">5. Testing</h2>
<div class="bd-anchor" id="5-testing"></div>
<p>To test our messaging system, we&#8217;ll write a test case that publishes a message to a channel and verifies that the consumer receives the message.</p>
<h3  id="bd-51-test-class" data-id="51-test-class">5.1. Test Class</h3>
<div class="bd-anchor" id="51-test-class"></div>
<p>To start, let&#8217;s create a test class and set up our connection:<img class="code-fence-highlighter-copy-button-icon" /></p>
<pre class="code-fence"><code class="language-kotlin">@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class RedisSubscriberUnitTest {
    val messageListener = MessageListener()
    val redisSubscriber = RedisSubscriber(messageListener)
    val redisPublisher = RedisPublisher()
    val channel = "channel"
    val message = Message("Hello, Redis!")
    val redisServer = RedisServer(6379)
    @BeforeAll
    fun setUp() {
        redisServer.start()
    }
    @AfterAll
    fun tearDown() {
        RedisConnectionManager.close()
        redisServer.stop()
    }
}</code></pre>
<p>In the <em>setUp()</em> method, we start an embedded Redis server using the <em>RedisServer</em> class of the <em>embedded-redis</em> library. Similarly, in the <em>tearDown()</em> method, we close the Redis connection and stop the embedded Redis server.</p>
<h3  id="bd-52-test-case" data-id="52-test-case">5.2. Test Case</h3>
<div class="bd-anchor" id="52-test-case"></div>
<p>Now, let&#8217;s write a test case that publishes a message to a channel and verifies that the consumer receives the message:</p>
<pre class="code-fence"><code class="language-kotlin">@Test
fun givenMessageListener_whenMessagePublished_thenMessageReceived() {
    redisSubscriber.subscribeToChannel(channel)
    redisPublisher.publishMessage(channel, message)
    messageListener.latch.await(500, TimeUnit.MILLISECONDS)
    assertEquals(message.content, messageListener.messagesReceived.get(0))
}
</code></pre>
<p><strong>First, we subscribe to the channel using the <em>RedisSubscriber</em> instance, or we&#8217;ll miss the published message</strong>. Then, we publish a message to the channel using the <em>RedisPublisher</em> instance.</p>
<p>The latch in the <em>MessageListener</em> class waits for the message to be received.</p>
<p>Finally, we assert that the message the listener receives is the same as the message published.</p>
<h2  id="bd-6-conclusion" data-id="6-conclusion">6. Conclusion</h2>
<div class="bd-anchor" id="6-conclusion"></div>
<p>In this article, we explored implementing a publish-subscribe messaging system using Kotlin and Redis. We set up a Redis connection, created a consumer to listen to messages on a channel, and finally a publisher to send messages to the channel. We also tested our system by publishing and consuming messages.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/redis-messaging">PubSub Messaging With Kotlin Redis</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/910111523/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910111523/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-04-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910111523/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/apache-log4j-introduction">Introduction to Apache Log4j Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/gradle-exclude-library-all-dependencies">Excluding a Library from All Dependencies in Kotlin DSL in Gradle</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/kandy">Plotting Charts in Kotlin With Kandy</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-04-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/gradle-exclude-library-all-dependencies</feedburner:origLink>
		<title>Excluding a Library from All Dependencies in Kotlin DSL in Gradle</title>
		<link>https://feeds.feedblitz.com/~/910111526/0/baeldung/kotlin~Excluding-a-Library-from-All-Dependencies-in-Kotlin-DSL-in-Gradle</link>
		
		<dc:creator><![CDATA[Leonardo Colman Lopes]]></dc:creator>
		<pubDate>Sun, 29 Dec 2024 09:35:58 +0000</pubDate>
				<category><![CDATA[Libraries]]></category>
		<category><![CDATA[Gradle]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/?p=56379</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn how to exclude a library or a transitive dependency using the Kotlin DSL syntax in a Gradle.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/910111526/0/baeldung/kotlin~Excluding-a-Library-from-All-Dependencies-in-Kotlin-DSL-in-Gradle">Excluding a Library from All Dependencies in Kotlin DSL in Gradle</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910111526/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-06-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/gradle-library">Building a Kotlin Library Using Gradle</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/apache-log4j-introduction">Introduction to Apache Log4j Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/redis-messaging">PubSub Messaging With Kotlin Redis</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p>When working on a Kotlin project with Gradle, there are scenarios where we need to exclude certain libraries or transitive dependencies to avoid conflicts or reduce the size of our final build. Gradle provides mechanisms to exclude libraries globally across all dependencies.</p>
<p>In this tutorial, we’ll explore how to exclude a library or a transitive dependency using the Kotlin DSL syntax in a Gradle build script.</p>
<h2 id="bd-understanding-the-problem" data-id="understanding-the-problem">2. Understanding the Problem</h2>
<div class="bd-anchor" id="understanding-the-problem"></div>
<p>Dependencies in a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/gradle">Gradle</a> project often include other libraries as transitive dependencies. However, there are several reasons why we might need to exclude specific libraries:</p>
<ul>
<li><strong>Version Conflicts</strong>: Different dependencies may include varying versions of the same library, causing compatibility issues or runtime errors. For example, if two libraries bring in different versions of <em>commons-logging</em>, we might face runtime inconsistencies.</li>
<li><strong>Optimizing Build Size</strong>: Unused libraries can add unnecessary weight to the final build. Excluding these unwanted transitive dependencies helps reduce the overall size of the project output.</li>
<li><strong>Replacing Default Libraries</strong>: Sometimes, we need to replace a default dependency with an alternative. For instance, certain <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/spring-boot-logging">Spring Boot</a> starters include <em>commons-logging</em> by default, but we might prefer to use <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/slf4j-with-log4j2-logback"><em>slf4j</em></a> instead. By excluding the unwanted library, we can include the replacement explicitly.</li>
</ul>
<p>By understanding these common scenarios, we can effectively manage the dependency graph and ensure only the required libraries are included in the build.</p>
<h2 id="bd-excluding-a-library-in-kotlin-dsl" data-id="excluding-a-library-in-kotlin-dsl">3. Excluding a Library in Kotlin DSL</h2>
<div class="bd-anchor" id="excluding-a-library-in-kotlin-dsl"></div>
<p>Gradle provides flexible ways to exclude unwanted libraries or transitive dependencies in a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/gradle-dsl">Kotlin DSL build script</a>. <strong>We can achieve this either globally, across all dependencies, or at a more granular level for specific dependencies.</strong> The exclusion mechanisms leverage the <em>configurations</em> and <em>dependencies</em> blocks, allowing us to control the dependency graph precisely.</p>
<p>In the following sections, we’ll explore how to exclude libraries globally or for individual dependencies using the Kotlin DSL syntax.</p>
<h3 id="bd-1-exclude-a-library-globally" data-id="1-exclude-a-library-globally">3.1. Exclude a Library Globally</h3>
<div class="bd-anchor" id="1-exclude-a-library-globally"></div>
<p><strong>To exclude a library or transitive dependency globally across all dependencies, we use the <em>configurations</em> block in our <em>build.gradle.kts</em> file</strong>:</p>
<pre><code class="language-kotlin">configurations.all {
    exclude(group = "org.apache.commons", module = "commons-logging")
}</code></pre>
<p>In this example, the <em>exclude</em> function specifies the group and module of the dependency we want to remove. The <em>group</em> refers to the group ID, and the <em>module</em> refers to the artifact ID of the library.</p>
<h3 id="bd-2-excluding-a-library-from-specific-dependencies" data-id="2-excluding-a-library-from-specific-dependencies">3.2. Excluding a Library from Specific Dependencies</h3>
<div class="bd-anchor" id="2-excluding-a-library-from-specific-dependencies"></div>
<p><strong>If we only want to exclude a library from a particular dependency instead of applying it globally, we use the dependencies block with an inline exclude function</strong>:</p>
<pre><code class="language-kotlin">dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web") {
        exclude(group = "org.apache.commons", module = "commons-logging")
    }
}
</code></pre>
<p>In this example, the <em>spring-boot-starter-web</em> dependency includes <em>commons-logging</em> as a transitive dependency. By adding the <em>exclude</em> block, we remove <em>commons-logging</em> specifically for this dependency while leaving other dependencies unaffected.</p>
<h3 id="bd-3-excluding-multiple-libraries" data-id="3-excluding-multiple-libraries">3.3. Excluding Multiple Libraries</h3>
<div class="bd-anchor" id="3-excluding-multiple-libraries"></div>
<p><strong>To exclude multiple libraries, we can add multiple <em>exclude</em> statements inside the <em>configurations</em> block</strong>:</p>
<pre><code class="language-kotlin">configurations.all {
    exclude(group = "org.apache.commons", module = "commons-logging")
    exclude(group = "ch.qos.logback", module = "logback-classic")
}
</code></pre>
<p>Alternatively, for better readability and maintainability, we can define a list of exclusions and loop over them:</p>
<pre><code class="language-kotlin">val exclusions = listOf(
    "org.apache.commons" to "commons-logging",
    "ch.qos.logback" to "logback-classic"
)
configurations.all {
    exclusions.forEach { (group, module) -&gt;
        exclude(group = group, module = module)
    }
}
</code></pre>
<p>This approach is particularly useful when dealing with a large number of exclusions, as it keeps the code clean and easier to maintain.</p>
<h2 id="bd-verifying-exclusions" data-id="verifying-exclusions">4. Verifying Exclusions</h2>
<div class="bd-anchor" id="verifying-exclusions"></div>
<p>To verify that exclusions are applied, we can use Gradle’s dependency insight task:</p>
<pre><code class="language-kotlin">./gradlew dependencies --configuration implementation
</code></pre>
<p>This will display the resolved dependency graph, helping us confirm that the unwanted libraries are excluded.</p>
<h2 id="bd-conclusion" data-id="conclusion">5. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we explored how to exclude a library or transitive dependency in Gradle using Kotlin DSL. Whether globally or for a specific dependency, Gradle provides flexible options to manage exclusions effectively.</p>
<p>By carefully applying exclusions, we can resolve dependency conflicts, optimize our build, and ensure compatibility with desired libraries.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/gradle-exclude-library-all-dependencies">Excluding a Library from All Dependencies in Kotlin DSL in Gradle</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/910111526/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910111526/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-06-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910111526/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/gradle-library">Building a Kotlin Library Using Gradle</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/apache-log4j-introduction">Introduction to Apache Log4j Kotlin</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/redis-messaging">PubSub Messaging With Kotlin Redis</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-06-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/kotlin/retrofit-coroutines-download-pdf</feedburner:origLink>
		<title>Download PDF Files with Retrofit and Coroutines</title>
		<link>https://feeds.feedblitz.com/~/909800285/0/baeldung/kotlin~Download-PDF-Files-with-Retrofit-and-Coroutines</link>
		
		<dc:creator><![CDATA[Diego Torres]]></dc:creator>
		<pubDate>Sun, 22 Dec 2024 02:56:13 +0000</pubDate>
				<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[Coroutines]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/kotlin/retrofit-coroutines-download-pdf</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Explore an efficient approach to downloading PDF files using Retrofit and the support of Kotlin Coroutines.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/909800285/0/baeldung/kotlin~Download-PDF-Files-with-Retrofit-and-Coroutines">Download PDF Files with Retrofit and Coroutines</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/909800285/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-07-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-catch-operator">Kotlin Flow catch() Operator</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/function-reference-ambiguity">Removing Ambiguity in Kotlin Function by Reference</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/format-number-thousand-separator">Format Number With Thousand Separator in Kotlin</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-600x314.jpg 600w, https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-overview" data-id="overview">1. Overview</h2>
<div class="bd-anchor" id="overview"></div>
<p>When working with documents stored in the cloud, we sometimes need to download them to perform additional processing. <strong>The process of downloading can be automated with a program that can take the URL as a parameter to get these documents</strong> and store them later in the file system of our choice.</p>
<p>In this tutorial, we&#8217;ll see how to download PDF files with Kotlin using Coroutines and the Retrofit library.</p>
<h2 id="bd-implementation" data-id="implementation">2. Implementation</h2>
<div class="bd-anchor" id="implementation"></div>
<p>Using <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/retrofit"><em>Retrofit </em></a>and <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/coroutines"><em>Kotlin</em> <em>Coroutines</em></a> is an efficient approach when we want to perform HTTP requests to get resources stored in the cloud. In the next flowchart, we can see the process we&#8217;ll apply:</p>
<img decoding="async" class="alignnone size-full wp-image-64713" src="https://www.baeldung.com/wp-content/uploads/sites/5/2024/12/coroutine-diagram.png" alt="PDF Download Process" />
<p>Let&#8217;s start defining the first component of the process.</p>
<h2 id="bd-retrofit-service-interface" data-id="retrofit-service-interface">3. Retrofit Service Interface</h2>
<div class="bd-anchor" id="retrofit-service-interface"></div>
<p>First, we need to define a service interface for <em>Retrofit</em> that will expose a function for downloading files:</p>
<pre><code class="language-kotlin">interface FileDownloadService {
    @GET
    suspend fun downloadFile(@Url fileUrl: String): ResponseBody
}</code></pre>
<p>The <em>@GET</em> annotation specifies the HTTP method we want to execute, and the <em>@Url</em> parameter allows us to dynamically pass the URL of the file we need to download.</p>
<h2 id="bd-retrofit-instance" data-id="retrofit-instance">4. Retrofit Instance</h2>
<div class="bd-anchor" id="retrofit-instance"></div>
<p>Now we need to create and setup the Retrofit instance to perform the HTTP requests:</p>
<pre><code class="language-kotlin">val retrofit = Retrofit.Builder()
  .baseUrl("https://example.com/")
  .build()
val service = retrofit.create(FileDownloadService::class.java)</code></pre>
<p>Since we&#8217;ll pass the <em>@Url</em> parameter dynamically, the baseUrl will not be used in the request. However, <strong>this is a required parameter in <em>Retrofit</em> configuration and for that reason, we need to define a valid URL as a placeholder</strong>.</p>
<h2 id="bd-download-the-pdf" data-id="download-the-pdf">5. Download the PDF</h2>
<div class="bd-anchor" id="download-the-pdf"></div>
<p><strong>Now that our <em>Retrofit</em> service is ready, we can execute the download process in a suspend function</strong>. We need the <em>Dispatchers.IO</em> to ensure that the operation runs on a separate thread:</p>
<pre><code class="language-kotlin">suspend fun downloadPdfWithRetrofit(url: String, outputFile: File) {
    // retrofit service setup
    withContext(Dispatchers.IO) {
        val responseBody = service.downloadFile(url)
        // Save the file to disk
        responseBody.byteStream().use { inputStream -&gt;
            FileOutputStream(outputFile).use { outputStream -&gt;
                inputStream.copyTo(outputStream)
            }
        }
        println("File downloaded successfully to ${outputFile.absolutePath}")
    }
}</code></pre>
<h2 id="bd-execute-the-coroutine" data-id="execute-the-coroutine">6. Execute the Coroutine</h2>
<div class="bd-anchor" id="execute-the-coroutine"></div>
<p>Now we can execute our function in a runBlocking block. <strong>This block provides the support to run coroutines functions synchronously</strong>. In the next example, we can see how to pass the URL parameter to the function and download the PDF file:</p>
<pre><code class="language-kotlin">fun main() {
    val url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
    val outputFile = File("sample.pdf")
    runBlocking {
        try {
            downloadPdfWithRetrofit(url, outputFile)
        } catch (e: Exception) {
            println("Failed to download PDF: ${e.message}")
        }
    }
}</code></pre>
<h2 id="bd-conclusion" data-id="conclusion">7. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this tutorial, we&#8217;ve explored an efficient approach to downloading PDF files using <em>Retrofit</em> and the support of <em>Kotlin</em> Coroutines.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin/retrofit-coroutines-download-pdf">Download PDF Files with Retrofit and Coroutines</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/kotlin/~https://www.baeldung.com/kotlin">Baeldung on Kotlin</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/909800285/0/baeldung/kotlin">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/909800285/baeldung/kotlin,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f5%2f2024%2f11%2fKotlin-Featured-Image-07-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/909800285/baeldung/kotlin"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/flow-catch-operator">Kotlin Flow catch() Operator</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/function-reference-ambiguity">Removing Ambiguity in Kotlin Function by Reference</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/kotlin/format-number-thousand-separator">Format Number With Thousand Separator in Kotlin</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/5/2024/11/Kotlin-Featured-Image-07-150x150.jpg</webfeeds:featuredImage></item>
</channel></rss>

