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())
......
Related
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);
}
Just for fun I wanted to try to implement a field by field, generic object comparator and this is what I did :
private Boolean isEqualFiedByField(Object o1, Object o2){
if (o1 == null || o2 == null || o1.getClass() != o2.getClass())
return false;
ObjectMapper mapper = new ObjectMapper();
Boolean result = true;
Map map1 = mapper.convertValue(o1, Map.class);
Map map2 = mapper.convertValue(o2, Map.class);
for (Object field : map1.keySet()) {
String fieldName = field.toString();
if (map1.get(fieldName) != null && map2.get(fieldName) != null)
result &= map1.get(fieldName).toString().equals(map2.get(fieldName).toString());
else
result &= (map2.get(fieldName) == map1.get(fieldName));
}
return result;
}
Is there anyway to improve this code ? Make it cleaner, faster or treat edges cases I forgot ?
Your current code uses ObjectMapper, you could also do this using reflection and not depend on any library. Not sure that's better, but something to consider.
I always put braces around blocks, even one-liners. You might later want to add a line to your if block and forget to add the braces.
You chose to handle the case with two null arguments by returning false. Is that a deliberate decision? You might want to put some JavaDoc on your method explaining this.
I think you could split your method into at least 3 parts, already indicated by empty lines in your current code. These parts do different things so could be handled in separate methods.
You are calling map1.get(fieldName) three times in your code (also map2). I would call it only once and assign the value to a local variable.
If you can get ObjectMapper (I don't know the class) to return a Map<String, Object> you can avoid all the toString calls later in the code.
i am sure this must have been asked before in different ways - as isEmptyOrNull is so common yet people implement it differently. but i have below curious query in terms of best available approach which is good for memory and performance both.
1) Below does not account for all spaces like in case of empty XML tag
return inputString==null || inputString.length()==0;
2) Below one takes care but trim can eat some performance + memory
return inputString==null || inputString.trim().length()==0;
3) Combining one and two can save some performance + memory (As Chris suggested in comments)
return inputString==null || inputString.trim().length()==0 || inputString.trim().length()==0;
4) Converted to pattern matcher (invoked only when string is non zero length)
private static final Pattern p = Pattern.compile("\\s+");
return inputString==null || inputString.length()==0 || p.matcher(inputString).matches();
5) Using libraries like -
Apache Commons (StringUtils.isBlank/isEmpty)
or Spring (StringUtils.isEmpty)
or Guava (Strings.isNullOrEmpty)
or any other option?
Useful method from Apache Commons:
org.apache.commons.lang.StringUtils.isBlank(String str)
https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html#isBlank(java.lang.String)
To detect if a string is null or empty, you can use the following without including any external dependencies on your project and still keeping your code simple/clean:
if(myString==null || myString.isEmpty()){
//do something
}
or if blank spaces need to be detected as well:
if(myString==null || myString.trim().isEmpty()){
//do something
}
you could easily wrap these into utility methods to be more concise since these are very common checks to make:
public final class StringUtils{
private StringUtils() { }
public static bool isNullOrEmpty(string s){
if(s==null || s.isEmpty()){
return true;
}
return false;
}
public static bool isNullOrWhiteSpace(string s){
if(s==null || s.trim().isEmpty()){
return true;
}
return false;
}
}
and then call these methods via:
if(StringUtils.isNullOrEmpty(myString)){...}
and
if(StringUtils.isNullOrWhiteSpace(myString)){...}
Just to show java 8's stance to remove null values.
String s = Optional.ofNullable(myString).orElse("");
if (s.trim().isEmpty()) {
...
}
Makes sense if you can use Optional<String>.
This one from Google Guava could check out "null and empty String" in the same time.
Strings.isNullOrEmpty("Your string.");
Add a dependency with Maven
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
with Gradle
dependencies {
compile 'com.google.guava:guava:20.0'
}
Haven't seen any fully-native solutions, so here's one:
return str == null || str.chars().allMatch(Character::isWhitespace);
Basically, use the native Character.isWhitespace() function. From there, you can achieve different levels of optimization, depending on how much it matters (I can assure you that in 99.99999% of use cases, no further optimization is necessary):
return str == null || str.length() == 0 || str.chars().allMatch(Character::isWhitespace);
Or, to be really optimal (but hecka ugly):
int len;
if (str == null || (len = str.length()) == 0) return true;
for (int i = 0; i < len; i++) {
if (!Character.isWhitespace(str.charAt(i))) return false;
}
return true;
One thing I like to do:
Optional<String> notBlank(String s) {
return s == null || s.chars().allMatch(Character::isWhitepace))
? Optional.empty()
: Optional.of(s);
}
...
notBlank(myStr).orElse("some default")
Apache Commons Lang has StringUtils.isEmpty(String str) method which returns true if argument is empty or null
springframework library Check whether the given String is empty.
f(StringUtils.isEmpty(str)) {
//.... String is blank or null
}
Optional.ofNullable(label)
.map(String::trim)
.map(string -> !label.isEmpty)
.orElse(false)
OR
TextUtils.isNotBlank(label);
the last solution will check if not null and trimm the str at the same time
In most of the cases, StringUtils.isBlank(str) from apache commons library would solve it. But if there is case, where input string being checked has null value within quotes, it fails to check such cases.
Take an example where I have an input object which was converted into string using String.valueOf(obj) API. In case obj reference is null, String.valueOf returns "null" instead of null.
When you attempt to use, StringUtils.isBlank("null"), API fails miserably, you may have to check for such use cases as well to make sure your validation is proper.
Simply and clearly:
if (str == null || str.trim().length() == 0) {
// str is empty
}
With the openJDK 11 you can use the internal validation to check if the String is null or just white spaces
import jdk.internal.joptsimple.internal.Strings;
...
String targetString;
if (Strings.isNullOrEmpty(tragetString)) {}
You can make use of Optional and Apache commons Stringutils library
Optional.ofNullable(StringUtils.noEmpty(string1)).orElse(string2);
here it will check if the string1 is not null and not empty else it will return string2
If you have to test more than one string in the same validation, you can do something like this:
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class StringHelper {
public static Boolean hasBlank(String ... strings) {
Predicate<String> isBlank = s -> s == null || s.trim().isEmpty();
return Optional
.ofNullable(strings)
.map(Stream::of)
.map(stream -> stream.anyMatch(isBlank))
.orElse(false);
}
}
So, you can use this like StringHelper.hasBlank("Hello", null, "", " ") or StringHelper.hasBlank("Hello") in a generic form.
We can make use of below
Optional.ofNullable(result).filter(res -> StringUtils.isNotEmpty(res))
.ifPresent( s-> val.set(s));
I have the following:
fruitMap.remove(fruitId, fruitProperties);
The fruitMap is:
private Map<FruitId, FruitProperties> fruitMap = new HashMap<FruitId, FruitProperties>();
When I attempt to build my code I get a:
ERROR
The method remove(Object) in the type Map<MyImplementation.FruitId, FruitProperties>
is not applicable for the arguments (Map<MyImplementation.FruitId, FruitProperties>)
What is the issue?
Note that thiis call is inside of a method "removeFruit()" inside my "FruitImplementation" class.
From the Javadocs:
The default implementation is equivalent to, for this map:
if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.remove(key);
return true;
} else
return false;
The default implementation makes no guarantees about synchronization or atomicity properties of this method. Any implementation providing atomicity guarantees must override this method and document its concurrency properties.
So you could use that default implementation. Put it in a static helper method maybe.
But if this is supposed to be thread-safe, you may need to add some synchronization code (or consider using a ConcurrentMap, which by the way already has the remove method since Java 5).
The remove(key, value) method removes the entry for key if it is currently mapped to value. The method was added in Java 1.8. The Javadoc for the Map interface mentions the following default implementation:
if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.put(key, newValue);
return true;
} else
return false;
Since the Objects class was only added in Java 1.7, for Java 1.6 you have to write the equality test yourself. So, if you don't need the return value of the method, you can replace map.remove(key, value) with:
if (map.containsKey(key) {
Object storedValue = map.get(key);
if (storedValue == null ? value == null : storedValue.equals(value)) {
map.remove(key);
}
}
Note that this is not thread-safe. If you access the map from multiple threads, you will have to add a synchronized block.
You'll have to test the value yourself:
if(fruitProperties.equals(fruitMap.get(fruitId)) {
fruitMap.remove(fruitId);
}
Note, my implementation here assumes you are testing a non-null fruitProperties object.
You need to do the following assuming your values cannot be null
if (fruitProperties.equals(fruitMap.get(fruitId))
fruitMap.remove(fruitId);
Note: for this to be thread safe you would need to wrap this in a synchronized block.
Here is complete solution, handling synchronization and specific cases like null values.
synchronized (fruitMap)
{
if ((fruitMap.containsKey(fruitId) // The key is present
&& (
(fruitProperties == null && fruitMap.get(fruitId) == null) // fruitProperties is null, so is the stored value
|| (fruitProperties != null && fruitProperties.equals(fruitMap.get(fruitId)))
)
)
{
fruitMap.remove(fruitId);
}
}
It works in Java 6, it's an equivalent to :
fruitMap.remove(fruitId, fruitProperties);
Objects.equals has an implementation like this :
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
Therefore, the default implementation of remove :
if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.remove(key);
return true;
} else
return false;
Can be written in Java 6 as :
if (map.containsKey(key) && ((map.get(key) == value) || (map.get(key) != null && map.get(key).equals(value)))) {
map.remove(key);
return true;
} else
return false;
As per the Java Doc, remove(Object key, Object value)
Removes the entry for the specified key only if it is currently mapped
to the specified value.
If your equals() is properly defined, you can do something like this
FruitProperties valueFromMap = map.get(key);
if(valueFromMap != null){
if( valueFromMap == originalValue || valueFromMap.equals(originalValue)){
map.remove(key);
}
}
Now that you're using simple HashMap, I assume that you'll take care of thread-safety by either synchronizing or change it to ConcurrentHashMap :)
Is it possible to wrap following code in a reusable function?
EDIT: this is just an example, I want a working solution for ALL recursion depths
what I want is that following code is generated:
if (MyObject o == null ||
o.getSubObject() == null ||
o..getSubObject().getSubSubObject() == null /*||
... */)
return defaultValue;
return o.getSubObject().getSubObject()/*...*/.getDesiredValue();
by calling something like
Object defaultValue = null;
Object result = NullSafeCall(o.getSubObject().getSubObject()/*...*/.getDesiredValue(), defaultValue);
The seond code block is just an idea, I don't care how it looks like, all I want is that I, if desired, can avoid all the null checks before calling a deeper function...
Injection could do this propably, but is there no other/easier solution? Never looked at injection before yet...
EDIT2: example in another language: http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator
Not really, any code you would write this way would look horrible and/or use very slow reflection. Unless you use an actual Java preprocessor that can understand and change the code you've written.
A better (but associated with quite a bit of refactoring) approach would be to make sure that the values in question cannot possibly be null. For example, you could modify the individual accessors (getSubObject(), getDesiredValue()) to never return null in the first place: make them return default values. The accessors on the default values return default values in turn.
Java8 helps to get the closest you'll get to your syntax with decent performance I suspect;
// Evaluate with default 5 if anything returns null.
int result = Optional.eval(5, o, x->x.getSubObject(), x->x.getDesiredValue());
This can be done with this utility class;
class Optional {
public static <T, Tdef, T1> Tdef eval(Tdef def, T input, Function<T,T1> fn1,
Function<T1, Tdef> fn2)
{
if(input == null) return def;
T1 res1 = fn1.apply(input);
if(res1 == null) return def;
return fn2.apply(res1);
}
}
Sadly, you'll need a separate eval() defined per number of method calls in the chain, so you may want to define a few, but compile time type safe and reusable with just about any calls/types.
You can do something like this
public static Object NullSafeCall(MyObject o,Object defaultValue){
if ( o == null || o.getSubObject() == null)
{
return defaultValue;
}
else
{
return o.getSubObject().getDesiredValue();
}
}
Now you can call this method as follows
Object result = NullSafeCall(o, defaultValue);
i would suggest just replace
Object result = NullSafeCall(o.getSubObject().getDesiredValue(), defaultValue);
by the
Object result = (o == null || o.subObject == null) ? defaultVlue : o.getSubObject().getDesiredValue();
Create method only if you can reuse it......
What you want is not possible. It is essential to understand that using this syntax: Object result = NullSafeCall(o.getSubObject().getSubObject() ...); the part of o.getSubObject().getSubObject() will be evaluated before any control passes to the function/method thus throwing the exception.
It is required to have some type of context before executing such code. The closest to this I could think of, can be done using anonymous inner classes like the example below:
// intended to be implemented by an anonymous inner class
interface NullSafeOperation<T> {
public T executeSafely();
};
// our executor that executes operations safely
public static class NullSafeExecutor<T> {
public NullSafeExecutor() {}
public T execute(T defaultValue, NullSafeOperation<T> nso) {
T result = defaultValue;
try {
result = nso.executeSafely();
} catch(NullPointerException e) {
// ignore
}
return result;
}
// utility method to create a new instance and execute in one step
public static <T> T executeOperation(T defaultValue, NullSafeOperation<T> nso) {
NullSafeExecutor<T> e = new NullSafeExecutor<T>();
T result = e.execute(defaultValue, nso);
return result;
}
}
public static void main(String[] args) {
final String aNullString = null;
String result = NullSafeExecutor.executeOperation("MyDefault", new NullSafeOperation<String>() {
#Override
public String executeSafely() {
// trying to call a method on a null string
// it will throw NullPointerException but it will be catched by the executor
return aNullString.trim();
}
});
System.out.println("Output = " + result); // prints: Output = MyDefault
}