1 package org.apache.lucene.search; 2 3 import org.apache.lucene.util.PriorityQueue; 4 5 public class TopDocCollector extends HitCollector { 6 7 private ScoreDoc reusableSD; 8 9 int totalHits; 10 PriorityQueue hq; 11 12 public TopDocCollector(int numHits) { 13 this(numHits, new HitQueue(numHits)); 14 } 15 16 TopDocCollector(int numHits, PriorityQueue hq) { 17 this.hq = hq; 18 } 19 20 // javadoc inherited 21 public void collect(int doc, float score) { 22 if (score > 0.0f) { 23 totalHits++; 24 if (reusableSD == null) { 25 reusableSD = new ScoreDoc(doc, score); 26 } else if (score >= reusableSD.score) { 27 // reusableSD holds the last "rejected" entry, so, if 28 // this new score is not better than that, there's no 29 // need to try inserting it 30 reusableSD.doc = doc; 31 reusableSD.score = score; 32 } else { 33 return; 34 } 35 reusableSD = (ScoreDoc) hq.insertWithOverflow(reusableSD); 36 } 37 } 38 39 /** The total number of documents that matched this query. */ 40 public int getTotalHits() { return totalHits; } 41 42 // 获取topDocs,将hq中元素取出,放入scoreDocs数组,返回TopDocs对象。 43 public TopDocs topDocs() { 44 ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()]; 45 for (int i = hq.size()-1; i >= 0; i--) 46 scoreDocs[i] = (ScoreDoc)hq.pop(); 47 48 float maxScore = (totalHits==0) 49 ? Float.NEGATIVE_INFINITY 50 : scoreDocs[0].score; 51 52 return new TopDocs(totalHits, scoreDocs, maxScore); 53 } 54 }
PriorityQueue默认情况下,类型为HitQueue(HitQueue为PriorityQueue子类,实现了lessThan方法,在执行insert时,对ScoreDoc对象进行比较,按score降序排序,score相同时,按doc的id降序排列)。