when should we use hasnext()

sohan_snow
Tera Contributor

Hi All,

I understand that hasnext() will either return true or false, but next() also in a way does the same thing and then goes to the next record.

I would like understand when should we use hasnext(), Is there any case scenario where usage of hasnext() is important

Thanks in advance

1 ACCEPTED SOLUTION

Dave Smith1
ServiceNow Employee
ServiceNow Employee

Although the question has been answered, you may find reading up about an iterator explains a bit about the underlying purpose of these two methods.



Suggested reading: https://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html



For what it's worth, consider standing near the edge of a cliff:


  • hasNext() is usually used to check there's another step to be taken
  • next() takes that step.

View solution in original post

11 REPLIES 11

Oleksiy Kosenko
Tera Expert

In reality the difference between these two is significant.

If you execute the code below (see the bottom) in Scripts – Background, you get about the following printout :

 

Background message, type:info, message: done in 19398 ms
Background message, type:info, message: done in 19425 ms
Background message, type:info, message: done in 19574 ms
Background message, type:info, message: done in 19648 ms
Background message, type:info, message: done in 19426 ms
Background message, type:info, message: done in 7666 ms
Background message, type:info, message: done in 7468 ms
Background message, type:info, message: done in 7273 ms
Background message, type:info, message: done in 7344 ms
Background message, type:info, message: done in 7390 ms

 

You observe a very manifest performance gain of GlideRecord.hasNext() compared to GlideRecord.next()

 

The reason for this difference is fundamental and not specific to ServiceNow, but to how relational database works. After a query is executed, a collection of pointers to physical records is gathered in the memory of DB server. Typically, hasNext() API returns whether that collection is empty. This is computationally cheap operation because everything is already in the memory. On the contrary, next() goes and retrieves physical record from the disk, which is the most computationally expensive operation ever.

 

Conclusion: if you are about to retrieve all records one after the other,  next() is the way to go.

If you only want to check whether your recordset is empty, use hasNext()

 

for (var j=0; j<5; j++) {
var iStartMilli = new GlideDateTime().getNumericValue();
for (var i=0; i<1000; i++) {
    var gr = new GlideRecord('incident');
    gr.addActiveQuery();
    gr.query();
    if (gr.next()) {

    }
}
var iEndMilli = new GlideDateTime().getNumericValue();
gs.addInfoMessage('done in ' + (iEndMilli - iStartMilli) + ' ms' );
}

for (var j=0; j<5; j++) {
var iStartMilli = new GlideDateTime().getNumericValue();
for (var i=0; i<1000; i++) {
    var gr = new GlideRecord('incident');
    gr.addActiveQuery();
    gr.query();
    if (gr.hasNext()) {

    }
}
var iEndMilli = new GlideDateTime().getNumericValue();
gs.addInfoMessage('done in ' + (iEndMilli - iStartMilli) + ' ms' );
}

 

That's great if hasNext actually works.  I've not tried lately, but as I reported 2 years ago, because it was completely unreliable in results it could not be used.  If anyone can point to a release note indicating it's been fixed that would be great.