DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Type Variance in Java and Kotlin
  • Using Python Libraries in Java
  • Why You Should Migrate Microservices From Java to Kotlin: Experience and Insights
  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing

Trending

  • Beyond Code Coverage: A Risk-Driven Revolution in Software Testing With Machine Learning
  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  • Agentic AI for Automated Application Security and Vulnerability Management
  • FIPS 140-3: The Security Standard That Protects Our Federal Data
  1. DZone
  2. Coding
  3. Languages
  4. Default Map Value

Default Map Value

Learn how to provide a default value when querying an absent key in a hash map in different programming languages including Java, Kotlin, Python, and more.

By 
Nicolas Fränkel user avatar
Nicolas Fränkel
DZone Core CORE ·
Aug. 16, 24 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
5.8K Views

Join the DZone community and get the full member experience.

Join For Free

In this post, I'll explain how to provide a default value when querying an absent key in a hash map in different programming languages.

Java

Let's start with Java, my first professional programming language.

In older versions, retrieving a value from a map required using the get() method:

Java
 
Map map = new HashMap();                                 //1
Object value = map.get(new Object());                    //2
if (value == null) {
    value = "default";                                   //3
}


  1. Initialize an empty map.
  2. Attempt to retrieve a non-existent key.
  3. Assign a default value if the key is absent.

With Java 1.8, the Map interface introduced a more concise way to handle absent keys:

Java
 
var map = new HashMap<Object, String>();
var value = map.getOrDefault(new Object(), "default");   //1


  1. Retrieve the value with a default in one step.

Kotlin

Kotlin provides several approaches to retrieve values from a map:

  • get() and getOrDefault() function just like their Java counterparts.
  • getValue() throws an exception if the key is missing.
  • getOrElse() accepts a lambda to provide a default value lazily.
Kotlin
 
val map = mapOf<Any, String>()
val default = map.getOrDefault("absent", "default")      //1
val lazyDefault = map.getOrElse("absent") { "default" }  //2


  1. Retrieve the default value.
  2. Lazily evaluate the default value.

Python

Python is less forgiving than Java when handling absent keys — it raises a KeyError:

Python
 
map = {}
value = map['absent']                                    #1


  1. Raises a KeyError

To avoid this, Python offers the get() method:

Python
 
map = {}
value = map.get('absent', 'default')                     #1


Alternatively, Python's collections.defaultdict allows setting a default for all absent keys:

Python
 
from collections import defaultdict
map = defaultdict(lambda: 'default')                     #1
value = map['absent']


  1. Automatically provide a default value for any absent key.

Ruby

Ruby's default behavior returns nil for absent keys:

Ruby
 
map = {}
value = map['absent']


For a default value, use the fetch method:

Ruby
 
map = {}
value = map.fetch('absent', 'default')                  #1


  1. Provide a default value for the absent key.

Ruby also supports a more flexible approach with closures:

Ruby
 
map = {}
value = map.fetch('absent') { |key| key }               #1


  1. Return the queried key instead of a constant.

Lua

My experience with Lua is relatively new, having picked it up for Apache APISIX. Let's start with Lua's map syntax:

Lua
 
map = {}                                                --1
map["a"] = "A"
map["b"] = "B"
map["c"] = "C"
for k, v in pairs(map) do                               --2
  print(k, v)                                           --3
end


  1. Initialize a new map.
  2. Iterate over key-value pairs.
  3. Print each key-value pair.

Fun fact: the syntax for tables is the same as for maps:

Lua
 
table = {}                                              --1
table[0] = "zero"
table[1] = "one"
table[2] = "two"
for k,v in ipairs(table) do                             --2
  print(k, v)                                           --3
end


  1. Initialize a new map
  2. Loop over the pairs of key values
  3. Print the following:

    1   one
    2   two


    Lua arrays start at index 0!

We can mix and match indices and keys. The syntax is similar, but there's no difference between a table and a map. Indeed, Lua calls the data structure a table:

Lua
 
something = {}                                              
something["a"] = "A"
something[1] = "one"
something["b"] = "B"
for k,v in pairs(something) do
  print(k, v)
end


The result is the following:

1	one
a	A
b	B


In Lua, absent keys return nil by default:

Lua
 
map = {}
value = map['absent']


To provide a default, Lua uses metatables and the __index metamethod:

Metatables allow us to change the behavior of a table. For instance, using metatables, we can define how Lua computes the expression a+b, where a and b are tables. Whenever Lua tries to add two tables, it checks whether either of them has a metatable and whether that metatable has an __add field. If Lua finds this field, it calls the corresponding value (the so-called metamethod, which should be a function) to compute the sum.

- Metatables and Metamethods

Each table in Lua may have its own metatable.

As I said earlier, when we access an absent field in a table, the result is nil. This is true, but it is not the whole truth. Such access triggers the interpreter to look for an __index metamethod: if there is no such method, as usually happens, then the access results in nil; otherwise, the metamethod will provide the result.

- The __index Metamethod

Here's how to use it:

Lua
 
table = {}                                              --1
mt = {}                                                 --2
setmetatable(table, mt)                                 --3
mt.__index = function (table, key)                      --4
  return key
end
default = table['absent']                               --5


  1. Create the table.
  2. Create a metatable.
  3. Associate the metatable with the table.
  4. Define the __index function to return the absent key.
  5. The __index function is called because the key is absent.

Summary

This post explored how to provide default values when querying absent keys across various programming languages. Here's a quick summary:

Programming language Per call Per map Static Lazy
  Scope Value
Java ❎ ❌ ❎ ❌
Kotlin ❎ ❌ ❎ ❎
Python ❎ ❎ ❌ ❎
Ruby ❎ ❌ ❎ ❎
Lua ❌ ❎ ❎ ❌
Ruby (programming language) Java (programming language) Kotlin (programming language) Lua (programming language) Python (language)

Published at DZone with permission of Nicolas Fränkel, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Type Variance in Java and Kotlin
  • Using Python Libraries in Java
  • Why You Should Migrate Microservices From Java to Kotlin: Experience and Insights
  • Be Punctual! Avoiding Kotlin’s lateinit In Spring Boot Testing

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!