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
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Dust: Open-Source Actors for Java
  • Testcontainers With Kotlin and Spring Data R2DBC
  • High-Performance Java Serialization to Different Formats
  • Multithreading in Modern Java: Advanced Benefits and Best Practices

Trending

  • 5 AI Security Incidents That Broke Things in Production (and What They Have in Common)
  • Alternative Structured Concurrency
  • Every Cache Miss Is a Tiny Tax on Your Performance
  • Why Stable RAG Answers Can Still Hide Unstable Evidence
  1. DZone
  2. Coding
  3. Java
  4. Writing (Slightly) Cleaner Code With Collections and Optionals

Writing (Slightly) Cleaner Code With Collections and Optionals

See how utility methods provided by Kilo's Collections and Optionals classes can help you write more readable and maintainable Java code.

By 
Greg Brown user avatar
Greg Brown
·
Oct. 27, 25 · Analysis
Likes (1)
Comment
Save
Tweet
Share
2.7K Views

Join the DZone community and get the full member experience.

Join For Free

Kilo is an open-source project for creating and consuming RESTful and REST-like web services in Java. Among other things, it includes the Collections and Optionals classes, which are designed to help simplify code that depends on collection types and optional values, respectively. Both are discussed in more detail below.

Collections

Kilo’s Collections class provides a set of static utility methods for declaratively instantiating list, map, and set values:

Java
 
public static <E> List<E> listOf(E... elements) { ... }
public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entries) { ... }
public static <E> Set<E> setOf(E... elements) { ... }


They offer an alternative to similar methods defined by the List, Map, and Set interfaces, which return immutable instances and do not permit null values. The following immutable variants are provided as well:

Java
 
public static <E> List<E> immutableListOf(E... elements) { ... }
public static <K, V> Map<K, V> immutableMapOf(Map.Entry<K, V>... entries) { ... }
public static <E> Set<E> immutableSetOf(E... elements) { ... }


Map entries can be declared using the following method:

Java
 
public static <K, V> Map.Entry<K, V> entry(K key, V value) { ... }


Collectively, these methods represent a Java approximation of the “collection literal” syntax supported by languages like JavaScript and Swift. For example (in Swift, lists are called “arrays” and maps are called “dictionaries”):

Java
 
var array = [
    "one",
    "two",
    "three"
]

let immutableArray = [
    "four",
    "five",
    "six"
]


Java
 
var dictionary = [
    "a": 1,
    "b": 2,
    "c": 3
]

let immutableDictionary = [
    "d": 4,
    "e": 5,
    "f": 6
]


Using Collections, the code might look like this (the methods have been statically imported to reduce verbosity):

Java
 
var list = listOf(
    "one",
    "two",
    "three"
);

var immutableList = immutableListOf(
    "four",
    "five",
    "six"
);


Java
 
var map = mapOf(
    entry("a", 1),
    entry("b", 2),
    entry("c", 3)
);

var immutableMap = immutableMapOf(
    entry("d", 4),
    entry("e", 5),
    entry("f", 6)
);


It’s not quite as concise as the Swift version, but it is structurally and visually similar, making it easy to read, understand, and modify when needed. It also looks a lot like Kotlin, though the mutability options are reversed:

Java
 
val list = mutableListOf(
    "one",
    "two",
    "three"
)

val immutableList = listOf(
    "four",
    "five",
    "six"
)


Java
 
val map = mutableMapOf(
    "a" to 1,
    "b" to 2,
    "c" to 3
)

val immutableMap = mapOf(
    "d" to 4,
    "e" to 5,
    "f" to 6
)


Optionals

The Optionals class contains methods for working with optional (or “nullable”) values:

Java
 
public static <T> T coalesce(T value, Supplier<? extends T> supplier) { ... }
public static <T, U> U map(T value, Function<? super T, ? extends U> transform) { ... }


These are provided as a less verbose alternative to similar methods defined by the java.util.Optional class. They also represent an attempt to emulate some of the null safety features of Kotlin and Swift.

For example, the following Java code assigns a default value to a variable if the original value is null:

Java
 
Object a = null;

var b = a;

if (b == null) {
    b = 123;
}


Using Java’s Optional class, the code could be simplified as follows, reducing complexity and eliminating the variable reassignment:

Java
 
Object a = null;

var b = Optional.ofNullable(a).orElse(123);


However, this is still somewhat awkward and verbose. In Kotlin, the code could be written like this, using the null-coalescing Elvis operator:

Java
 
val a = null

val b = a ?: 123


Using the coalesce() method of Kilo’s Optionals class, it could be written as shown below:

Java
 
Object a = null;

var b = coalesce(a, () -> 123);


This is almost as simple as the Kotlin version. If a is not null, it is returned immediately. Otherwise, the provided supplier is invoked to produce the default value of 123.

Null-Safe Calls

Kotlin also provides a safe call operator designed to help avoid NullPointerExceptions. For example, the following Java code would throw when attempting to invoke the length()method on a:

Java
 
String a = null;

var b = a.length();


The code could be rewritten as follows to avoid the exception, at the cost of increased complexity and decreased readability:

Java
 
String a = null;

int b;
if (a != null) {
    b = a.length();
} else {
    b = 0;
}


In Kotlin, it can be reduced to the following:

Java
 
val a: String? = null

val b = a?.length ?: 0


When a is not null, the length property is accessed, and the return value is assigned to b. However, when a is null, length is not read, and the safe call operator returns null. The Elvis operator ensures that a non-null default value of 0 is assigned to b in this case.

Using Java’s Optional class, the code could be written like this:

Java
 
String a = null;

var b = Optional.ofNullable(a).map(String::length).orElse(0);


This is better than the original version, but it is still more awkward than necessary. Using Optionals, it could be written in a way that more closely resembles the Kotlin version:

Java
 
String a = null;

var b = coalesce(map(a, String::length), () -> 0);


Conclusion

Will Collections and Optionals drastically alter the way you write Java code? Probably not. But they can help make your code more modern, readable, and maintainable.

If you’re currently using Kilo, you already have access to these features. If not, you can easily adopt them by adding org.httprpc:kilo-client to your project dependencies.

For more information, see the project documentation.

Kotlin (programming language) Data Types Open source Java (programming language)

Published at DZone with permission of Greg Brown. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Dust: Open-Source Actors for Java
  • Testcontainers With Kotlin and Spring Data R2DBC
  • High-Performance Java Serialization to Different Formats
  • Multithreading in Modern Java: Advanced Benefits and Best Practices

Partner Resources

×

Comments

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

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

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 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook