<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dylan</title>
    <description>The latest articles on DEV Community by Dylan (@dylanfw).</description>
    <link>https://dev.to/dylanfw</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F803521%2F87864ba7-b2ae-42ba-b645-60f8423cb8fa.jpeg</url>
      <title>DEV Community: Dylan</title>
      <link>https://dev.to/dylanfw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dylanfw"/>
    <language>en</language>
    <item>
      <title>From Python to Java: Using JShell</title>
      <dc:creator>Dylan</dc:creator>
      <pubDate>Fri, 15 Apr 2022 16:15:02 +0000</pubDate>
      <link>https://dev.to/dylanfw/from-python-to-java-using-jshell-3j6p</link>
      <guid>https://dev.to/dylanfw/from-python-to-java-using-jshell-3j6p</guid>
      <description>&lt;p&gt;For most of my career, I've worked primarily as a Python developer. There were occasional trips into the frontend for some JavaScript or a brief detour through a Go application, but the vast majority of my work was solidly Python.&lt;/p&gt;

&lt;p&gt;That is, until I joined Square. Square might be better known for its Ruby code, but there is also a sizable chunk of Java within its codebase. So when I came to Square, I knew I'd be putting away my list comprehensions, generators, and &lt;code&gt;@decorators&lt;/code&gt;, and instead I'd be learning some new programming language patterns and idioms.&lt;/p&gt;

&lt;p&gt;But of course, my Python experience would not be for nothing. As it turns out, we can find parallel ideas throughout most programming languages. In this series, I'll be highlighting some of these parallels I've encountered switching from Python to Java in hopes that it might help someone else who also finds themselves crossing this language barrier!&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;One of the first pain points that a Python developer is going to encounter when picking up Java is the lack of an interpreter. When writing in Python, I would frequently want to "test drive" a short snippet of code. In those moments, I'd pop open a terminal, run &lt;code&gt;python3&lt;/code&gt;, and try out my code. This made it easy to make slight adjustments and see the results instantaneously before settling on a solution. If I needed to call an existing function in my codebase, it was a simple &lt;code&gt;import myModule&lt;/code&gt; away and suddenly I was interacting with my code in new ways.&lt;/p&gt;

&lt;p&gt;Since Java is a compiled language, we can't enjoy this on-the-fly exploratory interaction with our code. We have to wrap our snippets in a big, ugly &lt;code&gt;public static void main(String[] args)&lt;/code&gt; method within a class and then &lt;em&gt;wait for it to compile&lt;/em&gt; just to see that we actually wanted to write it differently. What if I told you there was a better way?&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter JShell
&lt;/h2&gt;

&lt;p&gt;No, really. Enter &lt;code&gt;jshell&lt;/code&gt; in your terminal. Assuming you have JDK 9+ installed, you should be greeted with the following.&lt;sup id="fnref1"&gt;1&lt;/sup&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|  Welcome to JShell -- Version 17.0.2
|  For an introduction type: /help intro

jshell&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JShell was introduced in Java 9 but is still massively underappreciated, so it's understandable if you haven't heard of it until now. JShell is a REPL&lt;sup id="fnref2"&gt;2&lt;/sup&gt; for Java code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Starting to Explore
&lt;/h2&gt;

&lt;p&gt;Imagine you've just read about the Streams API&lt;sup id="fnref3"&gt;3&lt;/sup&gt; and you want to explore it for yourself before using it in your code. Within JShell, type the following and hit enter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Adam"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Charles"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's practice consuming the stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
     &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
     &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! You should see the output immediately just like we'd expect when using the Python interpreter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Play it back
&lt;/h2&gt;

&lt;p&gt;Let's try consuming our stream again within the same session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
     &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
     &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;IllegalStateException: stream has already been operated upon or closed&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Looks like streams can only be used once! Rather than re-declaring our initial Stream object, let's take advantage of another JShell feature. Type &lt;code&gt;/list&lt;/code&gt; to view a numbered list of every statement we've written in this session. Number 1 should be our &lt;code&gt;names&lt;/code&gt; initialization. Let's re-execute that statement! Type &lt;code&gt;/1&lt;/code&gt; to rerun the variable initialization. Once the Stream has been reinstated, we can type &lt;code&gt;/3&lt;/code&gt; to rerun our last snippet!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;

   &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Adam"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Charles"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
   &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toUpperCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
   &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;

&lt;span class="n"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Adam"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Charles"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;util&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ReferencePipeline&lt;/span&gt;&lt;span class="n"&gt;$Head&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;b05039f&lt;/span&gt;

&lt;span class="n"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;toLowerCase&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;alice&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;adam&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interacting with other libraries
&lt;/h2&gt;

