|
用户名:zhafn 笔名:zhafn 地区: 行业:其他 |
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
欢迎访问水木尤寒的博客
大队培训
J2SE中 QUEUES & 延时处理
使用Thread Pooling处理简短任务
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
RejectedExecutionHandler handler)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
public class NamePrinter implements Runnable {
private final String name;
private final int delay;
public NamePrinter(String name, int delay) {
this.name = name;
this.delay = delay;
}
public void run() {
System.out.println("Starting: " + name);
try {
Thread.sleep(delay);
} catch (InterruptedException ignored) {
}
System.out.println("Done with: " + name);
}
}
----------------------------------------------------------------------------------
import java.util.concurrent.*;
import java.util.Random;
public class UsePool {
public static void main(String args[]) {
Random random = new Random();
ExecutorService executor =
Executors.newFixedThreadPool(3); //设定线程池容量为3
// Sum up wait times to know when to shutdown
int waitTime = 500;
for (int i=0; i<10; i++) {
String name = "NamePrinter " + i;
int time = random.nextInt(1000);
waitTime += time;
Runnable runner = new NamePrinter(name, time);
System.out.println("Adding: " + name + " / " + time);
executor.execute(runner);
}
try {
Thread.sleep(waitTime);
executor.shutdown();
executor.awaitTermination
(waitTime, TimeUnit.MILLISECONDS);
} catch (InterruptedExceptin ignored) {
}
System.exit(0);
}
}
----------------------------------------------------------------------------------
可能输出:
unique with the random sleeps present:
Adding: NamePrinter 0 / 30
Adding: NamePrinter 1 / 727
Adding: NamePrinter 2 / 980 //前3个添加进行的明显比较快
Starting: NamePrinter 0
Starting: NamePrinter 1
Starting: NamePrinter 2
Adding: NamePrinter 3 / 409
Adding: NamePrinter 4 / 49
Adding: NamePrinter 5 / 802
Adding: NamePrinter 6 / 211
Adding: NamePrinter 7 / 459
Adding: NamePrinter 8 / 994
Adding: NamePrinter 9 / 459
Done with: NamePrinter 0 虽然任务全部已经添加到线程池,
Starting: NamePrinter 3 但是因为线程池容量为3个,
Done with: NamePrinter 3 前3个任务又都在执行,
Starting: NamePrinter 4 所以任务3一直等到任务0结束才开始执行
Done with: NamePrinter 4
Starting: NamePrinter 5
Done with: NamePrinter 1
Starting: NamePrinter 6
Done with: NamePrinter 6
Starting: NamePrinter 7
Done with: NamePrinter 2
Starting: NamePrinter 8
Done with: NamePrinter 5
Starting: NamePrinter 9
Done with: NamePrinter 7
Done with: NamePrinter 9
Done with: NamePrinter 8
HttpSessionListener统计在线人数
/**
* 编写以下SessionCounter.java
* 并编译为SessiionCounter.class
* 然后放到你的网站的classpath的
* SessionCount(自己建立此目录)下面
*/
package SessionCount;
import javax.servlet.*;
import javax.servlet.http.*;
public class SessionCounter implements HttpSessionListener {
private static int activeSessions = 0;
public void sessionCreated(HttpSessionEvent se) {
activeSessions++;
}
public void sessionDestroyed(HttpSessionEvent se) {
if(activeSessions > 0)
activeSessions--;
}
public static int getActiveSessions() {
return activeSessions;
}
}
接着建立online.jsp文件用于显示在线人数
在线:
然后需要在你的网站的WEB-INF中建立web.xml
文件内容如下:
Flash Lite 1.1 FSCommand2 用法列表
这些资料其实是从 Flash Lite 1.1 的文档翻译来的,是为了今后查找的时候更方便一些而已。这些功能并不是所有手机都会支持,需要上机测试才能了解是否支持。
Flash Lite 1.1 目前支持功能相对较强的 FSCommand2,这在普通的 FLash 播放器中是不支持的。相对 FSCommand,有如下的不同:
FSCommand2 主要分成三类:普通指令、控制影片播放的指令、平台相关指令。下面是详细内容:
普通指令
普通指令::URL 编码相关
Escape
status = FSCommand2( “Escape”, original, encoded )
URL 编码指令,将 original 编码成 encoded。
返回 0 失败,返回 1 成功。
Example:
original_string = “hello, how are you?”;
status = fscommand2(”Escape”, original_string, “encoded_string”);
Unescape
status = FSCommand2( “Unescape”, encoded, original )
URL 解码指令,将 encoded 解码成 original。
返回 0 失败,返回 1 成功。
Example:
string2 = “Hello%7B%5BWorld%5D%7D”;
status = fscommand2(”Unescape”, string2, “normal_string”);
普通指令::输入框相关
SetInputTextType()
status = FSCommand2( “SetInputTextType”, variableName, type )
设定文本框可输入文本的类型,variableName 是对应的文本框内的值,type 则由以下内容控制:
Numeric: [0-9];
Alpha: [A-Z, a-z];
Alphanumeric: [0-9, A-Z, a-z];
Latin: 拉丁符号;
NonLatin: 非拉丁符号;
NoRestriction: 默认模式。
返回 0 失败,返回 1 成功。
Example:
status = fscommand2(”SetInputTextType”, “input1″, “Numeric”);
控制影片播放的指令
控制影片播放的指令::显示
FullScreen()
status = FSCommand2( “FullScreen”, size )
设置全屏播放模式,size 应该为 true 或者 false
返回 -1 为不支持,0 则为支持。
某些手机不支持全屏播放模式。
SetQuality()
status = FSCommand2( “SetQuality”, quality )
设置动画播放的质量,quality 的值为 high,medium 或 low。
返回 -1 为不支持,0 则为支持。
控制影片播放的指令::键盘设置
SetSoftKeys()
status = FSCommand2( “SetSoftkeys”, left, right )
设置手机上左右两个软键的功能显示内容,left 和 right 可以是变量或者字符串。按下左键的时候激活的是 PageUp 事件,而右键则是 PageDown 事件。
返回 -1 为不支持,0 则为支持。
ResetSoftKeys()
status = FSCommand2( “ResetSoftKeys” )
重置左右软键。
返回 -1 为不支持,0 则为支持。
播放器操作指令
GetFreePlayerMemory()
status = FSCommand2( “GetFreePlayerMemory” )
获得剩余内存数,以 K 为单位。
返回 -1 为不支持,其它值则为剩余的内存,以 K 为单位。
GetTotalPlayerMemory()
status = FSCommand2( “GetTotalPlayerMemory” )
获得 Flash Lite 可使用的内存总数,以 K 为单位。
返回 -1 为不支持,其它值则为内存数,以 K 为单位。
Launch()
status = FSCommand( “Launch”, “application-path,arg1,arg2,…,argn” )
执行手机上的其它应用程序(操作系统无关)。
Quit()
status = FSCommand2( “Quit” )
退出当前的 Flash Lite 程序。
返回 -1 为不支持。
平台相关指令
平台相关指令::日期和时间
GetDateDay()
status = FSCommand2( “GetDateDay” )
获得当前的日期(1-31)。
返回 -1 为不支持,支持则返回 1-31 之间的数字。
GetDateMonth()
status = FSCommand2( “GetDateMonth” )
获得当前的月份(1-12)。
返回 -1 为不支持,支持则返回 1-12 之间的数字。
GetDateWeekday()
status = FSCommand2( “GetDateWeekday” )
获得当前的月份(0-6)。
返回 -1 为不支持,支持则返回 0-6 之间的数字。
GetDateYear()
status = FSCommand2( “GetDateYear” )
获得当前的年份。
返回 -1 为不支持,支持则返回数字,如:2005。
GetLocaleLongDate()
status = FSCommand2( “GetLocaleLongDate”, “longdate” )
获取当前的长日期串。日期格式根据手机本身以及 Locale 来确定。日期值指向到一个字串。
返回 -1 为不支持,0 则为支持。
以下是两个返回的 longdate 的例子:
October 16, 2004
16 October 2004
GetLocaleShortDate()
status = FSCommand2( “GetLocaleShortDate”, “shortdate” )
获取当前的短日期串。日期格式根据手机本身以及 Locale 来确定。日期值指向到一个字串。
返回 -1 为不支持,0 则为支持。
以下是两个返回的 shortdate 的例子:
10/16/2004
16-10-2004
GetLocaleTime()
status = FSCommand2( “GetLocalTime”, “time” )
获取当前的时间串。时间格式根据手机本身以及 Locale 来确定。时间值指向到一个字串。
返回 -1 为不支持,0 则为支持。
以下是两个返回的 time 的例子:
6:10:44 PM
18:10:44
GetTimeHours()
status = FSCommand2( “GetTimeHours” )
获得当前的小时(0-23)。
返回 -1 为不支持,支持则返回 0-23 之间的数字。
GetTimeMinutes()
status = FSCommand2( “GetTimeMinutes” )
获得当前的分钟(0-59)。
返回 -1 为不支持,支持则返回 0-59 之间的数字。
GetTimeSeconds()
status = FSCommand2( “GetTimeSeconds” )
获得当前的秒(0-59)。
返回 -1 为不支持,支持则返回 0-59 之间的数字。
GetTimeZoneOffset()
status = FSCommand2( “GetTimeZoneOffset”, “timezoneoffset” )
获取当前的时差数。时差值指向到一个数字,单位为秒。
返回 -1 为不支持,0 则为支持。
以下是两个返回的 timezoneoffset 的例子:
540: Japan standard time
-420: Pacific daylight savings time
平台相关指令::音量
GetMaxVolumeLevel()
status = FSCommand2( “GetMaxVolumeLevel” )
获取系统最大音量。
返回 -1 为不支持,支持则返回一个数字。
GetVolumeLevel()
status = FSCommand2( “GetVolumeLevel” )
获取系统当前音量。
返回 -1 为不支持,支持则返回一个数字。
平台相关指令::震动
StartVibrate()
status = FSCommand2( “StartVibrate”, time_on, time_off, repeat )
设定手机震动,time_on 为开始时间,time_off 为停止时间, repeat 为重复次数。time_on 和 time_off 均为百分秒,并且不超过 5 秒。
返回 -1 为不支持,0 为目前正在震动,1 为出现错误。
StopVibrate()
status = FSCommand2( “StopVibrate” )
停止震动。
返回 -1 为不支持,0 为停止成功。
平台相关指令::电源
GetBatteryLevel()
status = FSCommand2( “GetBatteryLevel” )
获得电量。
返回 -1 为不支持,支持则返回一个数字。
GetMaxBatteryLevel()
status = FSCommand2( “GetMaxBatteryLevel” )
获得最大电量。
返回 -1 为不支持,支持则返回一个数字。
GetPowerSource()
status = FSCommand2( “GetPowerSource” )
获取供电方式。
返回 -1 为不支持,0 为目前在使用电池供电,1 为目前在使用外部电源供电。
平台相关指令::网络信息
GetMaxSignalLevel()
status = FSCommand2( “GetMaxSignalLevel” )
获取最大信号强度值。
返回 -1 为不支持,支持则返回一个数字。
GetNetworkConnectStatus()
status = FSCommand2( “GetNetworkConnectStatus” )
获取当前网络状态。
返回 -1 为不支持,其它则为
0:在网络连接状态;
1:正在试图连接网络;
2:无可用网络连接;
3:网络连接暂停状态;
4:无法判断状态。
GetNetworkName()
status = FSCommand2( “GetNetworkName”, “networkname” )
获取连接网络的名称,返回值指向一个字串。
返回 -1 为不支持,其它则为
0:未连接网络;
1:连接网络,但是无法获取名称;
2:成功。
返回的 networkname 的例子:
AT&T Wireless
KPN Mobile
GetNetworkRequestStatus()
status = FSCommand2( “GetNetworkRequestStatus” )
获取网络请求状态。
返回 -1 为不支持,其它则为
0:等待中,网络连接已经成功,主机名已经解析,服务器也已经连接;
1:等待中,网络连接已经成功;
2:等待中,但是网络连接尚未成功;
3:等待中,连接已经成功,主机名已经解析;
4:失败,网络连接错误;
5:失败,连接服务器失败;
6:服务器返回 404 错误;
7:失败,无法连接 DNS 服务器或者无法解析主机名称;
8:请求成功完成;
9:请求超时;
10:尚未执行请求。
GetNetworkStatus()
status = FSCommand2( “GetNetworkStatus” )
获取网络状态。
返回 -1 为不支持,其它则为
0:无网络;
1:在本地网络;
2:在本地扩展网络;
3:漫游。
GetSignalLevel()
status = FSCommand2( “GetSignalLevel” )
获取当前信号强度值。
返回 -1 为不支持,支持则返回一个数字。
平台相关指令::用户设备信息
GetLanguage()
status = FSCommand2( “GetLanguage”, “language”)
获取用户设备使用的语言,返回值指向一个字串。
返回 -1 为不支持,0 则为支持。
返回的 language 值:
cs: Czech.
da: Danish.
de: German.
en-UK: UK or international English.
en: USA English.
es: Spanish.
fi: Finnish.
fr: French.
hu: Hungarian.
it: Italian.
jp: Japanese.
ko: Korean.
nl: Dutch.
no: Norwegian.
pl: Polish.
pt: Portuguese.
ru: Russian.
Platform integration commands 45
sv: Swedish.
tr: Turkish.
xu: The language cannot be determined.
zh-CN: Simplified Chinese.
zh-TW: Traditional Chinese.
平台相关指令::用户设备及播放器标识
GetDeviceID()
status = FSCommand2( “GetDeviceID”, “id” )
获取备的 ID,返回值指向一个字串。
返回 -1 为不支持,0 则为支持。
GetPlatform()
status = FSCommand2( “GetPlatform”, “platform” )
获取设备的操作系统平台,返回值指向一个字串。
返回 -1 为不支持,0 则为支持。
返回的 paltform 例子:
506i
FOMA1
GetDevice()
status = FSCommand2( “GetDevice”, “device” )
获取设备的型号,返回值指向一个字串。
返回 -1 为不支持,0 则为支持。
关于ActionScript 1.0、ActionScript 2.0、java的区别与联系
问题:创建两个位置大小颜色各不同的可拖拽的矩形。
方法一:method1.fla //ActionScript 1.0
//Flash Player 6(含)以上
//ActionScript 1.0或ActionScript 2.0均可
createEmptyMovieClip ("rectangle1_mc", 1);
rectangle1_mc._x = 10;
rectangle1_mc._y = 10;
with (rectangle1_mc) {
beginFill (0xff0000, 100);
moveTo (0, 0);
lineTo (200, 0);
lineTo (200, 200);
lineTo (0, 200);
endFill ();
}
rectangle1_mc.onPress = startDrag;
rectangle1_mc.onRelease = rectangle1_mc.onReleaseOutside = stopDrag;
//
createEmptyMovieClip ("rectangle2_mc", 2);
rectangle2_mc._x = 50;
rectangle2_mc._y = 50;
with (rectangle2_mc) {
beginFill (0xffcc00, 100);
moveTo (0, 0);
lineTo (400, 0);
lineTo (400, 100);
lineTo (0, 100);
endFill ();
}
rectangle2_mc.onPress = startDrag;
rectangle2_mc.onRelease = rectangle2_mc.onReleaseOutside = stopDrag;方法二:method2.fla //ActionScript 2.0
//Flash Player 6(含)以上
//必须为ActionScript 2.0
var rect1:Rectangle = new Rectangle (this, 10, 10, 200, 200, 0xff0000, 1); var rect2:Rectangle = new Rectangle (this, 50, 50, 400, 100, 0xffcc00, 2); delete rect1; delete rect2; delete Rectangle;
此方法必须得有一个Rectangle.as与之同路径。Rectangle.as内容如下:
class Rectangle extends MovieClip {
private var rectangle_mc:MovieClip;
public function Rectangle (target:MovieClip, x:Number, y:Number, w:Number,
h:Number, color:Number, depth:Number) {
rectangle_mc = target.createEmptyMovieClip ("rectangle_mc" + depth, depth);
rectangle_mc._x = x;
rectangle_mc._y = y;
with (rectangle_mc) {
beginFill (color, 100);
moveTo (0, 0);
lineTo (w, 0);
lineTo (w, h);
lineTo (0, h);
endFill ();
}
rectangle_mc.onPress = startDrag;
rectangle_mc.onRelease = rectangle_mc.onReleaseOutside = stopDrag;
}
}方法三:method3.java //如果.java也可以直接编译.swf的话
public class method3{
public static void main(String[] args){
Rectangle rect1 = new Rectangle (this, 10, 10, 200, 200, 0xff0000, 1);
Rectangle rect2 = new Rectangle (this, 50, 50, 400, 100, 0xffcc00, 2);
//这里就不需要手动delete了,因为java有垃圾回收器,它会自动清除。
}
}
class Rectangle extends MovieClip {
private MovieClip rectangle_mc;
public Rectangle (MovieClip target, Double x, Double y, Double w, Double h,
Double color, Double depth) {
rectangle_mc = target.createEmptyMovieClip ("rectangle_mc" + depth, depth);
rectangle_mc._x = x;
rectangle_mc._y = y;
with (rectangle_mc) {
beginFill (color, 100);
moveTo (0, 0);
lineTo (w, 0);
lineTo (w, h);
lineTo (0, h);
endFill ();
}
rectangle_mc.onPress = startDrag;
rectangle_mc.onRelease = rectangle_mc.onReleaseOutside = stopDrag;
}
}通过比较不难发现,ActionScript 1.0最灵活、最简单、最容易理解。但重复类似的操作时也会最繁琐。如果要画1000个位置大小颜色各不同的矩形的话,不累死也会被笑死! ActionScript 2.0则非常系统,单独用Rectangle.as定义了一个矩形类,使用时new即可,爽!有点小小的遗憾的是有几行delete,当然你也可以不加,让它永远霸占你的内存。再看看java,看完了又看,看完了再看,呵呵! 啥也不说了,谁老大肯定有人知道。
编辑:卡其色
给flash加一个trim()函数
AS3.0概要–了解AS3.0的改变
随着一些相关资料对as3.0的介绍,有人可能认为它是另一种语言.它的根本改变在哪呢,它是什么呢?现在我们要放松一点.如果你熟知as2.0,那么它的变化并不是很大,甚至增加了一些命令你可以使用。
从我们第一眼看as3.0,它并不是一个全新的语言,它的架构要好于AS2.0,你将从FLASH8开始发现这些.任何东西都有自已的类和整洁的子类.类的继承关系看起来很复杂,但是它却是很容易理解。
主要的改变:
1、不在有_global范围了,但是你可以通过在预先的public,private和internal里,使用”namespace”来创建你自已的命名。
2、int/uint. 新的数据类型来描述非浮点数,这项增加可以使flash与其它程序语言同步,并且解决一些使用java和AMF/Flash Remoting令人头痛的问题。
3、你不能在在时间线上使用命令play()或stop().MovieClip不在是在global的范围内了,你必须通过flash.display.MovieClip来使用它的属性。
4、正规标准表达式—-快速搜索操作字符串。
5、新的更简单的委派(delegate)。
6、DOM3 事件模型——个新的,但是不被熟知的生成和操作事件信息的方法。
7、显示API列表——图像根据新的或更多的逻辑基于类别如Sprites精灵和Shapes形体被细分。
8、在也不需要指定depth深度数值给对象. Depth管理类现在会自动控制(基于API列表)并内建于flash player内.新的方法提供了对对象z-order也就是Z轴的操作。
9、Final/protected关键词.—防止你的类或函数被覆写。
10、新的简单的XML元素及属性使用E4X。
11、ArgumentError 类.——使用此类可以避免函数调用了不相符合的参数时所产生的错误。
12、Package 关键诩—-如果你不知道pagckage是什么,不要担心,当你在做大的项目时你会慢慢喜欢上它。
13、被用在数据输入输出接口的ByteArray提供方法和属性来优化读,写,和二进制数据。
低级别—异常
异常处理对于FLASH开发人员来说路还较长,如果一个数值超出新的int/unit数据类型,一个错误就会被显示出来.有些类似于JAVA.你必须要想办法解决这些问题,否则FLASH程序可能就会垮台.如果一些东西在AS1和AS2中失效,flash player可能会很友好的忽略掉,在FLASH8中,你可能已经通过使用file upload看的了新的究错能力,它需要一系列事件来显示上载进程和缓存错.使用AS3,这些是工作在一个低级别的状态。
异常可能会发生几个地方,例如:使用As3.0,你需要查看你的内存的最近使用状况,MemoryError是一个新的异常,当内存寻址失败时,它就会通过AVM2虚拟机显示错识.其它的异常为EOFError,illegalOperatinError,IOError,ScriptTimeoutError和StackOverflowError。
想一下上面这些内容,之前许多是JAVA等其它语言专用的,你可以通过StringBuilder类看到,它来自java类StringBuffer可以允许我们很容易的操作字符.终上所述,我必须说新的AS3类的结构看起来非常好.有不同背景的程序员看到FLASH就会说我知道它是怎么做的,我认为我们可以说actionscript已经过去了,它的童年过去了,青年时代刚刚到来。
新的命令
可能有更多的新命令,这里面例出一些发现到的。
Sound(声音)
leftPeak / rightPeak Property——当前声音的右声道振幅,从0到1
isBuffering : Boolean [read-only]——返回外缓冲MP3的状态
soundBufferTime : uint——声音在流式播放前缓冲的秒数
System(系统)
vmVersion : String [read-only]——当前安装的ActionScript虚拟机的版本
totalMemory : uint [read-only]——报告当前使用的内存数量:System.html
Debugging(调试)
getClassByName(name:String):Class——返回指定名称类对象的引用
describeType(value:Object):XML——xml对象产物,用来描述actionscript对象参数的方法。
ps:看来As3.0并没有想象中的变化那么大,不过先是FLASH8,接着FLEX2,AS3.0,macroemdia的脚步是越走越快。
在oracle中实现自动增长的列号(例子)
第29届奥林匹克运动会吉祥物!







