I want to re-write my null checking code, and use Optional instead.
public BySelector select(BySelector bySelector, Boolean value) {
return (bySelector == null) ? By.checkable(value) : bySelector.checkable(value);
}
The above is my original code. I have no idea how to replace to Optional. I've tried the following but it is not working. Please advise. Thank you.
public BySelector select(BySelector bySelector, Boolean value) {
return Optional.ofNullable(bySelector.checkable(value).orElse(By.checkable(value);
}
There is no need to use Optional in your case as it is less clear than your simple null check, but this is how I would do :
Optional.ofNullable(bySelector)
.map(x -> By.checkable(value))
.orElse(BySelector.checkable(value));
Maybe you want your method to return an optional, which makes more sense.
Related
One of the best things about Optional is it saves all the boilerplate checking for null values in a long chain:
Optional.ofNullable(myService.getSomething())
.map(secondService::fetch)
.map(thirdService::fetchAgain)
// And so forth...
At any point the Optional will jump onto the 'empty' track if map returns a null.
It would be great if something similar could be done for Strings instead of having to check them for String::isEmpty every time:
Optional.ofNullable(entity.getName())
.filter(String::isEmpty)
.map(Utils::performSomeOperation)
.filter(String::isEmpty)
.or(service::getMostCommonName)
.filter(String::isEmpty)
.orElse("Bob");
Something like this:
OptionalString.ofEmptyable(entity.getName())
.map(Utils::performSomeOperation)
.or(service::getMostCommonName)
.orElse("Bob");
The key logic in Optional happens in ofNullable when it calls its check for value == null. Theoretically you could apply any sort of logic in there:
MagicalOptionalString(StringUtils::isNotBlank).ofEmptyable(entity.getName())
.map(Utils::performSomeOperation)
.or(service::getMostCommonName)
.orElse("Bob");
However, Optional is final, preventing any straightforward way of extending this behaviour. So is there an existing, robust implementation of this out there already?
Trying out a few things to resolve what you were aiming at, and realizing that I would second the thought from VGR as implementing such a use case is a lot of extra work as compared to using the existing methods.
Yet, few details that I could add to after spending some time looking over the implementations -
As a utility, you could implement a static implementation which verifies for both null and isEmpty condition for a string input and returns Optional accordingly. The code could look something like -
private static Optional<String> ofEmptyable(String string) {
return isNullOrEmpty(string) ? Optional.empty() : Optional.of(string);
}
private static boolean isNullOrEmpty(String target) {
return target == null || target.isEmpty();
}
this could then replace the usage of the ofNullable which specifically checks for null(the primary purpose of Optional).
Since the expectations in your problem statement were to actually handle the cases per method(map/or/orElse) call as in the optional, one approach similar to OptionalInt could be to implement a custom OptionalString as -
public final class OptionalString {
private static final OptionalString EMPTY = new OptionalString();
private final boolean isPresent;
private final String value;
private OptionalString() {
this.isPresent = false;
this.value = "";
}
private static OptionalString empty() {
return EMPTY;
}
private boolean isPresent() {
return isPresent;
}
private OptionalString(String value) {
this.isPresent = true;
this.value = value;
}
public static OptionalString of(String value) {
return value == null || value.isEmpty() ? OptionalString.empty() : new OptionalString(value);
}
public OptionalString map(Function<? super String, ? extends String> mapper) {
return !isPresent() ? OptionalString.empty() : OptionalString.of(mapper.apply(this.value));
}
public OptionalString or(Supplier<String> supplier) {
return isPresent() ? this : OptionalString.of(supplier.get());
}
String orElse(String other) {
return isPresent ? value : other;
}
public String getAsString() {
return Optional.of(value).orElseThrow(() -> new NoSuchElementException("No value present"));
}
}
which could be further implemented for your use case in the following manner -
String customImpl = OptionalString.of(entity.getName())
.map(OptionalStringTest::trimWhiteSpaces) // OptionalStringTest is my test class name where 'trimWhiteSpaces' operation on String resides
.or(service::getMostCommonName)
.orElse("learning");
System.out.println(String.format("custom implementation - %s", customImpl));
where
private static String trimWhiteSpaces(String x) {
return x.trim();
}
Note - Honestly, I couldn't find the rationale behind not having an OptionalString class upfront in the JDK (the reason why I am stating this is because I suspect there definitely must have been a thought behind it), I believe its just that the radius of my reach is much smaller and I would expect someone credible to add to the details here. IMHO, it seems more like almost all of what you desire is right there using the Optional<String> and which takes us back to the starting of the loop.
For anyone working in Kotlin, this is really easy to do:
class NonEmptyString private constructor(val Email: String) {
companion object Factory {
operator fun invoke(value: String?): T? = value?.let { if (it.isNotEmpty()) NonEmptyString(value) else null }
}
}
The "static" invoke function conditionally creates a new object depending on whether it's valid or not. And allows you to call it like a constructor (NonEmptyString(value)). The private constructor forces you to use the invoke method.
Because this returns a null if it's not valid, and Kotlin has null-safety built in, it can be really easy to chain. Adding map or flatMap functions is then pretty straight-forward.
See this Code Review question for a more comprehensive, generalisable example I wrote.
I have a piece of code which returns value of one field, but also initializes it:
public Observable<Integer> asObservable() {
if (subject == null) {
subject = BehaviorSubject.createDefault(0);
}
return subject;
}
I'm trying to use Optional class to avoid if statement:
public Observable<Integer> asObservableWithOptional() {
Optional.ofNullable(subject)
.executeIfAbsent(() -> BehaviorSubject.createDefault(0));
return subject;
}
Hovewer I'm still not happy with this code. Is there a way to turn this methos into one with one statement only? Something similar to following won't work because subject have not been initialized during call to ofNullable factory method:
return Optional.ofNullable(subject)
.executeIfAbsent(() -> BehaviorSubject.createDefault(0))
.get();
Note: I'm not using original Java8 API, but aNNiMON port of this API https://github.com/aNNiMON/Lightweight-Stream-API.
How about
return subject = Optional.ofNullable(subject).orElseGet(() -> BehaviorSubject.createDefault(0));
of course, you can use a ternary conditional operator instead of creating an Optional just to discard it immediately:
return subject != null ? subject : (subject = BehaviorSubject.createDefault(0));
I would suggest something like this :
return (subject == null ? (subject = BehaviorSubject.createDefault(0)) : subject);
How can I use the Java Optional API to rewrite following code in a more elegant way:
first == null || second == null ? null : first + second;
The code should return null if any of the two variables is null or their sum elsewhere.
I can understand maybe you start to learn how to operate the Optional. How about this?
String result =
Optional.ofNullable(first)
// v--- the trick is use the `flatMap` here.
.flatMap(left -> Optional.ofNullable(second).map(right-> left + right))
.orElse(null);
If you are taking in nulls and returning nulls, then using Optional isn't very useful. You can wrap your code in Optional, but it will look just like your normal null checking code with some extra junk hanging around. Using Optional just to check for nulls is still just checking for nulls. If you rewrite your whole method to be fully Optional aware, you get something like the following:
public Optional<Integer> add(Optional<Integer> first, Optional<Integer> second)
{
return first.flatMap(left -> second.map(right -> left + right))
}
Notice how, by making full use of the Optional interface, you no longer need to worry about special processing for null. Additionally, if someone calls your method, the return type is much more specific about what happens on null/empty input.
If the input is out of your control, as you indicated in the comments, you can wrap it in an Optional using Optional.ofNullable, and then proceed. If both your input and output return type are fixed, then as nice as Optional is, you just don't have a good use for it.
If we stick to your requirement:
The code should return null if any of the two variables is null or their sum elsewhere.
Then you shouldn't use Optional at all. It will only make your code less readable and harder to maintain.
The true power of Optional doesn't reside in its elegance to avoid null-checks (nor in it's tempting potential to chain methods), but on its expressiveness to encapsulate either a present or an absent value. The best way to use it is as the return value of methods.
In your example, as you are saying that the method should return null if either operand is null, you are not taking advantage of Optional's potential. On the other hand, if you had a method that returned Optional (either empty or with the sum), you would be using it as expected:
public Optional<Integer> firstPlusSecond() {
Optional<Integer> a = Optional.ofNullable(first);
Optional<Integer> b = Optional.ofNullable(second);
if (!a.isPresent() || !b.isPresent()) {
return Optional.empty();
}
return Optional.of(a.get() + b.get());
}
This would in fact clearly express your intention, which is that the returned Optional is either empty (in case one operand is null) or holds the result of first + second.
It would be even better if you had optional getters for both first and second:
public Optional<Integer> first() {
return Optional.ofNullable(first);
}
public Optional<Integer> second() {
return Optional.ofNullable(second);
}
This way, the firstPlusSecond() method above would now turn to:
public Optional<Integer> firstPlusSecond() {
Optional<Integer> a = first();
Optional<Integer> b = second();
if (!a.isPresent() || !b.isPresent()) {
return Optional.empty();
}
return Optional.of(a.get() + b.get());
}
Which, IMO, is much better code.
Or even nicer, as suggested by #holi-java in the comments:
public Optional<Integer> firstPlusSecond() {
Optional<Integer> a = first();
Optional<Integer> b = second();
return a.isPresent() && b.isPresent() ?
Optional.of(a.get() + b.get()) :
Optional.empty();
}
Or, as again suggested by #holi-java, if you don't want to create optional getters for first and second, but still want to return an Optional, you might do it as follows:
public Optional<Integer> firstPlusSecond() {
return first != null && second != null ?
Optional.of(first + second) :
Optional.empty();
}
This is my solution using java stream
private Integer sum(Integer ...additions) {
return Arrays.stream(additions).filter(Objects::nonNull).reduce(0, Integer::sum);
}
I want to verify whether a collection is empty and null. Could anyone please let me know the best practice.
Currently, I am checking as below:
if (null == sampleMap || sampleMap.isEmpty()) {
// do something
}
else {
// do something else
}
If you use the Apache Commons Collections library in your project, you may use the CollectionUtils.isEmpty(...) and MapUtils.isEmpty(...) methods which respectively check if a collection or a map is empty or null (i.e. they are "null-safe").
The code behind these methods is more or less what user #icza has written in his answer.
Regardless of what you do, remember that the less code you write, the less code you need to test as the complexity of your code decreases.
That is the best way to check it. You could write a helper method to do it:
public static boolean isNullOrEmpty( final Collection< ? > c ) {
return c == null || c.isEmpty();
}
public static boolean isNullOrEmpty( final Map< ?, ? > m ) {
return m == null || m.isEmpty();
}
If you use Spring frameworks, then you can use CollectionUtils to check against both Collections (List, Array) and Map etc.
if(CollectionUtils.isEmpty(...)) {...}
When you use spring then you can use
boolean isNullOrEmpty = org.springframework.util.ObjectUtils.isEmpty(obj);
where obj is any [map,collection,array,aything...]
otherwise: the code is:
public static boolean isEmpty(Object[] array) {
return (array == null || array.length == 0);
}
public static boolean isEmpty(Object obj) {
if (obj == null) {
return true;
}
if (obj.getClass().isArray()) {
return Array.getLength(obj) == 0;
}
if (obj instanceof CharSequence) {
return ((CharSequence) obj).length() == 0;
}
if (obj instanceof Collection) {
return ((Collection) obj).isEmpty();
}
if (obj instanceof Map) {
return ((Map) obj).isEmpty();
}
// else
return false;
}
for String best is:
boolean isNullOrEmpty = (str==null || str.trim().isEmpty());
Personally, I prefer to use empty collections instead of null and have the algorithms work in a way that for the algorithm it does not matter if the collection is empty or not.
We'll check a Collection object is empty, null or not. these all methods which are given below, are present in org.apache.commons.collections4.CollectionUtils package.
Check on List or set type of collection Objects.
CollectionUtils.isEmpty(listObject);
CollectionUtils.isNotEmpty(listObject);
Check on Map type of Objects.
MapUtils.isEmpty(mapObject);
MapUtils.isNotEmpty(mapObject);
The return type of all methods is boolean.
You can use org.apache.commons.lang.Validate's "notEmpty" method:
Validate.notEmpty(myCollection) -> Validate that the specified argument collection is neither null nor a size of zero (no elements); otherwise throwing an exception.
If you need to check for null, that is the way. However, if you have control on this, just return empty collection, whenever you can, and check only for empty later on.
This thread is about the same thing with C#, but the principles applies equally well to java. Like mentioned there, null should be returned only if
null might mean something more specific;
your API (contract) might force you to return null.
For all the collections including map use: isEmpty method which is there on these collection objects. But you have to do a null check before:
Map<String, String> map;
........
if(map!=null && !map.isEmpty())
......
So I'm not going for maintainability or elegance here.. looking for a way to cut down on the total tokens in a method just for fun. The method is comprised of a long nested if-else construct and I've found that (I think) the way to do it with the fewest tokens is the ternary operator. Essentially, I translate this:
String method(param) {
if (param == null)
return error0;
else if (param.equals(foo1))
if (condition)
return bar1;
else
return error1;
else if (param.equals(foo2))
if (condition)
return bar2;
else
return error1;
...
else
return error;
}
to this:
String method(param) {
return
param == null ?
error0 :
param.equals(foo1) ?
condition ?
bar1 :
error1 :
param.equals(foo2) ?
condition ?
bar2 :
error2 :
...
error
}
However, there are a couple cases where in addition to returning a value I also want to change a field or call a method; e.g.,
else if (param.equals(foo3))
if (condition) {
field = value;
return bar3;
}
else
return error3;
What would be the cheapest way to do this token-wise? What I'm doing now is ugly but doesn't waste too many tokens (here the field is a String):
param.equals(foo3) && (field = value) instanceOf String ?
condition ?
bar2 :
error2 :
Again, the point is not good coding, I'm just looking for hacks to decrease the token count. If there's a shorter way to write the entire thing I'm open to that as well. Thanks for any suggestions.
Edit: Each word and punctuation mark counts as one token. So, for example, "instanceOf String" is two tokens, but "!= null" is three. The main things I can see for possible improvement are the "&&" and the parentheses. Is there a way to put "field = value" somewhere besides the conditional, and if not is there a construct that makes "field = value" a boolean without the need for parentheses?
(field = value) instanceof String
Assuming that it already satisfies your needs (and it thus includes returning false when value is null), a shorter alternative would then have been
(field = value) != null
Or if you actually overlooked that and want to make null return true as well, then use
(field = value) == value
This can be made much shorter if you use 1-letter variable names.
Further I don't see other ways and I agree with most of us that this all is somewhat nasty ;)
if param is null, return 0
Then make a case/switch/select statement on the parameter. That's clean .