RAS
RAS

Reputation: 8158

How to check if list has at least one element without looping

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

Answers (6)

Stephen C
Stephen C

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

Jonathan Drapeau
Jonathan Drapeau

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

Denys S&#233;guret
Denys S&#233;guret

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

Axel
Axel

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

Joni
Joni

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

upog
upog

Reputation: 5521

Collections.frequency(list, null) > 0

Upvotes: 0

Related Questions