I’ve just lately explored a few of the variations between Java and Groovy when creating and initializing lists and building lists at runtime. I noticed the easy services supplied by Groovy for these functions compared to the complexity required in Java.
In this text, I look at creating and initializing maps in Java and Groovy. Maps present the flexibility to develop constructions you possibly can search by key. And if the important thing will get discovered, that returns the worth related to that key. Today, maps are carried out in lots of programming languages, together with Java and Groovy, but in addition Python (the place they’re known as dictionaries), Perl, awk, and plenty of others. Another time period generally used to explain maps is associative arrays, which you’ll examine in this Wikipedia article. Java and Groovy maps are properly basic, allowing keys and values to be any lessons that stretch the Object
class.
Install Java and Groovy
Groovy is predicated on Java and requires a Java set up as effectively. Both a current and respectable model of Java and Groovy is perhaps in your Linux distribution’s repositories. Or, you possibly can set up Groovy following the directions on the hyperlink talked about above. A pleasant various for Linux customers is SDKMan, which you need to use to get a number of variations of Java, Groovy, and plenty of different associated instruments. For this text, I’m utilizing SDK’s releases of:
- Java: model 11.0.12-open of OpenJDK 11;
- Groovy: model 3.0.8.
Back to the issue
Java presents quite a few methods to instantiate and initialize maps, and since Java 9, a number of new approaches bought added. The most evident candidate is the static technique java.util.Map.of()
which you need to use as follows:
It seems that Map.of()
used on this style bears two essential restrictions. First, the map occasion you create this manner is immutable. Second, this manner you possibly can provide at most 20 arguments, representing ten key-value pairs.
Try including tenth and eleventh pairs, say “AG”, “Antigua and Barbuda”, and “AR”, “Argentina” to see what occurs. You’ll see the Java compiler on the lookout for a model of Map.of()
that accepts 11 pairs and fails.
A fast have a look at the documentation for java.util.Map exhibits the rationale for this second limitation, and exhibits a manner out of that conundrum:
var m2 = Map.ofEntries(
Map.entry("AF", "Afghanistan"),
Map.entry("AX", "Åland Islands"),
Map.entry("AL", "Albania"),
Map.entry("DZ", "Algeria"),
Map.entry("AS", "American Samoa"),
Map.entry("AD", "Andorra"),
Map.entry("AO", "Angola"),
Map.entry("AI", "Anguilla"),
Map.entry("AQ", "Antarctica"),
Map.entry("AG", "Antigua and Barbuda"),
Map.entry("AR", "Argentina"),
Map.entry("AM", "Armenia"),
Map.entry("AW", "Aruba"),
Map.entry("AU", "Australia"),
Map.entry("AT", "Austria"),
Map.entry("AZ", "Azerbaijan"),
Map.entry("BS", "Bahamas"),
Map.entry("BH", "Bahrain"),
Map.entry("BD", "Bangladesh"),
Map.entry("BB", "Barbados")
);
System.out.println("m2 = " + m2);
System.out.println("m2 is an instance of " + m2.getClass());
As lengthy as I don’t have to subsequently change the contents of the map created and initialized with Map.ofEntries()
, this can be a respectable resolution. Note above that slightly than utilizing Map.of()
as within the first instance, I used Map.ofEntries()
.
However, supposing I need to create and initialize a map occasion with some entries and later add to that map, I have to do one thing like this:
var m3 = new HashMap<String,String>(Map.ofEntries(
Map.entry("AF", "Afghanistan"),
Map.entry("AX", "Åland Islands"),
Map.entry("AL", "Albania"),
Map.entry("DZ", "Algeria"),
Map.entry("AS", "American Samoa"),
Map.entry("AD", "Andorra"),
Map.entry("AO", "Angola"),
Map.entry("AI", "Anguilla"),
Map.entry("AQ", "Antarctica"),
Map.entry("AG", "Antigua and Barbuda"),
Map.entry("AR", "Argentina"),
Map.entry("AM", "Armenia"),
Map.entry("AW", "Aruba"),
Map.entry("AU", "Australia"),
Map.entry("AT", "Austria"),
Map.entry("AZ", "Azerbaijan"),
Map.entry("BS", "Bahamas"),
Map.entry("BH", "Bahrain"),
Map.entry("BD", "Bangladesh"),
Map.entry("BB", "Barbados")
));System.out.println("m3 = " + m3);
System.out.println("m3 is an instance of " + m3.getClass());m3.put("BY", "Belarus");
System.out.println("BY: " + m3.get("BY"));
Here, by utilizing the immutable map created by Map.ofEntries()
as an argument to the HashMap
constructor, I create a mutable copy of it, which I can then alter—for instance, with the put()
technique.
Take a have a look at the Groovy model of the above:
def m1 = [
"AF": "Afghanistan",
"AX": "Åland Islands",
"AL": "Albania",
"DZ": "Algeria",
"AS": "American Samoa",
"AD": "Andorra",
"AO": "Angola",
"AI": "Anguilla",
"AQ": "Antarctica",
"AG": "Antigua and Barbuda",
"AR": "Argentina",
"AM": "Armenia",
"AW": "Aruba",
"AU": "Australia",
"AT": "Austria",
"AZ": "Azerbaijan",
"BS": "Bahamas",
"BH": "Bahrain",
"BD": "Bangladesh",
"BB": "Barbados"]println "m1 = $m1"
println "m1 is an instance of ${m1.getClass()}"m1["BY"] = "Belarus"
println "m1 = $m1"
At a look, you see Groovy makes use of the def
key phrase slightly than var
—though in late-model Groovy (model 3+), it’s attainable to make use of var
as an alternative.
You additionally see which you can create a map illustration by placing a listing of key-value pairs between brackets. Moreover, the listing occasion so created is kind of helpful for a few causes. First, it’s mutable, and second, it’s an occasion of LinkedHashMap
, which preserves the order of insertion. So while you run the Java model and print the variable m3
, you see:
m3 = {BB=Barbados, BD=Bangladesh, AD=Andorra, AF=Afghanistan, AG=Antigua and Barbuda, BH=Bahrain, AI=Anguilla, AL=Albania, AM=Armenia, AO=Angola, AQ=Antarctica, BS=Bahamas, AR=Argentina, AS=American Samoa, AT=Austria, AU=Australia, DZ=Algeria, AW=Aruba, AX=Åland Islands, AZ=Azerbaijan}
When you run the Groovy model, you see:
m1 = [AF:Afghanistan, AX:Åland Islands, AL:Albania, DZ:Algeria, AS:American Samoa, AD:Andorra, AO:Angola, AI:Anguilla, AQ:Antarctica, AG:Antigua and Barbuda, AR:Argentina, AM:Armenia, AW:Aruba, AU:Australia, AT:Austria, AZ:Azerbaijan, BS:Bahamas, BH:Bahrain, BD:Bangladesh, BB:Barbados]
Once once more, you see how Groovy simplifies the scenario. The syntax may be very easy, considerably paying homage to Python’s dictionaries, and no want to recollect the assorted contortions crucial when you have an preliminary listing longer than ten pairs. Note that we use the expression:
m1[“BY”] = “Belarus”
Rather than the Java:
m1.put(“BY”, “Belarus”)
Also, the map is by default mutable, which is arguably good or dangerous, relying on the wants. I believe what bothers me concerning the “immutable default” of the Java scenario is that there isn’t one thing like Map.mutableOfMutableEntries()
. This forces the programmer, who has simply discovered find out how to declare and initialize a map, to modify gears and take into consideration simply find out how to convert the immutable map they’ve into one thing mutable. I additionally type of marvel concerning the enterprise of making one thing immutable simply to throw it away.
Another factor to consider is the sq. brackets as key lookup works to switch each put()
and get()
in Java, so you possibly can write:
m1[“ZZ”] = m1[“BY”]
Instead of:
m1.put(“ZZ”,m1.get(“BY”))
Sometimes, it’s good to think about keys and their values in the identical manner you consider fields within the occasion of a category. Imagine you could have a bunch of properties you need to set: In Groovy, this might appear like:
def properties = [
verbose: true,
debug: false,
logging: false]
And then later you possibly can change it as:
properties.verbose = false
This works as a result of, so long as the important thing follows sure guidelines, you possibly can omit the quotes and use the dot operator as an alternative of sq. brackets. While this may be fairly helpful and nice, it additionally signifies that to make use of the worth of a variable as a key worth in a map illustration, you could enclose the variable in parentheses, like:
def myMap = [(k1): v1, (k2): v2]
This is an efficient second to remind the diligent reader that Groovy is especially well-suited to scripting. Often, maps are a key component in scripts, offering lookup tables and customarily functioning as an in-memory database. The instance I’ve used here’s a subset of the ISO 3166 two-character nation codes and nation names. The codes are acquainted to anybody who accesses web hostnames in nations all over the world, which might kind a helpful a part of a scripting utility that appears at web hostnames in log recordsdata to be taught concerning the geographic distribution of customers.
Groovy assets
The Apache Groovy site has numerous nice documentation. Another nice Groovy useful resource is Mr. Haki. The Baeldung site offers numerous helpful how-to in Java and Groovy. And a extremely nice purpose to be taught Groovy is to go on and be taught Grails, which is a splendidly productive full-stack internet framework constructed on prime of wonderful elements like Hibernate, Spring Boot, and Micronaut.