简体   繁体   English

检查集合的最佳方法不是null和null条件

[英]Best way to check collections not null & null conditions

we use collections like ArrayList,hashmap & many more. 我们使用ArrayList,hashmap等集合。

Number of times we have check condition like whether list is null or not. 我们检查条件的次数,例如list是否为null。

We have many ways to chek whether our collection is null or not. 我们有很多方法来判断我们的集合是否为空。

Different ways. 不同的方法。

1. if(list==null)
2. if(list.size()==0)
3. if(list.isEmpty())

Also sometimes we also need to check whether list is not null , so we normally check it by these ways 有时我们还需要检查列表是否为空,因此我们通常会通过这些方式进行检查

1. if(list!=null)
2. if(list.size()>0)
3. if(!list.isEmpty()) 

Which is best condition or do we need to make some combination of these considering performance of program execution? 考虑到程序执行的性能,哪个是最佳条件还是需要将这些组合起来?

Best combination would be 最佳组合将是

if(list!=null && !list.isEmpty()){

        //Yeah ,do something
}

One for null check, and then any thing there or not check 一个用于空检查,然后是否有任何检查

1. if(list!=null)

You should make sure that is never the case!! 你应该确保永远不会这样!

Read Effective Java 2nd Edition by Joshua Bloch 阅读Joshua Bloch撰写的有效Java第2版
Item 43: Return empty arrays or collections, not nulls 第43项:返回空数组或集合,而不是空值

[...] In summary, there is no reason ever to return null from an array- or collection-valued method instead of returning an empty array or collection. [...]总之,没有理由从数组或集合值方法返回null,而不是返回空数组或集合。 The null-return idiom is likely a holdover from the C programming language, in which array lengths are returned separately from actual arrays. 空返回惯用语很可能是C编程语言的延续,其中数组长度与实际数组分开返回。 In C, there is no advantage to allocating an array if zero is returned as the length. 在C中,如果返回零作为长度,则分配数组没有任何优势。

In short, let your methods return Collections.emptyList() instead of null and you've got one thing less to worry about. 简而言之,让你的方法返回Collections.emptyList()而不是null,你有一点不用担心。

2. if(list.size()>0)
3. if(!list.isEmpty()) 

That depends. 那要看。 For a simple collection such as ArrayList, they are equivalent. 对于像ArrayList这样的简单集合,它们是等效的。 But what if your Collection is actually a live view of a Database query? 但是,如果您的Collection实际上是数据库查询的实时视图呢? Calling size() might me a very expensive operation, whereas isEmpty() will always be O(1). 调用size()可能是一个非常昂贵的操作,而isEmpty()将始终是O(1)。 I'd say use isEmpty(). 我会说使用isEmpty()。

Also see Jon Skeet's answer here: https://stackoverflow.com/a/11152624/342852 另见Jon Skeet的回答: https//stackoverflow.com/a/11152624/342852

In Java8 you can use Optional to handle null cases properly. Java8中,您可以使用Optional来正确处理空案例。 For example, both lists animalsNull and animalWithNullElements would be properly handled by the function filterList : 例如,两个列表animalsNullanimalWithNullElements都将由函数filterList正确处理:

List<String> animalsNull = null;

List<String> animalWithNullElements = new ArrayList<String>();
        animalWithNullElements.add(0, null);
        animalWithNullElements.add(1, "Guybrush Threepwood");
        animalWithNullElements.add(2, null);

private static List<String> filterList(List<String> animals) {
        return Optional.ofNullable(animals)
               .orElseGet(Collections::emptyList)
               .stream()
               .filter(Objects::nonNull)
               .collect(Collectors.toList());
    }

It really depends on what you want to do. 这真的取决于你想做什么。 If you want to be sure that a list exist AND has some elements then you would use 如果你想确定列表存在并且有一些元素,那么你会使用

if (list != null && !list.isEmpty())

If I may give some advice, while returning collections, return by default an empty collection. 如果我可以提供一些建议,在返回集合时,默认返回一个空集合。 That way you will avoid nulls. 这样你就可以避免空值。

Number of times we have check condition like whether list is null or not. 我们检查条件的次数,例如list是否为null。

For a start, a null collection and an empty collection are different things . 首先, null集合和空集合是不同的东西 If you need to test if a collection is null you need a different test to if you are trying to test if the collection is empty. 如果您需要测试集合是否为null ,那么如果您尝试测试集合是否为空,则需要进行不同的测试。

Secondly, if a collection could be either null or empty (and they "mean" the same thing, per your application design) then you have a problem in your design. 其次,如果一个集合可以为null或为空(根据您的应用程序设计,它们“意味着”相同的东西)那么您的设计就会出现问题。 You should most likely represent ... whatever it is you are trying to represent ... one way, and not either / both ways. 你最有可能代表......无论你想要代表什么......一种方式,而不是两种方式。

