Java 如何编写一个可以检查 null、empty 的通用 isEmpty 方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24591010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write a generic isEmpty method which can check for null, empty?
提问by john
I am writing a utility method which can check for empty and null string, or collection or an object or any general types -
我正在编写一个实用方法,它可以检查空字符串和空字符串、集合、对象或任何一般类型 -
public static boolean isEmpty(Object obj) {
if (obj == null)
return true;
if (obj instanceof Collection)
return ((Collection<?>) obj).size() == 0;
// is below line expensive?
final String s = String.valueOf(obj).trim();
return s.length() == 0 || s.equalsIgnoreCase("null");
}
How can I make my above method efficient, since above isEmpty
method will be called multiple times from the application which is very performance critical?
我怎样才能使我的上述方法有效,因为上述isEmpty
方法将从对性能非常关键的应用程序中多次调用?
I am suspecting below line will be expensive because of heavy toString methods and it will create temporary garbage as well that might cause GC and slow down the performance?
我怀疑由于大量的 toString 方法,下面的行会很昂贵,并且它还会创建临时垃圾,这可能会导致 GC 并降低性能?
final String s = String.valueOf(obj).trim();
Update:-
更新:-
I have separated isEmpty method for each type now. Below is what I got after simplifying the above isEmpty method.
我现在已经为每种类型分离了 isEmpty 方法。下面是我简化上面的 isEmpty 方法后得到的。
public static boolean isEmpty(Object obj) {
if (obj == null) {
return true;
}
return false;
}
public static boolean isEmpty(Collection<?> value) {
if (value == null || value.isEmpty()) {
return true;
}
return false;
}
public static boolean isEmpty(String value) {
if (value == null || value.isEmpty()) {
return true;
}
return false;
}
Update 2:-
更新 2:-
If I need to check for map null or empty, should I keep both collection isEmpty and Map isEmpty method both or Collection isEmpty method will be fine for that?
如果我需要检查地图是否为 null 或为空,我应该同时保留集合 isEmpty 和 Map isEmpty 方法还是集合 isEmpty 方法就可以了?
public static void main(String[] args) {
Map<String, String> hello = new HashMap<String, String>();
System.out.println(isEmpty(hello));
Map<String, HashMap<Integer, String>> primary = new HashMap<String, HashMap<Integer, String>>();
System.out.println(isEmpty(primary));
}
public static boolean isEmpty(Collection<?> value) {
return value == null || value.isEmpty();
}
public static boolean isEmpty(Map<?, ?> value) {
return value == null || value.isEmpty();
}
采纳答案by aioobe
This sounds like a bad design to me. Null is null, empty is empty, if it's a string it's a string, and so on. Don't try to jam everything up in one method. It's bad for maintainability and readability.
这对我来说听起来像是一个糟糕的设计。Null 为空,empty 为空,如果是字符串则是字符串,依此类推。不要试图用一种方法把所有事情都塞满。这对可维护性和可读性不利。
if (str == null || str.isEmpty())
...
and
和
if (coll == null || coll.isEmpty())
are both perfectly fine.
两者都很好。
Personally however, I try to never ever equate null
with an empty string or empty collection. I think it's a bad practice. A null
collection is no collection at all, an empty collection is in fact still a collection. You can avoid many if (coll == null)
checks by keeping a collection non-null. If you're worried about memory consumption, use use Collections.emptySet
et al.
然而,就我个人而言,我尝试永远不等同null
于空字符串或空集合。我认为这是一个不好的做法。一个null
集合根本就不是一个集合,一个空的集合实际上仍然是一个集合。您可以if (coll == null)
通过将集合保持为非空来避免多次检查。如果您担心内存消耗,请使用 useCollections.emptySet
等。
That being said, if you still want to go in this direction, I'd suggest you use plain method overloadingand create one isEmpty(Collection<?> coll)
and one isEmpty(String str)
to avoid instanceof and casting.
话虽如此,如果您仍然想朝这个方向发展,我建议您使用普通方法重载并创建一个isEmpty(Collection<?> coll)
和一个isEmpty(String str)
以避免 instanceof 和强制转换。
Regarding your edit:
关于您的编辑:
Don't do for instance
不要做例如
if (value == null || value.isEmpty()) {
return true;
}
return false;
just do
做就是了
return value == null || value.isEmpty();
回答by Steve Kuo
For collections, you'll want to use isEmpty()
instead of size()
. For some collection types (such as LinkedList), size() is more expensive than isEmpty().
对于集合,您需要使用isEmpty()
代替size()
。对于某些集合类型(例如 LinkedList),size() 比 isEmpty() 开销更大。
回答by aliteralmind
As I just wrote in my answerto your other question posted 30 minutes before this one, it is wasteful to check everything every time.
正如我刚刚在回答您在此之前 30 分钟发布的另一个问题中所写的那样,每次检查所有内容都是浪费。
However, these types of functions are still useful in some situations. Instead of using an "is-valid" function, however, I would implement it as a "crash-if-bad" function. Also note that this function is for collections only.
但是,这些类型的函数在某些情况下仍然有用。然而,我没有使用“is-valid”函数,而是将它实现为“crash-if-bad”函数。另请注意,此功能仅适用于集合。
An example use is
一个示例使用是
CrashIfCollection.badNullLength(coll, "coll", Null.BAD, 1);
Code:
代码:
import java.util.Arrays;
import java.util.Collection;
enum Null {OK, BAD};
public class CrashIfCollection {
public static final void main(String[] ignored) {
test(null);
test(Arrays.asList(new String[] {}));
test(Arrays.asList(new String[] {"one element"}));
}
private static final void test(Collection<?> to_test) {
System.out.println("Testing " + ((to_test == null) ? "null"
: Arrays.toString(to_test.toArray())));
try {
CrashIfCollection.badNullLength(to_test, "to_test", Null.BAD, 1);
} catch(Exception x) {
System.out.println(x);
}
}
public static final void badNullLength(Collection<?> coll, String coll_name, Null nullness, int min_len) {
try {
if(nullness == Null.OK) {
if(coll == null) {
return;
}
if(coll.size() < min_len) {
throw new IllegalArgumentException(coll_name + ".size() (" + coll.size() + ") is less than min_len (" + min_len + ")");
}
}
} catch(NullPointerException npx) {
if(nullness == null) {
throw new NullPointerException("nullness");
}
throw npx;
}
//Null.BAD
try {
if(coll.size() < min_len) {
throw new IllegalArgumentException(coll_name + ".size() (" + coll.size() + ") is less than min_len (" + min_len + ")");
}
} catch(NullPointerException npx) {
throw new NullPointerException(coll_name);
}
}
}
Output:
输出:
Testing null
java.lang.NullPointerException: to_test
Testing []
java.lang.IllegalArgumentException: to_test.size() (0) is less than min_len (1)
Testing [one element]
回答by DanO
I like to have a utility class in a common library that handles this. Note that we use the object's own isEmpty, length, or size methods (in that order) if the object has one (after determining the object isn't null). By making calls to this, one doesn't need to worry about NPEs anymore -- you make your calls to this and you are good-to-go -- if it's true, then your collection/map/etc isn't null and has something in it; if it's false, skip over the item (it's either null or empty by it's own account). The second method checks an array to see if it's null or empty, but doesn't check the contents. When you iterate over the array, you simply do a check, then iterate, and as you iterate, check each element.
我喜欢在处理这个的公共库中有一个实用程序类。请注意,如果对象有一个(在确定对象不为空之后),我们将使用对象自己的 isEmpty、length 或 size 方法(按此顺序)。通过调用它,人们不再需要担心 NPE——你调用它,你就可以开始了——如果它是真的,那么你的集合/地图/等不是空的,并且里面有东西;如果为 false,则跳过该项目(它自己的帐户为 null 或为空)。第二种方法检查数组以查看它是 null 还是空,但不检查内容。当您迭代数组时,您只需进行检查,然后进行迭代,并在迭代时检查每个元素。
/**
* Provides methods to perform input validation and boundary validation.
*/
public final class ValidationUtils {
/**
* Check to see if Object is empty or null.
*
* @param object
* The object to check
* @return boolean {@code true} iff the Object is null or determined to be empty (using methods that it provides --
* if it doesn't provide such methods, it's only empty if it's null)
*/
public static boolean isEmpty(@Nullable final Object object) {
if (object == null)
return true;
try {
// Try to use the object class's isEmpty method to check if we're empty, now that we know we're
// not NULL
final Method method = object.getClass().getMethod("isEmpty");
final Object result = method.invoke(object);
if (result instanceof Boolean)
return Boolean.class.cast(result).booleanValue();
} catch (@NotNull final NoSuchMethodException | InvocationTargetException | IllegalArgumentException
| IllegalAccessException | SecurityException ignored) {
// We couldn't invoke... let's go to the next common method
}
try {
// Try to use the object class's length method to check if we're empty, now that we know we're
// not NULL
final Method method = object.getClass().getMethod("length");
final Object result = method.invoke(object);
if (result instanceof Integer)
return Integer.class.cast(result).intValue() <= 0;
if (result instanceof Long)
return Long.class.cast(result).longValue() <= 0L;
} catch (@NotNull final NoSuchMethodException | InvocationTargetException | IllegalArgumentException
| IllegalAccessException | SecurityException ignored) {
// We couldn't invoke... let's go to the next common method
}
try {
// Try to use the object class's size method to check if we're empty, now that we know we're
// not NULL
final Method method = object.getClass().getMethod("size");
final Object result = method.invoke(object);
if (result instanceof Integer)
return Integer.class.cast(result).intValue() <= 0;
if (result instanceof Long)
return Long.class.cast(result).longValue() <= 0L;
} catch (@NotNull final NoSuchMethodException | InvocationTargetException | IllegalArgumentException
| IllegalAccessException | SecurityException ignored) {
// We couldn't invoke... but we're not null... treat it like an Object
}
// Let's treat it like an Object... we're not null, so we're not empty
return false;
}
/**
* Check to see if the array of Objects is empty or null.
*
* @param obj
* Object Array to check
* @return boolean true if empty
*/
public static boolean isEmpty(@Nullable final Object... obj) {
return ((obj == null) || (obj.length == 0));
}
}
Example uses:
示例用途:
final Map<String, String[]> postData = ServletActionContext.getRequest().getParameterMap();
// We're testing if the map is null or empty... we could just do a null check here because of how we're using the map after, but...
if (!ValidationUtils.isEmpty(postData)) {
for (final Map.Entry<String, String[]> reqKey : postData.entrySet()) {
// We're checking if the array is null or doesn't have any length; again, the foreach does the latter, but this is perfectly fine
if (!ValidationUtils.isEmpty(reqKey.getValue())) {
for (final String value : reqKey.getValue()) {
// Checking the value
if (ValidationUtils.isEmpty(value)) {
continue;
}
...
}
}
}
}
回答by Adan Vivero
You can try by doing this. If you have a size as a private integer. You could do the following:
您可以尝试这样做。如果你有一个私有整数的大小。您可以执行以下操作:
public boolean isEmpty()
{
if(size == 0)
{
return true;
}
else
{
return false;
}
}
This worked for me.
这对我有用。