You can't do it directly, you should provide your own way to check this. Eg.
class MyClass {
Object attr1, attr2, attr3;
public boolean isValid() {
return attr1 != null && attr2 != null && attr3 != null;
}
}
Or make all fields final and initialize them in constructors so that you can be sure that everything is initialized.
Answer from Jack on Stack OverflowYou can't do it directly, you should provide your own way to check this. Eg.
class MyClass {
Object attr1, attr2, attr3;
public boolean isValid() {
return attr1 != null && attr2 != null && attr3 != null;
}
}
Or make all fields final and initialize them in constructors so that you can be sure that everything is initialized.
import org.apache.commons.lang3.ObjectUtils;
if(ObjectUtils.isEmpty(yourObject)){
//your block here
}
Videos
Method overloading can make your implementations more efficient and cleaner:
public static boolean isEmpty(Collection obj) {
return obj == null || obj.isEmpty();
}
public static boolean isEmpty(String string) {
return string == null || string.trim().isEmpty();
}
public static boolean isEmpty(Object obj) {
return obj == null || obj.toString().trim().isEmpty();
}
The Collection version is as efficient as possible.
The String version would be more efficient without the trimming. It would be best to trim your strings as soon you see them, long before they reach this call. If you can review the callers and make sure that the strings are always trimmed at their origins, then you can remove .trim() for best performance.
The Object version can be inefficient, depending on the toString implementation of the objects that will be passed to it, and because of the trimming.
I removed the comparison with null from there, because it seems pointless to me. I mean, a class whose toString method says "null" would seem very very odd.
In any case, you don't really want the Object version to be called, at all. Most importantly because it probably won't even work. Take for example an empty Map. Its toString method returns the string {}, which won't match your conditions of emptiness. (For this type you should definitely add isEmpty(Map<?, ?> map) to benefit from its isEmpty method.)
If performance is so critical, then add more overloaded implementations for all other types that you care about, for example:
public static boolean isEmpty(Something obj) {
return obj == null || obj.isEmpty();
}
Finally, especially when something is so important, you definitely want to unit test it, for example:
@Test
public void testEmptyObject() {
assertTrue(isEmpty((Object) null));
assertFalse(isEmpty(new Object()));
}
@Test
public void testEmptyString() {
assertFalse(isEmpty("hello"));
assertTrue(isEmpty(""));
assertTrue(isEmpty(" "));
assertTrue(isEmpty((Object) null));
}
@Test
public void testEmptySet() {
assertFalse(isEmpty(new HashSet<String>(Arrays.asList("hello"))));
assertTrue(isEmpty(new HashSet<String>()));
}
@Test
public void testEmptyMap() {
Map<String, String> map = new HashMap<String, String>();
assertTrue(isEmpty(map));
map.put("hello", "hi");
assertFalse(isEmpty(map));
}
Don't.
I mean. Don't use the same method for all kinds of objects.
This method does not make much sense to me.
This line smells. A lot.
if (obj instanceof Collection)
return ((Collection<?>) obj).size() == 0;
Beware of instanceof operator.
I am sure that whatever it is that you are trying to do here, there are better ways to do it.
Java is a statically typed language, use the static types whenever possible. If you really don't know what type the object have, then I will provide another alternative below.
// is below line expensive?
final String s = String.valueOf(obj).trim();
That depends, on the implementation of the object's toString method.
The implementation of String.valueOf is:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
return s.length() == 0 || s.equalsIgnoreCase("null");
You have already checked for obj == null. The string will only be null when the object's toString method makes it so. And instead of s.length() == 0 you can use s.isEmpty() directly. (Although that is implemented as string length == 0
Do it differently
If possible, have the types of objects you're investigating implement an interface that provides an isEmpty method and let the object decide for itself if it is empty or not.
If that is not possible, you can use a dynamically created map with ways to determine whether or not the object is "empty".
Map<Class<?>, EmptyChecker> map = new HashMap<>();
map.put(String.class, new StringEmptyChecker());
map.put(Point.class, new PointEmptyChecker());
This is a kind of Strategy pattern.
Then to determine if an object is empty:
EmptyChecker checker = map.get(obj.getClass());
checker.isEmpty(obj);
The whole thing is kinda weird though, I can't really see a particular use-case for this kind of method.
I wanna add an object to an arrayList and it must have all the fields or else it will not be added.
For example, the fields i need are:
Class(String name, String date, String day)
If the name is null, the class would not be added to my arrayList. Is there a simpler way or do i have to check by:
if (class.name == null || class.date == null || day == null){ System.out.println(" please enter all details") }
^ not sure if class.name is the correct thing, tried it out on eclipse and it doesnt seem to work
You could use reflection, but I would not recommend using it unless absolutely necessary. You could use streams to make the check a bit more readable, something like
Stream.of(object.name, object.date)
.allMatch(Objects::nonNull);
I don't know where you are checking this, but i think this probably should be a method in your class, since this is validator type thingy, not responsibility of the place wherever you add your stuff to a list.
So something like:
public class SomeClass {
String name;
Date date;
public boolean hasAllDetailsEntered() {
return Stream.of(this.name, this.date)
.allMatch(Objects::nonNull);
}
}
Nah, you're doing something wrong. This is probably not necessary. What do you want to do?
A solution such as Option<T> is not a so bad idea. In fact, it has been successfully introduced in Haskell as a Maybe (but I don't know if this is the first time this solution has been used). Maybe monads are common in Haskell programs. Since, other languages have adopted the same system. For instance, Scala has an Option type.
If you don't want to become dependent of Guava, you could use Java 8, which introduces the Optional class.
However, Option/Maybe/… types are more relevant in a functional environment, because what you typically want to do is to get a behaviour/a property from the element if it really exists, and to get nothing or a default behaviour/property otherwise. So, a typical use of Options consists in
- applying a function A->B on the
Option[A]in order to get anOption[B]; - switching your code on the basis of the real content of the Option (for instance, by using Pattern matching if the language supports it and if Option has two subtypes, or by using method overload);
- or filtering the Options that represent (non-)existing elements.
As an alternative, you could use the Null Object Pattern, in which you have an abstract class MyClass and two concrete subclasses: MyRealClass and MyNullClass. You manipulate instances of MyClass, but generate instances of MyRealClass (if the element is really existing) or MyNullClass (if the element doesn't exist). MyNullClass contains the default behaviours/properties. If the null objects are stateless (which is typically the case), one could cache them, or even make them singletons.
This pattern is described in [Fowler].
[Fowler] Martin Fowler, Kent Beck, Refactoring: Improving the Design of Existing Code.
The whole point of a value object is that equality isn't based on identity; you could very well have two distinct blank objects. In fact, whether all blank objects are the same or different objects should be an implementation detail. For those reasons, the second approach is not good. If you look at the Java 8 APIs, there's a notion of a "value-based class" with the following properties:
- are final and immutable (though may contain references to mutable objects);
- have implementations of equals, hashCode, and toString which are computed solely from the instance's state and not from its identity or the state of any other object or variable;
- make no use of identity-sensitive operations such as reference equality (==) between instances, identity hash code of instances, or synchronization on an instances's intrinsic lock;
- are considered equal solely based on equals(), not based on reference equality (==);
- do not have accessible constructors, but are instead instantiated through factory methods which make no committment as to the identity of returned instances;
- are freely substitutable when equal, meaning that interchanging any two instances x and y that are equal according to equals() in any computation or method invocation should produce no visible change in behavior.
The documentation further adds:
A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly via reference equality or indirectly via an appeal to synchronization, identity hashing, serialization, or any other identity-sensitive mechanism. Use of such identity-sensitive operations on instances of value-based classes may have unpredictable effects and should be avoided.
There's no way to disable the == operator in Java so that warning is the best you can do.
Thus, your first approach is correct, with the caveat that foo1.equals(foo2) should always be true when foo1.isBlank() and foo2.isBlank() even if foo1 != foo2.