What should be the Java 8 equivalent of
if ( indicator != null ){
return getTest(a,indicator);
else{
return getTest(a);
}
if indicator is to be an Optional instead of nullable?
You can write:
Java
Optional<Boolean> indicator = ...;
return indicator.map(i -> getTest(a, i)).orElseGet(() -> getTest(a));
But not always is Optional better than simple null.
Probably provoking answer but the Java 8 version of :
if (indicator != null){
return getTest(a,indicator);
}
else{
return getTest(a);
}
is the same thing :
if (indicator != null){
return getTest(a,indicator);
}
else{
return getTest(a);
}
And in fact I would probably use that more terse way :
if (indicator != null){
return getTest(a,indicator);
}
return getTest(a);
In your case, using Optional with "chaining" methods such as :
return indicator.map(i -> getTest(a, i)).orElseGet(() -> getTest(a));
hides the flow logic while your actual code shows that perfectly: you have two distinct cases. In a general way, you want to chain processings/transformations but you don't want to chain forking scenarios since these are different scenarios.
If you want to use Optional to convey the fact that this object may be null, which is perfectly legitimate, I would probably do something that mimics the if-else logic that is clear :
Optional<Indicator> optIndicator = findIndicator();
if (indicator.isPresent()){
return getTest(a,indicator.get());
}
return getTest(a);
Simply you can write:
No time complexity and space.
Optional<Boolean> indicator = ...;
if(indicator.isPresent()) {
// value is present inside Optional
return getTest(a,indicator);
} else {
// value is absent
return getTest(a);
}
You could write it simply:
boolean indicator = ...;
return indicator ? getTest(a, i) : getTest(a);
Or
Optional<Boolean> indicator = ...;
return indicator.orElse(false) ? getTest(a, i) : getTest(a);
Related
I have this piece of code :
if (notificationSend.get(key) != null && notificationSend.get(key).equals(value)) {
return true;
} else {
notificationSend.put(key, value);
return false;
}
and I want to know if it is possible to refactor it using Jav8 Enhancements like compute() , computeIfPresent() or computeIfAbsent()
Assuming value is non-null, you don't need to use a conditional, or any of those compute* methods.
ValueType oldValue = map.put(key, value);
return value.equals(oldValue);
I have a code like this and when I am running it under sonar, it always complain on this line value.contains("true")
String value = getValue("/data/" + set, property);
if (!Strings.isNullOrEmpty(value)) {
if (value.contains("true")) {
return true;
} else {
return false;
}
} else {
return false;
}
Here is the message it is giving me: NullPointerException might be thrown as 'value' is nullable here
I am already checking value for null check just above then why it is complaining inside? Am I doing something wrong?
Update:
After Andy's suggestion. I rewrote something like this:
String value = getValue("/data/" + set, property);
if (value!=null) {
return Boolean.parseBoolean(value);
}
return false;
It's likely that sonar doesn't understand the semantics of Strings.isNullOrEmpty.
You can make it less confusing all round if you were to write the condition as:
if (value != null) {
It doesn't really matter if you call contains on an empty string.
Also, this:
if (value.contains("true")) {
return true;
} else {
return false;
}
is more easily written as
return value.contains("true");
Overall, you can write this as:
return value != null && value.contains("true");
Edit for your update: if you're using Boolean.parseBoolean, you don't even need the null check. parseBoolean returns false for a null input.
String value = getValue("/data/" + set, property);
return Boolean.parseBoolean(value);
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())
......