Java 如何编写一个可以检查null和empty的泛型isEmpty方法?
我正在编写一个实用程序方法,它可以检查空字符串和空字符串、集合、对象或任何常规类型-Java 如何编写一个可以检查null和empty的泛型isEmpty方法?,java,performance,string,null-check,Java,Performance,String,Null Check,我正在编写一个实用程序方法,它可以检查空字符串和空字符串、集合、对象或任何常规类型- public static boolean isEmpty(Object obj) { if (obj == null) return true; if (obj instanceof Collection) return ((Collection<?>) obj).size() == 0; // is below line expensiv
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");
}
更新:-
现在,我已经为每种类型分离了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;
}
public静态布尔值为空(objectobj){
if(obj==null){
返回true;
}
返回false;
}
公共静态布尔值isEmpty(集合值){
if(value==null | | value.isEmpty()){
返回true;
}
返回false;
}
公共静态布尔值为空(字符串值){
if(value==null | | value.isEmpty()){
返回true;
}
返回false;
}
更新2:-
如果我需要检查map null或empty,我应该同时保留collection-isEmpty和map-isEmpty方法吗?或者collection-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();
}
publicstaticvoidmain(字符串[]args){
Map hello=newhashmap();
System.out.println(isEmpty(hello));
Map primary=newhashmap();
System.out.println(isEmpty(primary));
}
公共静态布尔值isEmpty(集合值){
返回值==null | | value.isEmpty();
}
公共静态布尔值为空(映射值){
返回值==null | | value.isEmpty();
}
我觉得这个设计很糟糕。Null是Null,empty是空的,如果它是字符串,那么它就是字符串,依此类推。不要试图用一种方法把每件事都搞砸。这不利于可维护性和可读性
if (str == null || str.isEmpty())
...
及
两者都很好
然而,就我个人而言,我从不试图将null
等同于空字符串或空集合。我认为这是一种不好的做法。null
集合根本不是集合,空集合实际上仍然是集合。如果(coll==null)保持集合为非null,则可以避免许多检查。如果您担心内存消耗,请使用Collections.emptySet
等
也就是说,如果您仍然想朝这个方向发展,我建议您使用plain并创建一个isEmpty(Collection coll)
和一个isEmpty(String str)
,以避免使用instanceof和casting
关于您的编辑:
例如,不要这样做
if (value == null || value.isEmpty()) {
return true;
}
return false;
照办
return value == null || value.isEmpty();
对于集合,您需要使用isEmpty()
而不是size()
。对于某些集合类型(如LinkedList),size()比isEmpty()更昂贵。正如我刚才在这一问题前30分钟发布的另一个问题中所写,每次检查所有内容都是浪费时间的
但是,这些类型的函数在某些情况下仍然有用。但是,我不使用“is valid”函数,而是将其实现为“crash if bad”函数。还请注意,此函数仅适用于集合
一个例子是
CrashIfCollection.badNullLength(coll, "coll", Null.BAD, 1);
代码:
我希望在公共库中有一个实用程序类来处理这个问题。请注意,如果对象有一个isEmpty、length或size方法(在确定对象不为null之后),我们将使用该对象自己的isEmpty、length或size方法(按该顺序)。通过调用它,人们不再需要担心NPE——你调用它,你就可以开始了——如果它是真的,那么你的集合/map/etc就不是空的,并且里面有一些东西;如果为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));
}
}
/**
*提供执行输入验证和边界验证的方法。
*/
公共最终类ValidationUtils{
/**
*检查对象是空的还是空的。
*
*@param对象
*要检查的对象
*@return boolean{@code true}如果对象为null或确定为空(使用它提供的方法--
*如果它不提供这样的方法,则仅当它为null时才为空)
*/
公共静态布尔值isEmpty(@Nullable final Object){
if(object==null)
返回true;
试一试{
//尝试使用对象类的isEmpty方法检查我们是否为空,现在我们知道我们为空
//非空
final-Method=object.getClass().getMethod(“isEmpty”);
最终对象结果=method.invoke(对象);
if(布尔值的结果实例)
返回Boolean.class.cast(result.booleanValue();
}catch(@NotNull final NoSuchMethodException | InvocationTargetException | IllegalArgumentException
|IllegalAccessException | SecurityException被忽略){
//我们无法调用…让我们转到下一个常用方法
}
试一试{
//尝试使用对象类的length方法检查我们是否为空,现在我们知道我们为空
//非空
final-Method=object.getClass().getMethod(“长度”);
最终对象结果=method.invoke(对象);
if(整数的结果实例)
返回Integer.class.cast(result).intValue()您可以通过执行此操作进行尝试。如果您的大小为私有整数,则可以执行以下操作:
public boolean isEmpty()
{
if(size == 0)
{
return true;
}
else
{
return false;
}
}
这对我很有用。数组和映射呢?@bheshgurhung是的,这是个好建议。我还没有为数组和映射编码,但我也需要它们。如果这是性能关键,请使用严格的键入。将集合强制转换为对象,然后再返回集合将阻止许多JVM优化。@Banthar你能提供一个测试吗关于这一点,我该怎么做?@user2809564基本上对每种类型都有单独的方法。isEmpty(Collection)
,isEmpty(String)
等等。在某些情况下,你可能是对的,但如果size()
明显是slo,我会非常惊讶
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);
}
}
}
Testing null
java.lang.NullPointerException: to_test
Testing []
java.lang.IllegalArgumentException: to_test.size() (0) is less than min_len (1)
Testing [one element]
/**
* 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));
}
}
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;
}
...
}
}
}
}
public boolean isEmpty()
{
if(size == 0)
{
return true;
}
else
{
return false;
}
}