&lt;p&gt;Sometimes you need more context. Maybe you want to test out a snippet of code that calls a method of one of your classes or that uses some third-party library. In Python we could simply &lt;code&gt;import myModule&lt;/code&gt; to pull our code into the REPL session, or we could start the session already in context with the &lt;code&gt;-m&lt;/code&gt; flag, &lt;code&gt;python3 -m myModule&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;With JShell the process isn't much different. The only distinction is that our application (or any other dependencies we're trying to work with) must first be added to our class path before we can import them.&lt;/p&gt;

&lt;p&gt;Say we'd like to explore the &lt;a href="https://commons.apache.org/proper/commons-lang/"&gt;Apache Commons Lang&lt;/a&gt; library and we've already downloaded its &lt;code&gt;commons-lang3-3.12.0.jar&lt;/code&gt; somewhere on our computer. In order to import its packages within our JShell session, we have two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We can start the session with the library already loaded:&lt;br&gt;
&lt;code&gt;jshell --class-path /path/to/commons-lang3-3.12.0.jar&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After starting a new JShell session, we can add it to our environment:&lt;br&gt;
&lt;code&gt;/env -class-path /path/to/commons-lang3-3.12.0.jar&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once loaded into our JShell environment, we can import its packages and try it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="nc"&gt;path&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;commons&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;lang3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;3.12&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jar&lt;/span&gt;

&lt;span class="n"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.commons.lang3.StringUtils&lt;/span&gt;

&lt;span class="n"&gt;jshell&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;StringUtils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isBlank&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"  "&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interacting with your own application code follows the same process once you've built your own &lt;code&gt;.jar&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Tip: Loading in an application's &lt;code&gt;.jar&lt;/code&gt; and using its methods within a JShell session can make debugging issues in other environments like staging or production much easier - so long as you exercise the proper caution!&lt;/p&gt;

&lt;h2&gt;
  
  
  Java script?
&lt;/h2&gt;

&lt;p&gt;One last feature I'd like to call out with JShell is the ability to create Java scripts. No, not Javascript. Java scripts. Essentially, JShell can read its commands from a file rather than from the terminal prompt. For example, save the following as &lt;code&gt;helloWorld.jsh&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello world!"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then run it via &lt;code&gt;jshell helloWorld.jsh&lt;/code&gt;. You probably shouldn't write all of your scripts in Java now, but it's nice to have the option! &lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;Want to learn more about JShell?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Within JShell, run &lt;code&gt;/help intro&lt;/code&gt; and &lt;code&gt;/help&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/en/java/javase/17/jshell/introduction-jshell.html#GUID-465BA4F5-E77D-456F-BCB7-D826AC1E18AE"&gt;Introduction to JShell - Oracle.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;If you get &lt;code&gt;command not found&lt;/code&gt;, you might need to specify the full path. Give it a shot with &lt;code&gt;$JAVA_HOME/bin/jshell&lt;/code&gt;. Tip: adding &lt;code&gt;$JAVA_HOME/bin&lt;/code&gt; to your &lt;code&gt;$PATH&lt;/code&gt; might be a good idea. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;REPL stands for &lt;em&gt;Read, Evaluate, Print, Loop&lt;/em&gt;. Interpreted languages (Python, Ruby, et al) get REPLs for free - it's just the regular interpreter reading from standard input instead of a .py or .rb file. Compiled languages like Java need a little extra help. Thankfully, we have JShell! ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;For a super basic introduction to Streams, check out another entry in this series: &lt;a href="https://dev.to/dylanfw/from-python-to-java-comprehensions-and-streams-3j53"&gt;From Python to Java: Comprehensions and Streams&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>java</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>From Python to Java: Comprehensions and Streams</title>
      <dc:creator>Dylan</dc:creator>
      <pubDate>Fri, 08 Apr 2022 17:36:25 +0000</pubDate>
      <link>https://dev.to/dylanfw/from-python-to-java-comprehensions-and-streams-3j53</link>
      <guid>https://dev.to/dylanfw/from-python-to-java-comprehensions-and-streams-3j53</guid>
      <description>&lt;p&gt;For most of my career, I've worked primarily as a Python developer. There were occasional trips into the frontend for some JavaScript or a brief detour through a Go application, but the vast majority of my work was solidly Python.&lt;/p&gt;

&lt;p&gt;That is, until I joined Square. Square might be better known for its Ruby code, but there is also a sizable chunk of Java within its codebase. So when I came to Square, I knew I'd be putting away my list comprehensions, generators, and &lt;code&gt;@decorators&lt;/code&gt;, and instead I'd be learning some new programming language patterns and idioms.&lt;/p&gt;

&lt;p&gt;But of course, my Python experience would not be for nothing. As it turns out, we can find parallel ideas throughout most programming languages. In this series, I'll be highlighting some of these parallels I've encountered switching from Python to Java in hopes that it might help someone else who also finds themselves crossing this language barrier!&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It's impossible to avoid list (and dictionary!) comprehensions when working in Python. Whether you need to create a sublist by filtering out certain values, transform each element in an existing list, or rearrange keys and values into a new dictionary, comprehensions are a quintessential Python tool.&lt;/p&gt;

&lt;p&gt;They're so useful in Python and so numerous that you might find yourself afraid that you can't do even the simplest tasks in Java. You might recall hearing other developers groan about Java's verbosity and heavy-handedness as you start writing...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;evenIntegers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;allIntegers&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;evenIntegers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...at least that's how I felt, until I learned about Streams. With Streams, we don't have to rewire our brains or begrudgingly write lengthy boilerplate for simple tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;.stream()&lt;/code&gt;, &lt;code&gt;.collect()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;However, this is Java and we are going to be writing &lt;em&gt;some&lt;/em&gt; boilerplate. Types are everything in Java and in order to leverage the Streams API, we'll have to have an object of type &lt;code&gt;Stream&amp;lt;T&amp;gt;&lt;/code&gt;. Luckily this is often as easy as calling &lt;code&gt;.stream()&lt;/code&gt; on our object (assuming our object is iterable: a list, set, array, etc).&lt;/p&gt;

&lt;p&gt;Once we have our &lt;code&gt;Stream&amp;lt;T&amp;gt;&lt;/code&gt; object, we can apply a series of filters and transformations, but in the end we're going to want a list again (or a set, map, etc). This is where &lt;code&gt;.collect()&lt;/code&gt; comes in along with various &lt;code&gt;Collectors&lt;/code&gt;. In this post, we'll only focus on two Collector methods, &lt;code&gt;Collectors.toList()&lt;/code&gt; and &lt;code&gt;Collectors.toMap()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The basic structure of a stream is like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;obj.stream()
   &amp;lt;intermediate actions&amp;gt;
   .collect(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More verbose than Python, certainly, but not too bad!&lt;/p&gt;

&lt;p&gt;So without further ado, let's check out a few common operations and how we might do them with Python's comprehensions and then with Java's Streams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filtering
&lt;/h2&gt;

&lt;p&gt;Imagine we have a list of integers and we want only the even numbers. (The example is trivial, but I think it generalizes well enough.)&lt;/p&gt;

&lt;p&gt;In Python we would solve this problem with a simple list comprehension&lt;sup id="fnref1"&gt;1&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;even_nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;list_of_nums&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Java Streams, we could accomplish this like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;evenNums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listOfNums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Transforming
&lt;/h2&gt;

&lt;p&gt;Sometimes we want to take one list of elements and transform them into something else. For a simple example, let's take our same list of integers and multiply each by two.&lt;/p&gt;

&lt;p&gt;First in Python&lt;sup id="fnref2"&gt;2&lt;/sup&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;doubled_nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;list_of_nums&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then with Java Streams,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doubledNums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listOfNums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lists to Dictionaries
&lt;/h2&gt;

&lt;p&gt;Not &lt;em&gt;everything&lt;/em&gt; can be accomplished with lists&lt;sup id="fnref3"&gt;3&lt;/sup&gt;, sometimes we need to put things into a dictionary (or a Map, as they're called in Java land).&lt;/p&gt;

&lt;p&gt;Suppose we have a &lt;em&gt;list&lt;/em&gt; of &lt;code&gt;User&lt;/code&gt; objects and we want a &lt;em&gt;dictionary&lt;/em&gt; of each &lt;code&gt;user.name&lt;/code&gt; keyed by their &lt;code&gt;user.id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;names_by_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a little more complicated in Java. In our previous examples, we used &lt;code&gt;Collectors.toList()&lt;/code&gt;. Now that we want a Map, we'll have to use &lt;code&gt;Collectors.toMap()&lt;/code&gt;. This collector asks for a lambda function to produce the key and another one to produce the value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;namesById&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Collectors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Java has a reputation for having a verbose syntax, and Streams are no exception. But they &lt;em&gt;are&lt;/em&gt; a marked improvement over excessive loops and temporary variables for otherwise simple transformations and collections.&lt;/p&gt;

&lt;p&gt;While this post highlighted some ways that we can use Streams when we would otherwise write a comprehension in Python, it's important to know that Streams are &lt;em&gt;much more&lt;/em&gt; than this and are capable of some really cool things (parallelization, lazy evaluation, sorting, querying, etc, etc)!&lt;/p&gt;

&lt;p&gt;To learn more about Streams, check out &lt;a href="https://stackify.com/streams-guide-java-8/"&gt;this post by Eugen Paraschiv on Stackify&lt;/a&gt; and of course the &lt;a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/package-summary.html"&gt;Java documentation&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;Python &lt;em&gt;does&lt;/em&gt; have support for the more functional programming-style &lt;code&gt;filter&lt;/code&gt; that more closely mirrors Java's implementation. Though list comprehensions are generally considered to be more Pythonic than &lt;code&gt;filter&lt;/code&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Like the previous note, Python has support for &lt;code&gt;map&lt;/code&gt; but &lt;em&gt;in most cases&lt;/em&gt; the list comprehension is preferred. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Lisp programmers might take issue with this statement. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>python</category>
      <category>java</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
