[JAVA] Write a null case using the Optional type without using an if statement

What is Optional (Philosophy)

Optional is a type that works on the premise that it may be null. By storing the object inside, you can write the behavior in the case of null separately. If you write the conclusion, you can write the ** "if" statement as a method chain. ** **

What's wrong with null in the first place

Well, in a word, "Nullpo" is a guy ...

In a little more detail, in object orientation, an object is a huge chunk of data that moves with many methods and fields.

If the variable of the object is null, when you call the method from that variable, you will access the unmaterialized method and get a ** NullPointerException **.

Therefore, it is necessary to rewrite the code largely depending on whether the object exists or does not exist.

When using if minutes

The if statement is a typical syntax that changes the behavior when it exists and when it does not exist. It's the basic of the basics of the program.

Now, when the A object exists, let's do something like get the value with the getDataWord () method of the B object.

foo.java


   ~
   String wantData = null;
   if(A_var != null){
      wantData = A_var.gethogeWord();
   } else if (B_var != null){
      wantData = B_var.getDataWord();
   } else {
     wantData = "There was neither(・_・`)") ;
   }
    System.out.println(wantData);
    ~

Is this a typical way of writing? Of course, don't forget the implicit ** A and B cases ** and ** A and B none **.

However, if statements are difficult to manage. In addition, it is easy to combine cases and cause an explosion, which makes it difficult to nest ifs.

Write this using Optional.

If you write this using an option, it will look like this.

foo.java


   ~
		String wantData = null;

		//Optional wrap value
		Optional<A_class> ObjA_opt = Optional.ofNullable(A_var);
		Optional<B_class> ObjB_opt = Optional.ofNullable(B_var);

		//Get the value.
		Optional<String>Hogeword_opt = ObjA_opt.map(A_var->  A_var.gethogeWord());
		Optional<String>DataWord_opt = ObjB_opt.map(B_var ->  B_var.getDataWord());

		//Substitution
		wantData = Hogeword_opt.orElseGet(() -> null);
		if(wantData == null){
			wantData =DataWord_opt .orElseGet(() -> null);

		}

        System.out.println(wantData);
    ~

It's hard to see the shit, and the "if" is coming out, which is the best. Let's explain the code before we get into it.

I'm using all optional methods. First, the **. Of Nullable () ** method. This wraps a variable that may be null into an Optional type. This time, we are declaring an Optional type that stores an object of type A_class.

Then the **. Map () ** method. Use a lambda expression to get a variable with the return value on the right wrapped in Optional. This time, I want the getter to return a string, so I'm using an Optional object that stores the String type.

Finally, the ** getElse () ** method. Here we are getting the value we put in the Optional object. To the right of the lambda expression is ** "value to assign when the value is null" **.

It should be noted here that the method of Optional type returns Optional type. In other words, ** can be made into one line in the method chain **.

Connect with Papa with a method chain, and it's awesome!

If you write this by connecting the method chain, it will be like this.

foo.java


   ~
		String wantData = null;

		wantData = Optional.ofNullable(A_var)		//Optional wrap value
				.map(A_var-> A_var.gethogeWord())//Method execution with the returned option
				.orElseGet(() -> null);//Get the value.

		wantData = Optional.ofNullable(B_var)		//Optional wrap value
				.map(B_var-> B_var.getDataWord())//Method execution with the returned option
				.orElseGet(() -> null);//Get the value.

       wantData =  Optional.ofNullable(wantData)
               .getElse(() -> "Neither was included.");

        System.out.println(wantData);
    ~

A technique that can be achieved because all return types are Optional. I think I've written a fairly clean code. It's more readable than an if statement, and I think it's easier to create similar conditions and add or change conditions.

I think that an if statement is fine for this, but I think that the effect will be understood if the conditions become more complicated.

I was able to write highly readable cases without using blocks.

Postscript 3/3

Yes, as commented, this will substitute the result of B regardless of the value of A. This is terrible. This is the code that works properly

foo.java


   ~
		String wantData = null;

        //Declare optional variables
		Optional<A_class> A_opt = Optional.ofNullable(A_var);
		Optional<B_class> B_opt = Optional.ofNullable(B_var);
	

		wantData =A_opt.map(haitteru_A ->  haitteru_A.gethogeWord())
							.orElseGet(() ->//Make lambda-style nesting!
							       cm_opt.map(haitteru_B -> haitteru_B.getDataWord())//Obtained by the method on the B object side
							      .orElseGet(() -> "No Password!") //Lambda expression execution again What is assigned when both are null
							);

        System.out.println(wantData);
    ~

The understanding of the lambda expression is also delicate, and the advanced version is unpleasant w I tried to make it, but ... in the end, it's inevitable that it will have a nest-like structure ...

One thing to note in this code is that the final value assigned to wantData must be of type Spring ** The .orElsGet () method works as a simple If statement on the right side of the lambda expression, and it even outputs it. ** Please note that a compiler error will occur if you enter Integer on the way **. You have to make a solid design around here.

Conclusion

Optional Let's use more. Make progress.

Recommended Posts

Write a null case using the Optional type without using an if statement
Duplicate an object using a generic type
Declare the model as an optional type
Write a third If statement that is neither an if statement nor a ternary operator
How to write an if statement to improve readability-java
Check if a string can be converted to an int without using Integer # parseInt
[Ruby] Get a 3-digit integer and conditionally branch using an if statement (digits method)
Find the remainder divided by 3 without using a number
null specifies the type
How to output array values without using a for statement
Let's understand the if statement!
What if I write a finally clause in the try-with-resources syntax?
Sidekiq's best practice, if you're using ActiveJob, that's not the case
The story of making a communication type Othello game using Scala.
Set up a Wordpress Docker environment without using the Worpdress image
[Java] You might be happy if the return value of a method that returns null is Optional <>