Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Immutable Data Structures in Java

DZone's Guide to

Immutable Data Structures in Java

A lesson in how you need to regularly challenge the way you think about code, rather than letting old habits take over.

· Java Zone
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

Before we are software developers, we are people – and thus creatures of habits. It’s hard for someone to change one’s own habits, it’s harder for someone to change someone else’s habits – and for some of us, it’s even harder.

This, week, during a code review, I stumbled upon this kind of structure:

public class MyStructure {
  private String myProp1;
  private String myProp2;
  // A bunch of other String properties
  public MyStructure(String myProp1, String myProp2 /* All other properties here */) {
    
  private this.myProp1 = myProp1;
   
  private this.myProp1 = myProp1;
    // All other properties set there
 }
  
 public String getMyProp1() { ... }
 public String getMyProp2() { ... }
 // All other getters
 public void setMyProp1(String myProp1) { ... }
 public void setMyProp2(String myProp2) { ... }
 // All other setters
}

Note: it seems like a JavaBean, but it’s not because there’s no no-argument constructor.

Looking at the code, I see that setters are never used in our code, making it a nice use-case for an immutable data structure – and saving a good number of lines of code:

public class MyStructure {

 private final String myProp1;
 private final String myProp2;
 // A bunch of other String properties

 public MyStructure(String myProp1, String myProp2 /* All other properties here */) {
 this.myProp1 = myProp1;
 this.myProp1 = myProp1;
 // All other properties set there
 }

 public String getMyProp1() { ... }
 public String getMyProp2() { ... }
 // All other getters
}

At this point, one realizes String are themselves immutable, which leads to the second proposal, which again save more lines of code:

public class MyStructure {

 public final String myProp1;
 public final String myProp2;
 // A bunch of other String properties

 public MyStructure(String myProp1, String myProp2 /* All other properties here */) {
 this.myProp1 = myProp1;
 this.myProp1 = myProp1;
 // All other properties set there
 }
}

Given that attributes are final and that Java Strings are immutable, the class still safe against unwanted changes. Note that it works only because Strings are immutable by definition in Java. With a Date property, it wouldn’t work as Dates are mutable.

The same can be done with stateless services, with embedded services that needs to be accessed from children classes. There’s no need to have a getter:

public class MyService {

 // Can be accessed from children classes
 protected final EmbeddedService anotherService;

 public MyService(EmbeddedService anotherService) {
 this.anotherService = anotherService;
 }
}

Note: This approach is 100% compatible with for Dependency Injections, either Spring or CDI.

Now, you cannot imagine the amount of back and forth comments this simple review caused. Why? Because even if that makes sense from a coding point of view, it’s completely different from what we usually do.

In that case, laziness and IDEs don’t serve us well. The latter make it too easy to create accessors. I’m pretty sure if we had to code getters and setters by hand, the above proposals would be more in favor.

This post could easily have been titled “Don’t let habits get the best of you”. The lesson here is to regularly challenge how you code, even for simple easy stuff. There might be better alternatives after all.

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

Topics:
java ,data structures

Published at DZone with permission of Nicolas Frankel, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}