{"id":64996,"date":"2022-06-10T09:00:39","date_gmt":"2022-06-10T09:00:39","guid":{"rendered":"https:\/\/www.cryptocabaret.com\/?p=64996"},"modified":"2022-06-10T09:00:39","modified_gmt":"2022-06-10T09:00:39","slug":"handling-maps-in-groovy-vs-java","status":"publish","type":"post","link":"https:\/\/www.cryptocabaret.com\/?p=64996","title":{"rendered":"Handling maps in Groovy vs Java"},"content":{"rendered":"<p><span class=\"field field--name-title field--type-string field--label-hidden\">Handling maps in Groovy vs Java<\/span><br \/>\n<span class=\"field field--name-uid field--type-entity-reference field--label-hidden\"><a title=\"View user profile.\" href=\"https:\/\/opensource.com\/users\/clhermansen\" class=\"username\">Chris Hermansen<\/a><\/span><br \/>\n<span class=\"field field--name-created field--type-created field--label-hidden\">Fri, 06\/10\/2022 &#8211; 03:00<\/span><\/p>\n<div data-drupal-selector=\"rate-node-70056\" class=\"rate-widget-thumbs-up\" title=\"Register or Login to like.\">\n<div class=\"rate-thumbs-up-btn-up vote-pending\"><a href=\"https:\/\/opensource.com\/user\/register\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml\">Login<\/a> to like<\/div>\n<div class=\"rate-score\"><a href=\"https:\/\/opensource.com\/user\/register\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml\">Login<\/a> to like<\/div>\n<\/div>\n<div class=\"clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item\">\n<p>Java is a great programming language, but sometimes I want a Java-like language that&#8217;s just a bit more flexible and compact. That&#8217;s when I opt for <a href=\"https:\/\/groovy-lang.org\/\" target=\"_blank\" rel=\"noopener\">Groovy<\/a>.<\/p>\n<p>In a recent article, I reviewed some of the differences between <a href=\"https:\/\/opensource.com\/article\/22\/3\/maps-groovy-vs-java\">creating and initializing maps in Groovy<\/a> and doing the same thing in Java. In brief, Groovy has a concise syntax for setting up maps and accessing map entries compared to the effort necessary in Java.<\/p>\n<p>This article will delve into more differences in map handling between Groovy and Java. For that purpose, I will use the <a href=\"https:\/\/datatables.net\/\" target=\"_blank\" rel=\"noopener\">sample table of employees<\/a> used for demoing the JavaScript DataTables library. To follow along, start by making sure you have recent versions of Groovy and Java installed on your computer.<\/p>\n<h2>Install Java and Groovy<\/h2>\n<p>Groovy is based on Java and requires a Java installation as well. A recent and\/or decent version of Java and Groovy might already be in your Linux distribution&#8217;s repositories, or you can download and install Groovy from the <a href=\"https:\/\/groovy.apache.org\/download.html\" target=\"_blank\" rel=\"noopener\">Apache Groovy website<\/a>. A good option for Linux users is <a href=\"https:\/\/opensource.com\/article\/22\/3\/manage-java-versions-sdkman\">SDKMan<\/a>, which can be used to get multiple versions of Java, Groovy, and many other related tools. For this article, I&#8217;m using SDK&#8217;s releases of:<\/p>\n<ul>\n<li>Java: version 11.0.12-open of OpenJDK 11<\/li>\n<li>Groovy: version 3.0.8.<\/li>\n<\/ul>\n<h2>Back to the problem: maps<\/h2>\n<p>First, in my experience, maps and lists (or at least arrays) often end up in the same program. For example, processing an input file is very similar to passing over a list; often, I do that when I want to categorize data encountered in the input file (or list), storing some kind of value in lookup tables, which are just maps.<\/p>\n<p>Second, Java 8 introduced the whole Streams functionality and lambdas (or anonymous functions). In my experience, converting input data (or lists) into maps often involves using Java Streams. Moreover, Java Streams are at their most flexible when dealing with streams of typed objects, providing grouping and accumulation facilities out of the box.<\/p>\n<h2>Employee list processing in Java<\/h2>\n<p>Here&#8217;s a concrete example based on those fictitious employee records. Below is a Java program that defines an Employee class to hold the employee information, builds a list of Employee instances, and processes that list in a few different ways:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"java geshifilter-java\">\u00a0 \u00a0 \u00a0<span class=\"nu0\">1<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.lang.*<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">2<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.util.Arrays<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">3<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.util.Locale<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">4<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.time.format.DateTimeFormatter<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">5<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.time.LocalDate<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">6<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.time.format.DateTimeParseException<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">7<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.text.NumberFormat<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">8<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.text.ParseException<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">9<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.util.stream.Collectors<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 <span class=\"nu0\">10<\/span>\u00a0 <span class=\"kw1\">public<\/span> <span class=\"kw1\">class<\/span> Test31 <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 <span class=\"nu0\">11<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">static<\/span> <span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> main<span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> args<span class=\"br0\">[<\/span><span class=\"br0\">]<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 <span class=\"nu0\">12<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 var employeeList <span class=\"sy0\">=<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+arrays\"><span class=\"kw3\">Arrays<\/span><\/a>.<span class=\"me1\">asList<\/span><span class=\"br0\">(<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">13<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">new<\/span> Employee<span class=\"br0\">(<\/span><span class=\"st0\">\"Tiger Nixon\"<\/span>, <span class=\"st0\">\"System Architect\"<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">14<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"Edinburgh\"<\/span>, <span class=\"st0\">\"5421\"<\/span>, <span class=\"st0\">\"2011\/04\/25\"<\/span>, <span class=\"st0\">\"$320,800\"<\/span><span class=\"br0\">)<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">15<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">new<\/span> Employee<span class=\"br0\">(<\/span><span class=\"st0\">\"Garrett Winters\"<\/span>, <span class=\"st0\">\"Accountant\"<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">16<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"Tokyo\"<\/span>, <span class=\"st0\">\"8422\"<\/span>, <span class=\"st0\">\"2011\/07\/25\"<\/span>, <span class=\"st0\">\"$170,750\"<\/span><span class=\"br0\">)<\/span>,<br>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 ...<br>\n\u00a0 \u00a0 <br>\n\u00a0 \u00a0 <span class=\"nu0\">81<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">new<\/span> Employee<span class=\"br0\">(<\/span><span class=\"st0\">\"Martena Mccray\"<\/span>, <span class=\"st0\">\"Post-Sales support\"<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">82<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"Edinburgh\"<\/span>, <span class=\"st0\">\"8240\"<\/span>, <span class=\"st0\">\"2011\/03\/09\"<\/span>, <span class=\"st0\">\"$324,050\"<\/span><span class=\"br0\">)<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">83<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">new<\/span> Employee<span class=\"br0\">(<\/span><span class=\"st0\">\"Unity Butler\"<\/span>, <span class=\"st0\">\"Marketing Designer\"<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">84<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"San Francisco\"<\/span>, <span class=\"st0\">\"5384\"<\/span>, <span class=\"st0\">\"2009\/12\/09\"<\/span>, <span class=\"st0\">\"$85,675\"<\/span><span class=\"br0\">)<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">85<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 <span class=\"nu0\">86<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"co1\">\/\/ calculate the average salary across the entire company<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 <span class=\"nu0\">87<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 var companyAvgSal <span class=\"sy0\">=<\/span> employeeList.<br>\n\u00a0 \u00a0 <span class=\"nu0\">88<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 stream<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0 <span class=\"nu0\">89<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 collect<span class=\"br0\">(<\/span>Collectors.<span class=\"me1\">averagingDouble<\/span><span class=\"br0\">(<\/span>Employee<span class=\"sy0\">::<\/span>getSalary<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">90<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">println<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"company avg salary = \"<\/span> <span class=\"sy0\">+<\/span> companyAvgSal<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 <span class=\"nu0\">91<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"co1\">\/\/ calculate the average salary for each location,<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">92<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"co1\">\/\/ \u00a0 \u00a0 compare to the company average<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 <span class=\"nu0\">93<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 var locationAvgSal <span class=\"sy0\">=<\/span> employeeList.<br>\n\u00a0 \u00a0 <span class=\"nu0\">94<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 stream<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0 <span class=\"nu0\">95<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 collect<span class=\"br0\">(<\/span>Collectors.<span class=\"me1\">groupingBy<\/span><span class=\"br0\">(<\/span><span class=\"br0\">(<\/span>Employee e<span class=\"br0\">)<\/span> <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">96<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 e.<span class=\"me1\">getLocation<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">97<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 Collectors.<span class=\"me1\">averagingDouble<\/span><span class=\"br0\">(<\/span>Employee<span class=\"sy0\">::<\/span>getSalary<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">98<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 locationAvgSal.<span class=\"kw1\">forEach<\/span><span class=\"br0\">(<\/span><span class=\"br0\">(<\/span>k,v<span class=\"br0\">)<\/span> <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">99<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">println<\/span><span class=\"br0\">(<\/span>k <span class=\"sy0\">+<\/span> <span class=\"st0\">\" avg salary = \"<\/span> <span class=\"sy0\">+<\/span> v <span class=\"sy0\">+<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">100<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"; diff from avg company salary = \"<\/span> <span class=\"sy0\">+<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">101<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">(<\/span>v <span class=\"sy0\">-<\/span> companyAvgSal<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">102<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"co1\">\/\/ show the employees in Edinburgh approach #1<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">103<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">print<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"employee(s) in Edinburgh (approach #1):\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">104<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 var employeesInEdinburgh <span class=\"sy0\">=<\/span> employeeList.<br>\n\u00a0 \u00a0<span class=\"nu0\">105<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 stream<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0<span class=\"nu0\">106<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 filter<span class=\"br0\">(<\/span>e <span class=\"sy0\">-&gt;<\/span> e.<span class=\"me1\">getLocation<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>.<span class=\"me1\">equals<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Edinburgh\"<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0<span class=\"nu0\">107<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 collect<span class=\"br0\">(<\/span>Collectors.<span class=\"me1\">toList<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">108<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 employeesInEdinburgh.<br>\n\u00a0 \u00a0<span class=\"nu0\">109<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">forEach<\/span><span class=\"br0\">(<\/span>e <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">110<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">print<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\" \"<\/span> <span class=\"sy0\">+<\/span> e.<span class=\"me1\">getSurname<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">+<\/span> <span class=\"st0\">\",\"<\/span> <span class=\"sy0\">+<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">111<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 e.<span class=\"me1\">getGivenName<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">112<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">println<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">113<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"co1\">\/\/ group employees by location<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">114<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 var employeesByLocation <span class=\"sy0\">=<\/span> employeeList.<br>\n\u00a0 \u00a0<span class=\"nu0\">115<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 stream<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0<span class=\"nu0\">116<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 collect<span class=\"br0\">(<\/span>Collectors.<span class=\"me1\">groupingBy<\/span><span class=\"br0\">(<\/span>Employee<span class=\"sy0\">::<\/span>getLocation<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">117<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"co1\">\/\/ show the employees in Edinburgh approach #2<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">118<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">print<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"employee(s) in Edinburgh (approach #2):\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">119<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 employeesByLocation.<span class=\"me1\">get<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Edinburgh\"<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0<span class=\"nu0\">120<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">forEach<\/span><span class=\"br0\">(<\/span>e <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">121<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">print<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\" \"<\/span> <span class=\"sy0\">+<\/span> e.<span class=\"me1\">getSurname<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">+<\/span> <span class=\"st0\">\",\"<\/span> <span class=\"sy0\">+<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">122<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 e.<span class=\"me1\">getGivenName<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">123<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">println<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">124<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">125<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">126<\/span>\u00a0 <span class=\"kw1\">class<\/span> Employee <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">127<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">private<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> surname<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">128<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">private<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> givenName<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">129<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">private<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> role<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">130<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">private<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> location<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">131<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">private<\/span> <span class=\"kw4\">int<\/span> extension<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">132<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">private<\/span> LocalDate hired<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">133<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">private<\/span> <span class=\"kw4\">double<\/span> salary<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">134<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">public<\/span> Employee<span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> fullName, <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> role, <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> location,<br>\n\u00a0 \u00a0<span class=\"nu0\">135<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> extension, <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> hired, <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> salary<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">136<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 var nn <span class=\"sy0\">=<\/span> fullName.<span class=\"me1\">split<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\" \"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">137<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">if<\/span> <span class=\"br0\">(<\/span>nn.<span class=\"me1\">length<\/span> <span class=\"sy0\">&gt;<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">138<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">surname<\/span> <span class=\"sy0\">=<\/span> nn<span class=\"br0\">[<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">]<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">139<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">givenName<\/span> <span class=\"sy0\">=<\/span> nn<span class=\"br0\">[<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">]<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">140<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">141<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">surname<\/span> <span class=\"sy0\">=<\/span> nn<span class=\"br0\">[<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">]<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">142<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">givenName<\/span> <span class=\"sy0\">=<\/span> <span class=\"st0\">\"\"<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">143<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">144<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">role<\/span> <span class=\"sy0\">=<\/span> role<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">145<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">location<\/span> <span class=\"sy0\">=<\/span> location<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">146<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">try<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">147<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">extension<\/span> <span class=\"sy0\">=<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer\"><span class=\"kw3\">Integer<\/span><\/a>.<span class=\"me1\">parseInt<\/span><span class=\"br0\">(<\/span>extension<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">148<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">catch<\/span> <span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+numberformatexception\"><span class=\"kw3\">NumberFormatException<\/span><\/a> nfe<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">149<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">extension<\/span> <span class=\"sy0\">=<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">150<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">151<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">try<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">152<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">hired<\/span> <span class=\"sy0\">=<\/span> LocalDate.<span class=\"me1\">parse<\/span><span class=\"br0\">(<\/span>hired,<br>\n\u00a0 \u00a0<span class=\"nu0\">153<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 DateTimeFormatter.<span class=\"me1\">ofPattern<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"yyyy\/MM\/dd\"<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">154<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">catch<\/span> <span class=\"br0\">(<\/span>DateTimeParseException dtpe<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">155<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">hired<\/span> <span class=\"sy0\">=<\/span> LocalDate.<span class=\"me1\">EPOCH<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">156<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">157<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">try<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">158<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">salary<\/span> <span class=\"sy0\">=<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+numberformat\"><span class=\"kw3\">NumberFormat<\/span><\/a>.<span class=\"me1\">getCurrencyInstance<\/span><span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+locale\"><span class=\"kw3\">Locale<\/span><\/a>.<span class=\"me1\">US<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0<span class=\"nu0\">159<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 parse<span class=\"br0\">(<\/span>salary<span class=\"br0\">)<\/span>.<span class=\"me1\">doubleValue<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">160<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">catch<\/span> <span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+parseexception\"><span class=\"kw3\">ParseException<\/span><\/a> pe<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">161<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"kw1\">this<\/span>.<span class=\"me1\">salary<\/span> <span class=\"sy0\">=<\/span> 0d<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">162<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">163<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">164<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">public<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> getSurname<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">surname<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">165<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">public<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> getGivenName<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">givenName<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">166<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">public<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a> getLocation<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">location<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">167<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">public<\/span> <span class=\"kw4\">int<\/span> getExtension<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">extension<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">168<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">public<\/span> LocalDate getHired<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">hired<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">169<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">public<\/span> <span class=\"kw4\">double<\/span> getSalary<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span> <span class=\"kw1\">return<\/span> <span class=\"kw1\">this<\/span>.<span class=\"me1\">salary<\/span><span class=\"sy0\">;<\/span> <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">170<\/span>\u00a0 <span class=\"br0\">}<\/span><\/div><\/div><\/pre>\n<\/p>\n<div class=\"embedded-resource-list callout-float-right\">\n<div class=\"field field--name-title field--type-string field--label-hidden field__item\">Programming and development<\/div>\n<div class=\"field field--name-links field--type-link field--label-hidden field__items\">\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/?intcmp=7016000000127cYAAQ\">Red Hat Developers Blog<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/downloads\/cheat-sheets?intcmp=7016000000127cYAAQ\">Programming cheat sheets<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/www.redhat.com\/en\/services\/training\/learning-subscription?intcmp=7016000000127cYAAQ\">Try for free: Red Hat Learning Subscription<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/downloads\/bash-programming-guide?intcmp=7016000000127cYAAQ\">eBook: An introduction to programming with Bash<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/cheat-sheets\/bash-shell-cheat-sheet?intcmp=7016000000127cYAAQ\">Bash shell scripting cheat sheet<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/e-books\/modernizing-enterprise-java?intcmp=7016000000127cYAAQ\">eBook: Modernizing Enterprise Java<\/a><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>Wow, that&#8217;s a lot of code for a simple demo program! I&#8217;ll go through it in chunks first.<\/p>\n<p>Starting at the end, lines 126 through 170 define the <code>Employee<\/code> class used to store employee data. The most important thing to mention here is that the fields of the employee record are of different types, and in Java that generally leads to defining this type of class. You could make this code a bit more compact by using <a href=\"https:\/\/projectlombok.org\/features\/Data\" target=\"_blank\" rel=\"noopener\">Project Lombok&#8217;s @Data<\/a> annotation to automatically generate the getters (and setters) for the <code>Employee<\/code> class. In more recent versions of Java, I can declare these sorts of things as a <i>record<\/i> rather than a class, since the whole point is to store data. Storing the data as a list of <code>Employee<\/code> instances facilitates the use of Java streams.<\/p>\n<p>Lines 12 through 85 create the list of <code>Employee<\/code> instances, so now you&#8217;ve already dealt with 119 of 170 lines.<\/p>\n<p>There are nine lines of import statements up front. Interestingly, there are no map-related imports! This is partly because I&#8217;m using stream methods that yield maps as their results, and partly because I&#8217;m using the <code>var<\/code> keyword to declare variables, so the type is inferred by the compiler.<\/p>\n<p>The interesting parts of the above code happen in lines 86 through 123.<\/p>\n<p>In lines 87-90, I convert <code>employeeList <\/code>into a stream (line 88) and then use <code>collect()<\/code> to apply the <code>Collectors.averagingDouble()<\/code> method to the <code>Employee::getSalary<\/code> (line 89) method to calculate the average salary across the whole company. This is pure functional list processing; no maps are involved.<\/p>\n<p>In lines 93-101, I convert <code>employeeList <\/code>into a stream again. I then use the <code>Collectors.groupingBy()<\/code> method to create a map whose keys are employee locations, returned by <code>e.getLocation()<\/code>, and whose values are the average salary for each location, returned by <code>Collectors.averagingDouble()<\/code> again applied to the <code>Employee::getSalary<\/code> method applied to each employee in the location subset, rather than the entire company. That is, the <code>groupingBy() <\/code>method creates subsets by location, which are then averaged. Lines 98-101 use <code>forEach()<\/code> to step through the map entries printing location, average salary, and the difference between the location averages and company average.<\/p>\n<p>Now, suppose you wanted to look at just those employees located in Edinburgh. One way to accomplish this is shown in lines 103-112, where I use the stream <code>filter() <\/code>method to create a list of only those employees based in Edinburgh and the <code>forEach()<\/code><b> <\/b>method to print their names. No maps here, either.<\/p>\n<p>Another way to solve this problem is shown in lines 113-123. In this method, I create a map where each entry holds a list of employees by location. First, in lines 113-116, I use the <code>groupingBy()<\/code> method to produce the map I want with keys of employee locations whose values are sublists of employees at that location. Then, in lines 117-123, I use the <code>forEach()<\/code> method to print out the sublist of names of employees at the Edinburgh location.<\/p>\n<p>When we compile and run the above, the output is:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"java geshifilter-java\">company avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">292082.5<\/span><br>\nSan Francisco avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">284703.125<\/span><span class=\"sy0\">;<\/span> diff from avg company salary <span class=\"sy0\">=<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">7379.375<\/span><br><span class=\"kw1\">New<\/span> York avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">410158.3333333333<\/span><span class=\"sy0\">;<\/span> diff from avg company salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">118075.83333333331<\/span><br>\nSingapore avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">357650.0<\/span><span class=\"sy0\">;<\/span> diff from avg company salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">65567.5<\/span><br>\nTokyo avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">206087.5<\/span><span class=\"sy0\">;<\/span> diff from avg company salary <span class=\"sy0\">=<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">85995.0<\/span><br>\nLondon avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">322476.25<\/span><span class=\"sy0\">;<\/span> diff from avg company salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">30393.75<\/span><br>\nEdinburgh avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">261940.7142857143<\/span><span class=\"sy0\">;<\/span> diff from avg company salary <span class=\"sy0\">=<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">30141.78571428571<\/span><br>\nSydney avg salary <span class=\"sy0\">=<\/span> <span class=\"nu0\">90500.0<\/span><span class=\"sy0\">;<\/span> diff from avg company salary <span class=\"sy0\">=<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">201582.5<\/span><br>\nemployee<span class=\"br0\">(<\/span>s<span class=\"br0\">)<\/span> in Edinburgh <span class=\"br0\">(<\/span>approach #<span class=\"nu0\">1<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">:<\/span> Nixon,Tiger Kelly,Cedric Frost,Sonya Flynn,Quinn Rios,Dai Joyce,Gavin Mccray,Martena<br>\nemployee<span class=\"br0\">(<\/span>s<span class=\"br0\">)<\/span> in Edinburgh <span class=\"br0\">(<\/span>approach #<span class=\"nu0\">2<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">:<\/span> Nixon,Tiger Kelly,Cedric Frost,Sonya Flynn,Quinn Rios,Dai Joyce,Gavin Mccray,Martena<\/div><\/div><\/pre>\n<h2>Employee list processing in Groovy<\/h2>\n<p>Groovy has always provided enhanced facilities for processing lists and maps, partly by extending the Java Collections library and partly by providing closures, which are somewhat like lambdas.<\/p>\n<p>One outcome of this is that maps in Groovy can easily be used with different types of values. As a result, you can&#8217;t be pushed into making the auxiliary Employee class; instead, you can just use a map. Let&#8217;s examine a Groovy version of the same functionality:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"java geshifilter-java\">\u00a0 \u00a0 \u00a0<span class=\"nu0\">1<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.util.Locale<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">2<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.time.format.DateTimeFormatter<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">3<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.time.LocalDate<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">4<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.time.format.DateTimeParseException<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">5<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.text.NumberFormat<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">6<\/span>\u00a0 <span class=\"kw1\">import<\/span> <span class=\"co2\">java.text.ParseException<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">7<\/span>\u00a0 def employeeList <span class=\"sy0\">=<\/span> <span class=\"br0\">[<\/span><br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">8<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">[<\/span><span class=\"st0\">\"Tiger Nixon\"<\/span>, <span class=\"st0\">\"System Architect\"<\/span>, <span class=\"st0\">\"Edinburgh\"<\/span>,<br>\n\u00a0 \u00a0 \u00a0<span class=\"nu0\">9<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"5421\"<\/span>, <span class=\"st0\">\"2011\/04\/25\"<\/span>, <span class=\"st0\">\"<span class=\"es0\">$<\/span>320,800\"<\/span><span class=\"br0\">]<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">10<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">[<\/span><span class=\"st0\">\"Garrett Winters\"<\/span>, <span class=\"st0\">\"Accountant\"<\/span>, <span class=\"st0\">\"Tokyo\"<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">11<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"8422\"<\/span>, <span class=\"st0\">\"2011\/07\/25\"<\/span>, <span class=\"st0\">\"<span class=\"es0\">$<\/span>170,750\"<\/span><span class=\"br0\">]<\/span>,<br><br>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0...<br><br>\n\u00a0 \u00a0 <span class=\"nu0\">76<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">[<\/span><span class=\"st0\">\"Martena Mccray\"<\/span>, <span class=\"st0\">\"Post-Sales support\"<\/span>, <span class=\"st0\">\"Edinburgh\"<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">77<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"8240\"<\/span>, <span class=\"st0\">\"2011\/03\/09\"<\/span>, <span class=\"st0\">\"<span class=\"es0\">$<\/span>324,050\"<\/span><span class=\"br0\">]<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">78<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">[<\/span><span class=\"st0\">\"Unity Butler\"<\/span>, <span class=\"st0\">\"Marketing Designer\"<\/span>, <span class=\"st0\">\"San Francisco\"<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">79<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"5384\"<\/span>, <span class=\"st0\">\"2009\/12\/09\"<\/span>, <span class=\"st0\">\"<span class=\"es0\">$<\/span>85,675\"<\/span><span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">80<\/span>\u00a0 <span class=\"br0\">]<\/span>.<span class=\"me1\">collect<\/span> <span class=\"br0\">{<\/span> ef <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">81<\/span>\u00a0 \u00a0 \u00a0 def surname, givenName, role, location, extension, hired, salary<br>\n\u00a0 \u00a0 <span class=\"nu0\">82<\/span>\u00a0 \u00a0 \u00a0 def nn <span class=\"sy0\">=<\/span> ef<span class=\"br0\">[<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">]<\/span>.<span class=\"me1\">split<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\" \"<\/span><span class=\"br0\">)<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">83<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">if<\/span> <span class=\"br0\">(<\/span>nn.<span class=\"me1\">length<\/span> <span class=\"sy0\">&gt;<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">84<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 surname <span class=\"sy0\">=<\/span> nn<span class=\"br0\">[<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">85<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 givenName <span class=\"sy0\">=<\/span> nn<span class=\"br0\">[<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">86<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">else<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">87<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 surname <span class=\"sy0\">=<\/span> nn<span class=\"br0\">[<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">88<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 givenName <span class=\"sy0\">=<\/span> <span class=\"st0\">\"\"<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">89<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">90<\/span>\u00a0 \u00a0 \u00a0 role <span class=\"sy0\">=<\/span> ef<span class=\"br0\">[<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">91<\/span>\u00a0 \u00a0 \u00a0 location <span class=\"sy0\">=<\/span> ef<span class=\"br0\">[<\/span><span class=\"nu0\">2<\/span><span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">92<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">try<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">93<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 extension <span class=\"sy0\">=<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+integer\"><span class=\"kw3\">Integer<\/span><\/a>.<span class=\"me1\">parseInt<\/span><span class=\"br0\">(<\/span>ef<span class=\"br0\">[<\/span><span class=\"nu0\">3<\/span><span class=\"br0\">]<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">94<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">catch<\/span> <span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+numberformatexception\"><span class=\"kw3\">NumberFormatException<\/span><\/a> nfe<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">95<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 extension <span class=\"sy0\">=<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">96<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">97<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">try<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 <span class=\"nu0\">98<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 hired <span class=\"sy0\">=<\/span> LocalDate.<span class=\"me1\">parse<\/span><span class=\"br0\">(<\/span>ef<span class=\"br0\">[<\/span><span class=\"nu0\">4<\/span><span class=\"br0\">]<\/span>,<br>\n\u00a0 \u00a0 <span class=\"nu0\">99<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 DateTimeFormatter.<span class=\"me1\">ofPattern<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"yyyy\/MM\/dd\"<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">100<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">catch<\/span> <span class=\"br0\">(<\/span>DateTimeParseException dtpe<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">101<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 hired <span class=\"sy0\">=<\/span> LocalDate.<span class=\"me1\">EPOCH<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">102<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">103<\/span>\u00a0 \u00a0 \u00a0 <span class=\"kw1\">try<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">104<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 salary <span class=\"sy0\">=<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+numberformat\"><span class=\"kw3\">NumberFormat<\/span><\/a>.<span class=\"me1\">getCurrencyInstance<\/span><span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+locale\"><span class=\"kw3\">Locale<\/span><\/a>.<span class=\"me1\">US<\/span><span class=\"br0\">)<\/span>.<br>\n\u00a0 \u00a0<span class=\"nu0\">105<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 parse<span class=\"br0\">(<\/span>ef<span class=\"br0\">[<\/span><span class=\"nu0\">5<\/span><span class=\"br0\">]<\/span><span class=\"br0\">)<\/span>.<span class=\"me1\">doubleValue<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">106<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span> <span class=\"kw1\">catch<\/span> <span class=\"br0\">(<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+parseexception\"><span class=\"kw3\">ParseException<\/span><\/a> pe<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">107<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 salary <span class=\"sy0\">=<\/span> 0d<span class=\"sy0\">;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">108<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">109<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">[<\/span>surname<span class=\"sy0\">:<\/span> surname, givenName<span class=\"sy0\">:<\/span> givenName, role<span class=\"sy0\">:<\/span> role,<br>\n\u00a0 \u00a0<span class=\"nu0\">110<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 location<span class=\"sy0\">:<\/span> location, extension<span class=\"sy0\">:<\/span> extension, hired<span class=\"sy0\">:<\/span> hired, salary<span class=\"sy0\">:<\/span> salary<span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">111<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">112<\/span>\u00a0 <span class=\"co1\">\/\/ calculate the average salary across the entire company<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">113<\/span>\u00a0 def companyAvgSal <span class=\"sy0\">=<\/span> employeeList.<span class=\"me1\">average<\/span> <span class=\"br0\">{<\/span> e <span class=\"sy0\">-&gt;<\/span> e.<span class=\"me1\">salary<\/span> <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">114<\/span>\u00a0 println <span class=\"st0\">\"company avg salary = \"<\/span> <span class=\"sy0\">+<\/span> companyAvgSal<br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">115<\/span>\u00a0 <span class=\"co1\">\/\/ calculate the average salary for each location,<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">116<\/span>\u00a0 <span class=\"co1\">\/\/ \u00a0 \u00a0 compare to the company average<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">117<\/span>\u00a0 def locationAvgSal <span class=\"sy0\">=<\/span> employeeList.<span class=\"me1\">groupBy<\/span> <span class=\"br0\">{<\/span> e <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">118<\/span>\u00a0 \u00a0 \u00a0 e.<span class=\"me1\">location<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">119<\/span>\u00a0 <span class=\"br0\">}<\/span>.<span class=\"me1\">collectEntries<\/span> <span class=\"br0\">{<\/span> l, el <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">120<\/span>\u00a0 \u00a0 \u00a0 <span class=\"br0\">[<\/span>l, el.<span class=\"me1\">average<\/span> <span class=\"br0\">{<\/span> e <span class=\"sy0\">-&gt;<\/span> e.<span class=\"me1\">salary<\/span> <span class=\"br0\">}<\/span><span class=\"br0\">]<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">121<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">122<\/span>\u00a0 locationAvgSal.<span class=\"me1\">each<\/span> <span class=\"br0\">{<\/span> l, a <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">123<\/span>\u00a0 \u00a0 \u00a0 println l <span class=\"sy0\">+<\/span> <span class=\"st0\">\" avg salary = \"<\/span> <span class=\"sy0\">+<\/span> a <span class=\"sy0\">+<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">124<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"st0\">\"; diff from avg company salary = \"<\/span> <span class=\"sy0\">+<\/span> <span class=\"br0\">(<\/span>a <span class=\"sy0\">-<\/span> companyAvgSal<span class=\"br0\">)<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">125<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">126<\/span>\u00a0 <span class=\"co1\">\/\/ show the employees in Edinburgh approach #1<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">127<\/span>\u00a0 print <span class=\"st0\">\"employee(s) in Edinburgh (approach #1):\"<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">128<\/span>\u00a0 def employeesInEdinburgh <span class=\"sy0\">=<\/span> employeeList.<span class=\"me1\">findAll<\/span> <span class=\"br0\">{<\/span> e <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">129<\/span>\u00a0 \u00a0 \u00a0 e.<span class=\"me1\">location<\/span> <span class=\"sy0\">==<\/span> <span class=\"st0\">\"Edinburgh\"<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">130<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">131<\/span>\u00a0 employeesInEdinburgh.<span class=\"me1\">each<\/span> <span class=\"br0\">{<\/span> e <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">132<\/span>\u00a0 \u00a0 \u00a0 print <span class=\"st0\">\" \"<\/span> <span class=\"sy0\">+<\/span> e.<span class=\"me1\">surname<\/span> <span class=\"sy0\">+<\/span> <span class=\"st0\">\",\"<\/span> <span class=\"sy0\">+<\/span> e.<span class=\"me1\">givenName<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">133<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">134<\/span>\u00a0 println<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">135<\/span>\u00a0 <span class=\"co1\">\/\/ group employees by location<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">136<\/span>\u00a0 def employeesByLocation <span class=\"sy0\">=<\/span> employeeList.<span class=\"me1\">groupBy<\/span> <span class=\"br0\">{<\/span> e <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">137<\/span>\u00a0 \u00a0 \u00a0 e.<span class=\"me1\">location<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">138<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">139<\/span>\u00a0 <span class=\"co1\">\/\/ show the employees in Edinburgh approach #2<\/span><br>\n\u00a0 \u00a0 \u00a0 \u00a0<br>\n\u00a0 \u00a0<span class=\"nu0\">140<\/span>\u00a0 print <span class=\"st0\">\"employee(s) in Edinburgh (approach #1):\"<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">141<\/span>\u00a0 employeesByLocation<span class=\"br0\">[<\/span><span class=\"st0\">\"Edinburgh\"<\/span><span class=\"br0\">]<\/span>.<span class=\"me1\">each<\/span> <span class=\"br0\">{<\/span> e <span class=\"sy0\">-&gt;<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">142<\/span>\u00a0 \u00a0 \u00a0 print <span class=\"st0\">\" \"<\/span> <span class=\"sy0\">+<\/span> e.<span class=\"me1\">surname<\/span> <span class=\"sy0\">+<\/span> <span class=\"st0\">\",\"<\/span> <span class=\"sy0\">+<\/span> e.<span class=\"me1\">givenName<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">143<\/span>\u00a0 <span class=\"br0\">}<\/span><br>\n\u00a0 \u00a0<span class=\"nu0\">144<\/span>\u00a0 println<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><\/div><\/div><\/pre>\n<p>Because I am just writing a script here, I don&#8217;t need to put the program body inside a method inside a class; Groovy handles that for us.<\/p>\n<p>In lines 1-6, I still need to import the classes needed for the data parsing. Groovy imports quite a bit of useful stuff by default, including <code>java.lang.*<\/code> and<b> <\/b><code>java.util.*<\/code>.<\/p>\n<p>In lines 7-90, I use Groovy&#8217;s syntactic support for lists as comma-separated values bracketed by <code>[<\/code> and <code>]<\/code>. In this case, there is a list of lists; each sublist is the employee data. Notice that you need the <code><\/code> in front of the <code>$<\/code> in the salary field. This is because a <code>$<\/code> occurring inside a string surrounded by double quotes indicates the presence of a field whose value is to be interpolated into the string. An alternative would be to use single quotes.<\/p>\n<p>But I don&#8217;t want to work with a list of lists; I would rather have a list of maps analogous to the list of Employee class instances in the Java version. I use the Groovy Collection<code> .collect()<\/code> method in lines 90-111 to take apart each sublist of employee data and convert it into a map. The collect method takes a Groovy Closure argument, and the syntax for creating a closure surrounds the code with <code>{<\/code> and <code>}<\/code> and lists the parameters as <code>a, b, c -&gt;<\/code> in a manner similar to Java&#8217;s lambdas. Most of the code looks quite similar to the constructor method in the Java Employee class, except that there are items in the sublist rather than arguments to the constructor. However, the last two lines\u2014<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"java geshifilter-java\"><span class=\"br0\">[<\/span>surname<span class=\"sy0\">:<\/span> surname, givenName<span class=\"sy0\">:<\/span> givenName, role<span class=\"sy0\">:<\/span> role,<br><br>\n\u00a0 \u00a0 location<span class=\"sy0\">:<\/span> location, extension<span class=\"sy0\">:<\/span> extension, hired<span class=\"sy0\">:<\/span> hired, salary<span class=\"sy0\">:<\/span> salary<span class=\"br0\">]<\/span><\/div><\/div><\/pre>\n<p>\u2014create a map with keys <code>surname<\/code>, <code>givenName<\/code>, <code>role<\/code>, <code>location<\/code>, <code>extension<\/code>, <code>hired<\/code>, and <code>salary<\/code>. And, since this is the last line of the closure, the value returned to the caller is this map. No need for a return statement. No need to quote these key values; Groovy assumes they are strings. In fact, if they were variables, you would need to put them in parentheses to indicate the need to evaluate them. The value assigned to each key appears on its right side. Note that this is a map whose values are of different types: The first four are <code>String<\/code>, then <code>int<\/code>, <code>LocalDate<\/code>, and <code>double<\/code>. It would have been possible to define the sublists with elements of those different types, but I chose to take this approach because the data would often be read in as string values from a text file.<\/p>\n<p>The interesting bits appear in lines 112-144. I&#8217;ve kept the same kind of processing steps as in the Java version.<\/p>\n<p>In lines 112-114, I use the Groovy Collection <code>average()<\/code> method, which like <code>collect()<\/code> takes a Closure argument, here iterating over the list of employee maps and picking out the <code>salary<\/code> value. Note that using these methods on the Collection class means you don&#8217;t have to learn how to transform lists, maps, or some other element to streams and then learn the stream methods to handle your calculations, as in Java. For those who like Java Streams, they are available in newer Groovy versions.<\/p>\n<p>In lines 115-125, I calculate the average salary by location. First, in lines 117-119, I transform <code>employeeList<\/code>, which is a list of maps, into a map, using the Collection<code> groupBy()<\/code> method, whose keys are the location values and whose values are linked sublists of the employee maps pertaining to that location. Then I process those map entries with the <code>collectEntries()<\/code> method, using the <code>average()<\/code> method to compute the average salary for each location.<\/p>\n<p>Note that <code>collectEntries()<\/code> passes each key (location) and value (employee sublist at that location) into the closure (the <code>l, el -&gt;<\/code> string) and expects a two-element list of key (location) and value (average salary at that location) to be returned, converting those into map entries. Once I have the map of average salaries by location, <code>locationAvgSal<\/code>, I can print it out using the Collection <code>each()<\/code> method, which also takes a closure. When <code>each()<\/code> is applied to a map, it passes in the key (location) and value (average salary) in the same way as <code>collectEntries()<\/code>.<\/p>\n<p>In lines 126-134, I filter the <code>employeeList<\/code> to get a sublist of <code>employeesInEdinburgh<\/code>, using the <code>findAll()<\/code> method, which is analogous to the Java Streams <code>filter()<\/code> method. And again, I use the <code>each()<\/code> method to print out the sublist of employees in Edinburgh.<\/p>\n<p>In lines 135-144, I take the alternative approach of grouping the <code>employeeList <\/code>into a map of employee sublists at each location, <code>employeesByLocation<\/code>. Then in lines 139-144, I select the employee sublist at Edinburgh, using the expression <code>employeesByLocation[\u201cEdinburgh\u201d] <\/code>and the <code>each()<\/code> method to print out the sublist of employee names at that location.<\/p>\n<h2>Why I often prefer Groovy<\/h2>\n<p>Maybe it&#8217;s just my familiarity with Groovy, built up over the last 12 years or so, but I feel more comfortable with the Groovy approach to enhancing Collection with all these methods that take a closure as an argument, rather than the Java approach of converting the list, map, or whatever is at hand to a stream and then using streams, lambdas, and data classes to handle the processing steps. I seem to spend a lot more time with the Java equivalents before I get something working.<\/p>\n<p>I&#8217;m also a huge fan of strong static typing and parameterized types, such as <code>Map<string><\/string>,employee&gt;<\/code>\u00a0<code><string><\/string>,employee&gt;<\/code>as found in Java. However, on a day-to-day basis, I find that the more relaxed approach of lists and maps accommodating different types does a better job of supporting me in the real world of data without requiring a lot of extra code. Dynamic typing can definitely come back to bite the programmer. Still, even knowing that I can turn static type checking on in Groovy, I bet I haven&#8217;t done so more than a handful of times. Maybe my appreciation for Groovy comes from my work, which usually involves bashing a bunch of data into shape and then analyzing it; I&#8217;m certainly not your average developer. So is Groovy really a more Pythonic Java? Food for thought.<\/p>\n<p>I would love to see in both Java and Groovy a few more facilities like <code>average()<\/code>and <code>averagingDouble()<\/code>. Two-argument versions to produce weighted averages and statistical methods beyond averaging\u2014like median, standard deviation, and so forth\u2014would also be helpful. <a href=\"https:\/\/www.tabnine.com\/code\/java\/methods\/java.util.stream.Collectors\/averagingDouble\" target=\"_blank\" rel=\"noopener\">Tabnine<\/a> offers interesting suggestions on implementing some of these.<\/p>\n<h2>Groovy resources<\/h2>\n<p>The <a href=\"https:\/\/groovy-lang.org\/\" target=\"_blank\" rel=\"noopener\">Apache Groovy site<\/a> has a lot of great documentation. Other good sources include the reference page for <a href=\"https:\/\/docs.groovy-lang.org\/latest\/html\/groovy-jdk\/java\/util\/Collection.html\" target=\"_blank\" rel=\"noopener\">Groovy enhancements to the Java Collection class<\/a>, the more tutorial-like introduction to <a href=\"https:\/\/groovy-lang.org\/groovy-dev-kit.html#_working_with_collections\" target=\"_blank\" rel=\"noopener\">working with collections<\/a>, and <a href=\"https:\/\/blog.mrhaki.com\/\" target=\"_blank\" rel=\"noopener\">Mr. Haki<\/a>. The <a href=\"https:\/\/www.baeldung.com\/\" target=\"_blank\" rel=\"noopener\">Baeldung site<\/a> provides a lot of helpful how-tos in Java and Groovy. And a really great reason to learn Groovy is to learn <a href=\"https:\/\/grails.org\/\" target=\"_blank\" rel=\"noopener\">Grails<\/a>, a wonderfully productive full-stack web framework built on top of excellent components like Hibernate, Spring Boot, and Micronaut.<\/p>\n<\/div>\n<div class=\"clearfix text-formatted field field--name-field-article-subhead field--type-text-long field--label-hidden field__item\">\n<p>Discover the differences in map handling between Groovy and Java with this hands-on demo.<\/p>\n<\/div>\n<div class=\"field field--name-field-lead-image field--type-entity-reference field--label-hidden field__item\">\n<article class=\"media media--type-image media--view-mode-caption\">\n<div class=\"field field--name-field-media-image field--type-image field--label-hidden field__item\">  <img decoding=\"async\" src=\"https:\/\/www.cryptocabaret.com\/wp-content\/uploads\/2022\/06\/collab-team-pair-programming-code-keyboard2.png\" width=\"520\" height=\"292\" alt=\"women programming\" title=\"women programming\" loading=\"lazy\"><\/div>\n<div class=\"field field--name-field-caption field--type-text-long field--label-hidden caption field__item\"><span class=\"caption__byline\">Image by: <\/span><\/p>\n<p>WOCinTech Chat. Modified by Opensource.com. CC BY-SA 4.0<\/p>\n<\/div>\n<\/article>\n<\/div>\n<div class=\"field field--name-field-tags field--type-entity-reference field--label-hidden field__items\">\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/tags\/programming\" hreflang=\"en\">Programming<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/tags\/java\" hreflang=\"en\">Java<\/a><\/div>\n<\/p><\/div>\n<div class=\"field field--name-field-listicle-title field--type-string field--label-hidden field__item\">What to read next<\/div>\n<div class=\"field field--name-field-listicles field--type-entity-reference field--label-hidden field__items\">\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/article\/22\/3\/maps-groovy-vs-java\" hreflang=\"und\">Creating and initializing maps in Groovy vs Java<\/a><\/div>\n<\/p><\/div>\n<div class=\"field field--name-field-default-license field--type-list-string field--label-hidden field__item\"><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\"><br \/>\n        <img decoding=\"async\" alt=\"Creative Commons License\" src=\"https:\/\/www.cryptocabaret.com\/wp-content\/uploads\/2022\/06\/cc-by-sa--13.png\" title=\"This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.\"><\/a>This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.<\/div>\n<section class=\"field field--name-field-comments field--type-comment field--label-hidden comment-wrapper\">\n<div class=\"comments__count\">\n<div class=\"login\"><a href=\"https:\/\/opensource.com\/user\/register?absolute=1\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml&amp;absolute=1\">Login<\/a> to post a comment.<\/div>\n<\/p><\/div>\n<\/section>\n<p class=\"wpematico_credit\"><small>Powered by <a href=\"http:\/\/www.wpematico.com\" target=\"_blank\" rel=\"noopener\">WPeMatico<\/a><\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Handling maps in Groovy vs Java Chris Hermansen Fri, 06\/10\/2022 &#8211; 03:00 Register or Login to like Register or Login to like Java is a great programming language, but sometimes I want a Java-like language that&#8217;s just a bit more flexible and compact. That&#8217;s when I opt for Groovy. In a recent article, I reviewed [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":64997,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[307],"tags":[],"class_list":["post-64996","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-open-source"],"_links":{"self":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts\/64996","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=64996"}],"version-history":[{"count":0,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts\/64996\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/media\/64997"}],"wp:attachment":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=64996"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=64996"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=64996"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}