Reputation: 8158
My question is quite clear.
I have a list and I want to be sure that it has at least one not null element. And that too, without looping (performance measurement).
list.size()
is definitely not helpful here. Because if the list contains 5 null values, then also its size will be 5.
Please note that, I'm not asking for a list that cannot contain null
.
Upvotes: 2
Views: 10618
Reputation: 718678
There is no way to do this with the standard List
implementations without looping, either explicitly or implicitly1. This is not supported by the List
API, and none of the standard list classes included as a specialized operation.
The only way to avoid looping is to create a custom List
implementation that treats null
as special, and keeps a count of the number of null
elements in the list. And the downside of that approach is that update operations on the list are more expensive because they need to test to see if the counter needs to be changed.
Note that using a hand-coded loop is typically not that expensive because you can stop looping as soon as you see a non-null element.
1 - If you are concerned about efficiency, then an implicit loop in some method like Collections.frequency
is likely to be much more expensive than a loop that is hand-code expressly for this purpose.
FOLLOW-UP
I'm not creating or filling the list. I got the already generated list from some code that I cannot alter.
In that case, a loop like the following is the fastest possible solution:
boolean empty = true;
for (SomeType t : list) {
if (t != null) {
empty = false;
break;
}
}
Indexing might be marginally faster if the list is an ArrayList
, but not for a LinkedList
.
Upvotes: 8
Reputation: 2610
I'm unsure if the copy constructor of ArrayList
is actually looping but this does the trick, using String
for my example. removeAll
does loop internally on the other hand... so that's not really "not looping"...
List<String> testLst = new ArrayList<String>();
testLst.add(null);
testLst.add(null);
testLst.add(null);
testLst.add(null);
List<String> testLst2 = new ArrayList<String>();
testLst2.add(null);
testLst2.add(null);
testLst2.add(null);
testLst2.add(null);
testLst2.add("test");
List<String> nullLst = new ArrayList<String>();
nullLst.add(null);
List<String> removedNull = new ArrayList<String>(testLst);
removedNull.removeAll(nullLst);
if (testLst.size() > 0 && removedNull.size() > 0) {
System.out.println("Contains non-null");
} else {
System.out.println("Contains only null or empty");
}
removedNull = new ArrayList<String>(testLst2);
removedNull.removeAll(nullLst);
if (testLst2.size() > 0 && removedNull.size() > 0) {
System.out.println("Contains non-null");
} else {
System.out.println("Contains only null or empty");
}
Upvotes: 0
Reputation: 382092
If you receive an object on which you only know it's a list (that is, it implements List
), you have no other solution that directly or indirectly looping.
The List
interface doesn't provide such feature and I know of no commonly available implementation providing it.
You have no other choice than to loop or to call a method which loops.
EDIT : Of course, if you write the list class yourself, you can do what you want like having a counter.
Upvotes: 3
Reputation: 14149
This is the wrong question. You cannot tell if a list contains null
elements without looking at the elements. I could give an answer using recursion, but that would be less performant and just circumvent using any loop statements.
What you want is either a collection that doesn't allow null in the first place or create a class that implements the list interface and keeps track of whether null values are contained in a private field.
Upvotes: -1
Reputation: 111219
You can create your own implementation of list that keeps the number of non-null elements in a local variable and updates it every time elements are added and removed.
Upvotes: 6