第29届奥林匹克运动会吉祥物——福娃
福娃是北京2008年第29届奥运会吉祥物,其色彩与灵感来源于奥林匹克五环、来源于中国辽阔的山川大地、江河湖海和人们喜爱的动物形象。福娃向世界各地的孩子们传递友谊、和平、积极进取的精神和人与自然和谐相处的美好愿望。 福娃是五个可爱的亲密小伙伴,他们的造型融入了鱼、大熊猫、藏羚羊、燕子以及奥林匹克圣火的形象。
每个娃娃都有一个琅琅上口的名字:“贝贝”、“晶晶”、“欢欢”、“迎迎”和“妮妮”,在中国,叠音名字是对孩子表达喜爱的一种传统方式。当把五个娃娃的名字连在一起,你会读出北京对世界的盛情邀请“北京欢迎您”......
详细信息可以阅读:http://www.beijing2008.com/48/01/column211990148.shtml
Inside Lucene/超人气搜索引擎学习(1)-查询机制
任何用户, 包括系统开发者, 使用搜索引擎的共同方式只有一个: 查询(query). 整个搜索过程的目的是为了满足查询要求, 搜索过程是由查询贯穿的. 若没有指定查询, 而是从索引(index)的内容出发, "搜索"将是漫无目的且毫无意义的过程. 搜索过程的起点只能是索引.
以下引用自Lucene in Action 的入门章节, 在其中能看到Query是如何用来启动查询的.
public class BasicSearchingTest extends LiaTestCase {
public void testTerm() throws Exception {
IndexSearcher searcher = new IndexSearcher(directory);
Term t = new Term(“subject”, “ant”);
Query query = new TermQuery(t);
Hits hits = searcher.search(query);
assertEquals(“JDwA”, 1, hits.length());
t = new Term(“subject”, “junit”);
hits = searcher.search(new TermQuery(t));
assertEquals(2, hits.length());
searcher.close();
}
}public class IndexSearcher extends Searcher {
public TopDocs search(Query query, Filter filter, final int nDocs)
throws IOException {
Scorer scorer = query.weight(this).scorer(reader);
if (scorer == null)
return new TopDocs(0, new ScoreDoc[0]);
final BitSet bits = filter!=null?filter.bits(reader):null;
final HitQueue hq = new HitQueue(nDocs);
final int[] totalHits = new int[1];
scorer.score(new HitCollector() {
public final void collect(int doc, float score) {
if (score > 0.0f &&
(bits==null || bits.get(doc))) {
totalHits[0]++;
hq.insert(new ScoreDoc(doc, score));
}
}
});
ScoreDoc[] scoreDocs = new ScoreDoc[hq.size()];
for (int i = hq.size()-1; i >= 0; i--)
scoreDocs[i] = (ScoreDoc)hq.pop();
return new TopDocs(totalHits[0], scoreDocs);
}
...
}Scorer scorer = termQuery.weight.scorer(indexReader)
scorer.score(new HitCollector() {
...
});public scorer weight#scorer(IndexReader reader){
TermDocs termDocs = reader.termDocs(term);
if (termDocs == null)
return null;
return new TermScorer(this, termDocs, getSimilarity(searcher),
reader.norms(term.field()));
}class Scorer{
...
public void score(HitCollector hc) throws IOException {
while (next()) {
hc.collect(doc(), score());
}
}
...
public boolean next() throws IOException {
pointer++;
if (pointer >= pointerMax) {
pointerMax = termDocs.read(docs, freqs); // refill buffer
if (pointerMax != 0) {
pointer = 0;
} else {
termDocs.close(); // close stream
doc = Integer.MAX_VALUE; // set to sentinel value
return false;
}
}
doc = docs[pointer];
return true;
}
...
}
可以看出, 上面的问题唯一可能的答案是: weight在构造Scorer时已经为Scorer决定了查询内容就在那个termDocs里. Scorer的代码也表明, 它在遍历所有合法文档时,背后的查询动作是在穷举一个数组:doc[], 而这个数组的来源就是TermDocs. 剩下的问题是,TermDoc在整个查询中扮演何种角色--它是怎么读数据的
看看TermDoc是个虾米东东
reader 创建好TermDoc后调用TermDoc.seek(term). 这个方法在硬盘索引文件中找到term所对应的所有文档记录, 每条记录包含文档id和term在文档中出现的次数tf. 这些文档信息是编制索引时就建好的, 索引文件中每个term对应的文档记录按顺序紧密排列在一起, seek方法能找到这些记录在索引中的开始位置及满足term的文档总数. 以后, TermDoc在scorer中的作用就是读入每个符合term的文档及term在该文档中的tf, 由于建好了索引只需在索引文件中遍历即可, termDoc包含的df将用于此过程的遍历计数.就是说scorer接收到的那个termDoc是调用过seek的, 已经定位到了term对应的数据位置,这便让scorer能遍历termQuery中所有包含那个term的Doc.
scorer怎样遍历全部doc
读数据又是另一门学问, 感兴趣的人也许研究过读一个100M文件,与读1000个1K byte文件有何区别,结果当然是震撼的.只要有可能,尽量读取整数据而不是零碎地读取小数总不会让人失望,然而同样没有人会在构造一个对象时就去对一个未知大小(可能真的包含100万个文档)的数据.只要没收到必要请求,任何人都会尽力避免这种冗长的操作. Lucene的设计者同样只是让在scorer在需要读入数据即第一次调用next()方法时调用termDoc的read方法读数据(代码中黑体部分).为了避免零碎读取降低硬盘效率,termDoc.read()会一次性读入所有合法文档(当然仅包括文档id和tf, 建立索引的过程中,这两个数据一组组的放在专门的文件中,每个term对应的全部文档在这个文件里连续排列以避免零碎读取),scorer调用next ()语句,遍历read()返回的文档id数组,整个遍历过程只需把读出来的doc[i]里的i进行++便万事大吉.
遍历过程中发生什么事情大家心里应该很清楚,无非是把这些doc(这就是搜索结果)一个个添加到Collector中. 查询结束后, 我们将得到一个int数组, 里面保存着每个结果文档的id. 要使用这些查询结果,用户还需要从按照每篇文档的id文档库中取出结果, 这些只需调用searcher.doc(id)即可完成的事务性过程不在本"技术"文章讨论范围中.
所谓搜索原来如此简单...
Inside Lucene/超人气搜索引擎学习(0.5)-前传
Inside Lucene/超人气搜索引擎学习(0)-序
用Javascript和DHTML构建的矢量图形库
用Javascript和DHTML构建的矢量图形库
面向JSF开发者 Otrix 发布WebStudio 2005 Volume 3
Otrix 近日宣布发行WebStudio 2005 Volume 3,这是一个面向JSF开发开发人员的商业one-stop组件合集。
其中包括:
WebGrid, WebInput (DateChooser, Email, RegEx, Range validator ...), WebMenu, WebTab and WebTree Components.
Samples for J2EE 1.4 application servers (IBM Websphere 6, JBoss 4, Resin 3, Sun AS8, Tomcat 5, ..)
Samples for J2EE 1.3 application servers (IBM Websphere 5.1, JBoss 3, Resin 2, Sun AS7, Tomcat 4, Weblogic 7 & 8..)
工作中八大最易被淘汰的人
情商低下的人
智商显示一个人做事的本领,情商反映一个人做人的表现。在未来的社会里,不仅要 会做事,更要会做人,做人有时比做事更重要。
心理脆弱的人
随着竞争的加剧,企业发展过程中不可避免的会有来自各方面的压力,尤其是竞争的压力,心理脆弱将使你挑不起企业的重担,积极锻炼强健的身心才能在未来是赢家。
知识陈旧的人
如今是资讯快速发达的时代,知识更新的速度越来越快,知识倍增的周期越来越短,要想靠早些时候学的知识“应付”一辈子,已完全不可能了。
技能单一的人
要想避免在职场中成为“积压物资”,唯一的办法就是多学几招,一专多能。这就是为什么复合型人才受欢迎的原因。
反应迟钝的人
“迟钝”就会“迟缓”,落后就要挨打,“敏捷”才是胜利的根本。
单独打斗的人
团队协作,沟通协调,合作共事是今后的必然形式,众人拾柴火焰高。
目光短浅的人
有句话说得好,“你能看多远,你便能走多远”。同样,一个人的成长需要不断地规划设计,要注重职业生涯规划,及早发现自己的职业锚,并尽可能匹配自己的工作。
不善学习的人
在当今学习型社会里,人与人之间的差异主要是学习能力的差异,人与人之间的“较量”关键在学习能力的“较量”,要做“学而知之”的人,学而不知或不知如何学的人是早晚会被淘汰的。
工作中八大最易被淘汰的人
情商低下的人
智商显示一个人做事的本领,情商反映一个人做人的表现。在未来的社会里,不仅要 会做事,更要会做人,做人有时比做事更重要。
心理脆弱的人
随着竞争的加剧,企业发展过程中不可避免的会有来自各方面的压力,尤其是竞争的压力,心理脆弱将使你挑不起企业的重担,积极锻炼强健的身心才能在未来是赢家。
知识陈旧的人
如今是资讯快速发达的时代,知识更新的速度越来越快,知识倍增的周期越来越短,要想靠早些时候学的知识“应付”一辈子,已完全不可能了。
技能单一的人
要想避免在职场中成为“积压物资”,唯一的办法就是多学几招,一专多能。这就是为什么复合型人才受欢迎的原因。
反应迟钝的人
“迟钝”就会“迟缓”,落后就要挨打,“敏捷”才是胜利的根本。
单独打斗的人
团队协作,沟通协调,合作共事是今后的必然形式,众人拾柴火焰高。
目光短浅的人
有句话说得好,“你能看多远,你便能走多远”。同样,一个人的成长需要不断地规划设计,要注重职业生涯规划,及早发现自己的职业锚,并尽可能匹配自己的工作。
不善学习的人
在当今学习型社会里,人与人之间的差异主要是学习能力的差异,人与人之间的“较量”关键在学习能力的“较量”,要做“学而知之”的人,学而不知或不知如何学的人是早晚会被淘汰的。
苹果iPhone出炉 超薄iPod Nano取代iPod mini
这款被业界称为iPhone的手机名字是拗口的ROKR,由摩托罗拉公司制造,它内置iTunes音乐播放软件,可以存储100首歌曲,带有彩屏和内置的数码相机。除了内置立体声扬声器,苹果还提供了立体声耳机,同时可以兼作二合一耳机。

不过,手机用户无法直接通过移动网络下载音乐文件,他们必须从电脑中转移文件。这个功能和日本早已普及的“空中音乐”服务相比,稍微有点逊色。
新的iPod播放器名为Nano,它将取代现有的mini系列。和使用硬盘的Mini相比,Nano将采用尚存,这使它重量更轻,也更加节电。Nano的体积仅有Mini的三分之一,重量只有1.5盎司,但苹果称它可以存储1000首歌曲和2.5万张照片。
乔布斯面对嘉宾说:“Nano是自iPod诞生以来最大的革命,它的体积小到难以想像,比一支二号铅笔还薄。” 除了音乐功能,Nano还支持游戏、照片存储和日历,它还带有一个“锁屏”的功能,可以禁止主人以外的用户使用播放器。