Thirdly, it is generally best to use an empty collection rather than a null , because you can treat an empty and non-empty collection uniformly. 第三,通常最好使用空集合而不是null ,因为您可以统一处理空集合和非空集合。 By contrast, a null always needs to be handled as a special case. 相比之下, null 始终需要作为特殊情况处理。 (And if you forget to handle the null case, then you've got a potential for NullPointerExceptions .) (如果你忘记处理null case,那么你就有可能使用NullPointerExceptions 。)


Having said that ... 话说回来 ...

Which is best condition or do we need to make some combination of these considering performance of program execution? 考虑到程序执行的性能,哪个是最佳条件还是需要将这些组合起来?

If you really need to deal with the case of a null , then you've no choice but to test for null . 如果你真的需要处理null的情况,那么你别无选择,只能测试null

For isEmpty() versus size() == 0 : 对于isEmpty()size() == 0

  • the two predicates should give the same answer (unless you have an infinite lazy collection ...), but 这两个谓词应该给出相同的答案(除非你有一个无限的懒惰集合......),但是

  • in some cases isEmpty() could be faster, at least in theory. 在某些情况下, isEmpty() 可能更快,至少在理论上是这样。

The latter depends on the implementation of the collection type: specifically, on whether the size() method needs to count the collection elements. 后者取决于集合类型的实现:具体来说,取决于size()方法是否需要计算集合元素。 (I don't think that any of the standard collection classes have this property, but that's not to say that you won't find some class that does ...) (我不认为任何标准集合类都有这个属性,但这并不是说你不会找到一些类...)

So the optimal predicate is most likely either: 所以最佳谓词最有可能是:

 c != null && !c.isEmpty()

or 要么

 !c.isEmpty()

depending on whether you (really) need to cater for nulls. 取决于你(真的)是否需要满足空值。

And the obvious corollary is that your application is likely to be more efficient ... as well as simpler and more robust ... if you don't use null to represent empty collections. 显而易见的必然结果是,您的应用程序可能更高效......以及更简单和更健壮......如果您使用null来表示空集合。 (If you need immutable empty collection objects, you can get them for free from methods / statics defined by the Collections class.) (如果需要不可变的空集合对象,可以从Collections类定义的方法/静态中免费获取它们。)

There is a useful util class called CollectionUtils from Apache commons-collections bundle. Apache commons-collections包中有一个名为CollectionUtils的有用的util类。 With using it the code will look like: 使用它时代码看起来像:

if(CollectionUtils.isEmpty(collection))

It looks nice and under the hood it has the same invocation: 它看起来不错,并且在引擎盖下它具有相同的调用:

public static boolean isEmpty(Collection coll) { return coll == null || coll.isEmpty(); }

null means list is initialized with null. null表示list初始化为null。 null list size or isEmpty will throw NullPointerException . null list sizeisEmpty将抛出NullPointerException But, not null list can be empty or size==0 但是,非空list可以为空或大小== 0

(list!=null) != (list.size()==0)

size==0 and isEmpty is equivalent. size == 0和isEmpty是等价的。

(list.size()==0) ==  list.isEmpty()

There can be multiple approaches to handle this: 可以有多种方法来处理这个问题:

1: If code makes sure that collection cannot be null by initializing it either in constructor or as field initializaiton then caller need not to ideally check for null everywhere. 1:如果代码通过在构造函数或字段初始化中初始化它来确保集合不能为null ,则调用者不需要理想地在任何地方检查null Only isEmpty check should suffice: 只有isEmpty检查才足够:

private List<Integer> numbers = new ArrayList<Integer>(); //or in constructor

// caller can then safely use //调用者可以安全地使用

if(numbers.isEmpty)

2: Alternatively write a utility method to have null and empty check, no need for size check as it already happens inside isEmpty call. 2:或者编写一个实用程序方法来进行nullempty检查,不需要进行size检查,因为它已经在isEmpty调用中发生了。 Use this utility method elsewhere in code. 在代码中的其他位置使用此实用程序

public static boolean empty(Collection<?> col) {
   return col == null || col.isEmpty();
}

It depends on your program structure. 这取决于您的程序结构。 For example, I have a helper class called ArrayUtils , in which I have an API that looks like this: 例如,我有一个名为ArrayUtils的辅助类,其中我有一个如下所示的API:

public static <E> boolean isEmpty(final Collection<E> collection)
{
    return collection == null || collection.isEmpty();
}

I use this one when I know that I may get a null list, but when I'm absolutely sure it's not null , I use only if ( collection.isEmpty ) . 当我知道我可能得到一个null列表时,我使用这个,但是当我完全确定它不是null ,我只使用if ( collection.isEmpty ) Improves code readability, too. 提高代码可读性。

collection.size() > 1 is redundant, because you have the other APIs at your disposal. collection.size() > 1是多余的,因为您可以使用其他API。

If it you are owner of the codebase, I would avoid using such logic at all. 如果你是代码库的所有者,我会避免使用这样的逻辑。 Instead try to follow the model when your collection supplier can't return null but has a reference to Collections.emptyXXX or just regular empty container empty. 相反,当您的集合供应商不能返回null但是引用Collections.emptyXXX或只是常规空容器为空时,请尝试遵循该模型。

You can do it with two predicates as below : 您可以使用以下两个谓词来执行此操作:

public static final Predicate<String> NULL_OR_EMPTY = (in) -> null == in || "".equals(in);

public static final Predicate<List<String>> STRING_LIST_NULL_OR_EMPTY = (strList) ->  strList.stream().filter(NULL_OR_EMPTY).collect(Collectors.toList()).size() > 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM