- 浏览: 79375 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
KeatsLee:
这篇文章是自己总结的吗?还是来自某本书,麻烦告知一下。觉得很经 ...
Java IO -
di1984HIT:
写的不错啊。
hive 实现多行转一行处理方法 -
di1984HIT:
大数据量分析。
hive海量数据--统计一年网站各个产品的UV
本文主要分析一下 Lucene输入部分——Analyzer(分析器)。为什么要有Analyzer部分呢?打个比方,人体在消化食物的时候,是不是都要把食物分解掉?食物在肠道里面,被分解成葡萄糖、氨基酸、脂肪等等。变成小块以后,才容易被吸收并加以利用。Lucene也有类似的过程:把文本分解成更小的单元,有词、标点符号、分割符号,甚至还有网站名等等。Analyzer就好比是人体的肠道,它的职责就是把输入的文本切成小的单元。
先看一段代码吧:
#0001 public static void TestAnalyzer()
#0002 {
#0003 Analyzer []analyzers = new Analyzer[4];
#0004 analyzers[0] = new WhitespaceAnalyzer();
#0005 analyzers[1] = new SimpleAnalyzer();
#0006 analyzers[2] = new StopAnalyzer();
#0007 analyzers[3] = new StandardAnalyzer();
#0008 String text = "This is a test document. For more info, please visit Victor's Blog: http://lqgao.spaces.msn.com. ";
#0009 for(int i=0; i<analyzers.Length; i++)
#0010 {
#0011 DumpAnalyzer(analyzers[i], new StringReader(text));
#0012 }
#0013 }
#0014
#0015 public static void DumpAnalyzer(Analyzer analyzer, TextReader reader)
#0016 {
#0017 TokenStream stream = analyzer.TokenStream(reader);
#0018 Token token;
#0019 System.Console.WriteLine(analyzer + " :");
#0020 while ((token = stream.Next()) != null)
#0021 {
#0022 System.Console.Write("[" + token.TermText() + "]");
#0023 }
#0024 System.Console.WriteLine();
#0025 System.Console.WriteLine();
#0026 }
运行结果如下:
Lucene.Net.Analysis.WhitespaceAnalyzer :
[This][is][a][test][document.][For][more][info,][please][visit][Victor's][Blog:]
[http://lqgao.spaces.msn.com.]
Lucene.Net.Analysis.SimpleAnalyzer :
[this][is][a][test][document][for][more][info][please][visit][victor][s][blog][h
ttp][lqgao][spaces][msn][com]
Lucene.Net.Analysis.StopAnalyzer :
[test][document][more][info][please][visit][victor][blog][http][lqgao][spaces][m
sn][com]
Lucene.Net.Analysis.Standard.StandardAnalyzer :
[test][document][more][info][please][visit][victor][blog][http][lqgaospacesmsnco
m]
好,让咱们来分析一下。Lucene中默认提供4个Analyzer:SimpleAnalyzer, StandardAnalyzer, StopAnalyzer, WhitespaceAnalyzer。至于这4个有什么区别,听我慢慢道来。
WhitespaceAnalyzer似乎什么都不做,就是按照white space (空格符号)把文本分开——这样做最省力,最简单。
SimpleAnalyzer 则比WhitespaceAnalyzer进步一些,至少不管大写还是小写的字母,统统变成小写形式。这样做的好处也很明显,不管输入是This tHis还是 THIS thIS,最后都统一为this,便于匹配。除了统一大小写外,SimpleAnalyzer还把标点符号处理了,或者说SimpleAnalyzer是按照标点符号分割单词的。比如`documents.’在SimpleAnalyzer的结果中变为`document’。
StopAnalyzer 看起来和SimpleAnalyzer非常相似,只不过,结果中有一些词被去掉了,比如‘this’, ‘is’, ‘a’, ‘for’等——这些大量出现但没有实际意义的词通常被称为stop word(停用词),并被去掉,不加入索引中。因为这样的词数量很大,但并不能很好的区分文档的内容。去掉stop word能减少索引的规模。
StandardAnalyzer做得要复杂一些了。像”Victor’s”这样的词,被处理为’victor’,并没有”’s”,而且网址也被处理了。稍后我们分析StandardAnalyzer的功能。这几个Analyzer的继承关系如图 1所示。
图 1几种analyzer的类层次图
现在回头再看看Analyzer们是怎么工作的(#0015~#0026)。其实Analyzer是一个工厂模式(Factory Pattern),见#0017。使用时需要其生成一个TokenStream的对象。TokenStream,顾名思义,表示token流,即一个 token序列。每个token都是Token类型的。#0020~#0023展现TokenStream的调用方式。
接下来让我们一步一步地展开Analyzers的细节。既然Token是TokenStream组成的元素,让我们先来看看它的“庐山真面目”。
#0001 public sealed class Token
#0002 {
#0003 internal System.String termText; // the text of the term
#0004 internal int startOffset; // start in source text
#0005 internal int endOffset; // end in source text
#0006 internal System.String type_Renamed_Field = "word"; // lexical type
#0007
#0008 private int positionIncrement = 1;
#0009
#0010 public Token(System.String text, int start, int end)
#0011 public Token(System.String text, int start, int end, System.String typ)
#0012
#0013 public void SetPositionIncrement(int positionIncrement)
#0014 public int GetPositionIncrement()
#0015 public System.String TermText()
#0016 public int StartOffset()
#0017 public int EndOffset()
#0018 public System.String Type()
#0019 }
可以看出,Token存储了term的字符串(#0003),并记录下起始和终止位置(#0004~#0005),此外还有一个类型信息(#0006)。DumpAnalyzer中调用了TermText()获取字符串信息。
然后看看TokenStream:
#0001 public abstract class TokenStream
#0002 {
#0003 /// <summary>Returns the next token in the stream, or null at EOS. </summary>
#0004 public abstract Token Next();
#0005
#0006 /// <summary>Releases resources associated with this stream. </summary>
#0007 public virtual void Close()
#0008 {}
#0009 }
TokenStream是一个抽象类,接口只有两个:Next()和Close()。Next()返回当前的token,并指向下一个token;没有token则返回null。
Analyzer也是一个抽象类。默认的TokenStream() (#0005)就是构造并返回一个TokenStream的对象。
#0001 public abstract class Analyzer
#0002 {
#0003 public virtual TokenStream TokenStream(System.IO.TextReader reader)
#0004 {
#0005 return TokenStream(null, reader);
#0006 }
#0007 }
再看它的一个子类WhitespaceTokenizer:
#0001 public class WhitespaceTokenizer:CharTokenizer
#0002 {
#0003 public WhitespaceTokenizer(System.IO.TextReader in_Renamed):base(in_Renamed)
#0004 {}
#0005 protected internal override bool IsTokenChar(char c)
#0006 {
#0007 return !System.Char.IsWhiteSpace(c);
#0008 }
#0009 }
#0010
#0021 public abstract class CharTokenizer : Tokenizer
#0022 {
#0023 public CharTokenizer(System.IO.TextReader input) : base(input)
#0024 {}
#0025
#0026 private int offset = 0, bufferIndex = 0, dataLen = 0;
#0027 private const int MAX_WORD_LEN = 255;
#0028 private const int IO_BUFFER_SIZE = 1024;
#0029 private char[] buffer = new char[MAX_WORD_LEN];
#0030 private char[] ioBuffer = new char[IO_BUFFER_SIZE];
#0031
#0032 protected internal abstract bool IsTokenChar(char c);
#0033 protected internal virtual char Normalize(char c)
#0034 {
#0035 return c;
#0036 }
#0037 public override Token Next()
#0038 {
#0039 int length = 0;
#0040 int start = offset;
#0041 while (true)
#0042 {
#0043 char c;
#0044
#0045 offset++;
#0046 if (bufferIndex >= dataLen)
#0047 {
#0048 dataLen = input.Read((System.Char[]) ioBuffer, 0, ioBuffer.Length);
#0049 bufferIndex = 0;
#0050 }
#0051 ;
#0052 if (dataLen <= 0)
#0053 {
#0054 if (length > 0)
#0055 break;
#0056 else
#0057 return null;
#0058 }
#0059 else
#0060 c = ioBuffer[bufferIndex++];
#0061
#0062 if (IsTokenChar(c))
#0063 {
#0064 // if it's a token char
#0065
#0066 if (length == 0)
#0067 // start of token
#0068 start = offset - 1;
#0069
#0070 buffer[length++] = Normalize(c); // buffer it, normalized
#0071
#0072 if (length == MAX_WORD_LEN)
#0073 // buffer overflow!
#0074 break;
#0075 }
#0076 else if (length > 0)
#0077 // at non-Letter w/ chars
#0078 break; // return 'em
#0079 }
#0080
#0081 return new Token(new System.String(buffer, 0, length), start, start + length);
#0082 }
#0083 }
#0084
#0085
#0086 public abstract class Tokenizer : TokenStream
#0087 {
#0088 protected internal System.IO.TextReader input;
#0089 protected internal Tokenizer()
#0090 {}
#0091 protected internal Tokenizer(System.IO.TextReader input)
#0092 {
#0093 this.input = input;
#0094 }
#0095 public override void Close()
#0096 {
#0097 input.Close();
#0098 }
#0099 }
几个类之间的关系:WhitespaceTokenizerCharTokenizerTokenizerTokenStream。而 CharTokenizer.Next()是一个关键(#0037~#0083)。它从缓冲区中找到分割符(#0062),然后用识别出来的字符串 (#0070)生成一个Token对象(#0081)。其余的Tokenizer只要定义不同的分割符号集合(#0032)就可以了。例如 WhitespaceTokenizer只要告诉Next()“只要不是white space就是分割符号”就可以了(#0005~#0008)。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/alex197963/archive/2008/08/01/2752761.aspx
先看一段代码吧:
#0001 public static void TestAnalyzer()
#0002 {
#0003 Analyzer []analyzers = new Analyzer[4];
#0004 analyzers[0] = new WhitespaceAnalyzer();
#0005 analyzers[1] = new SimpleAnalyzer();
#0006 analyzers[2] = new StopAnalyzer();
#0007 analyzers[3] = new StandardAnalyzer();
#0008 String text = "This is a test document. For more info, please visit Victor's Blog: http://lqgao.spaces.msn.com. ";
#0009 for(int i=0; i<analyzers.Length; i++)
#0010 {
#0011 DumpAnalyzer(analyzers[i], new StringReader(text));
#0012 }
#0013 }
#0014
#0015 public static void DumpAnalyzer(Analyzer analyzer, TextReader reader)
#0016 {
#0017 TokenStream stream = analyzer.TokenStream(reader);
#0018 Token token;
#0019 System.Console.WriteLine(analyzer + " :");
#0020 while ((token = stream.Next()) != null)
#0021 {
#0022 System.Console.Write("[" + token.TermText() + "]");
#0023 }
#0024 System.Console.WriteLine();
#0025 System.Console.WriteLine();
#0026 }
运行结果如下:
Lucene.Net.Analysis.WhitespaceAnalyzer :
[This][is][a][test][document.][For][more][info,][please][visit][Victor's][Blog:]
[http://lqgao.spaces.msn.com.]
Lucene.Net.Analysis.SimpleAnalyzer :
[this][is][a][test][document][for][more][info][please][visit][victor][s][blog][h
ttp][lqgao][spaces][msn][com]
Lucene.Net.Analysis.StopAnalyzer :
[test][document][more][info][please][visit][victor][blog][http][lqgao][spaces][m
sn][com]
Lucene.Net.Analysis.Standard.StandardAnalyzer :
[test][document][more][info][please][visit][victor][blog][http][lqgaospacesmsnco
m]
好,让咱们来分析一下。Lucene中默认提供4个Analyzer:SimpleAnalyzer, StandardAnalyzer, StopAnalyzer, WhitespaceAnalyzer。至于这4个有什么区别,听我慢慢道来。
WhitespaceAnalyzer似乎什么都不做,就是按照white space (空格符号)把文本分开——这样做最省力,最简单。
SimpleAnalyzer 则比WhitespaceAnalyzer进步一些,至少不管大写还是小写的字母,统统变成小写形式。这样做的好处也很明显,不管输入是This tHis还是 THIS thIS,最后都统一为this,便于匹配。除了统一大小写外,SimpleAnalyzer还把标点符号处理了,或者说SimpleAnalyzer是按照标点符号分割单词的。比如`documents.’在SimpleAnalyzer的结果中变为`document’。
StopAnalyzer 看起来和SimpleAnalyzer非常相似,只不过,结果中有一些词被去掉了,比如‘this’, ‘is’, ‘a’, ‘for’等——这些大量出现但没有实际意义的词通常被称为stop word(停用词),并被去掉,不加入索引中。因为这样的词数量很大,但并不能很好的区分文档的内容。去掉stop word能减少索引的规模。
StandardAnalyzer做得要复杂一些了。像”Victor’s”这样的词,被处理为’victor’,并没有”’s”,而且网址也被处理了。稍后我们分析StandardAnalyzer的功能。这几个Analyzer的继承关系如图 1所示。
图 1几种analyzer的类层次图
现在回头再看看Analyzer们是怎么工作的(#0015~#0026)。其实Analyzer是一个工厂模式(Factory Pattern),见#0017。使用时需要其生成一个TokenStream的对象。TokenStream,顾名思义,表示token流,即一个 token序列。每个token都是Token类型的。#0020~#0023展现TokenStream的调用方式。
接下来让我们一步一步地展开Analyzers的细节。既然Token是TokenStream组成的元素,让我们先来看看它的“庐山真面目”。
#0001 public sealed class Token
#0002 {
#0003 internal System.String termText; // the text of the term
#0004 internal int startOffset; // start in source text
#0005 internal int endOffset; // end in source text
#0006 internal System.String type_Renamed_Field = "word"; // lexical type
#0007
#0008 private int positionIncrement = 1;
#0009
#0010 public Token(System.String text, int start, int end)
#0011 public Token(System.String text, int start, int end, System.String typ)
#0012
#0013 public void SetPositionIncrement(int positionIncrement)
#0014 public int GetPositionIncrement()
#0015 public System.String TermText()
#0016 public int StartOffset()
#0017 public int EndOffset()
#0018 public System.String Type()
#0019 }
可以看出,Token存储了term的字符串(#0003),并记录下起始和终止位置(#0004~#0005),此外还有一个类型信息(#0006)。DumpAnalyzer中调用了TermText()获取字符串信息。
然后看看TokenStream:
#0001 public abstract class TokenStream
#0002 {
#0003 /// <summary>Returns the next token in the stream, or null at EOS. </summary>
#0004 public abstract Token Next();
#0005
#0006 /// <summary>Releases resources associated with this stream. </summary>
#0007 public virtual void Close()
#0008 {}
#0009 }
TokenStream是一个抽象类,接口只有两个:Next()和Close()。Next()返回当前的token,并指向下一个token;没有token则返回null。
Analyzer也是一个抽象类。默认的TokenStream() (#0005)就是构造并返回一个TokenStream的对象。
#0001 public abstract class Analyzer
#0002 {
#0003 public virtual TokenStream TokenStream(System.IO.TextReader reader)
#0004 {
#0005 return TokenStream(null, reader);
#0006 }
#0007 }
再看它的一个子类WhitespaceTokenizer:
#0001 public class WhitespaceTokenizer:CharTokenizer
#0002 {
#0003 public WhitespaceTokenizer(System.IO.TextReader in_Renamed):base(in_Renamed)
#0004 {}
#0005 protected internal override bool IsTokenChar(char c)
#0006 {
#0007 return !System.Char.IsWhiteSpace(c);
#0008 }
#0009 }
#0010
#0021 public abstract class CharTokenizer : Tokenizer
#0022 {
#0023 public CharTokenizer(System.IO.TextReader input) : base(input)
#0024 {}
#0025
#0026 private int offset = 0, bufferIndex = 0, dataLen = 0;
#0027 private const int MAX_WORD_LEN = 255;
#0028 private const int IO_BUFFER_SIZE = 1024;
#0029 private char[] buffer = new char[MAX_WORD_LEN];
#0030 private char[] ioBuffer = new char[IO_BUFFER_SIZE];
#0031
#0032 protected internal abstract bool IsTokenChar(char c);
#0033 protected internal virtual char Normalize(char c)
#0034 {
#0035 return c;
#0036 }
#0037 public override Token Next()
#0038 {
#0039 int length = 0;
#0040 int start = offset;
#0041 while (true)
#0042 {
#0043 char c;
#0044
#0045 offset++;
#0046 if (bufferIndex >= dataLen)
#0047 {
#0048 dataLen = input.Read((System.Char[]) ioBuffer, 0, ioBuffer.Length);
#0049 bufferIndex = 0;
#0050 }
#0051 ;
#0052 if (dataLen <= 0)
#0053 {
#0054 if (length > 0)
#0055 break;
#0056 else
#0057 return null;
#0058 }
#0059 else
#0060 c = ioBuffer[bufferIndex++];
#0061
#0062 if (IsTokenChar(c))
#0063 {
#0064 // if it's a token char
#0065
#0066 if (length == 0)
#0067 // start of token
#0068 start = offset - 1;
#0069
#0070 buffer[length++] = Normalize(c); // buffer it, normalized
#0071
#0072 if (length == MAX_WORD_LEN)
#0073 // buffer overflow!
#0074 break;
#0075 }
#0076 else if (length > 0)
#0077 // at non-Letter w/ chars
#0078 break; // return 'em
#0079 }
#0080
#0081 return new Token(new System.String(buffer, 0, length), start, start + length);
#0082 }
#0083 }
#0084
#0085
#0086 public abstract class Tokenizer : TokenStream
#0087 {
#0088 protected internal System.IO.TextReader input;
#0089 protected internal Tokenizer()
#0090 {}
#0091 protected internal Tokenizer(System.IO.TextReader input)
#0092 {
#0093 this.input = input;
#0094 }
#0095 public override void Close()
#0096 {
#0097 input.Close();
#0098 }
#0099 }
几个类之间的关系:WhitespaceTokenizerCharTokenizerTokenizerTokenStream。而 CharTokenizer.Next()是一个关键(#0037~#0083)。它从缓冲区中找到分割符(#0062),然后用识别出来的字符串 (#0070)生成一个Token对象(#0081)。其余的Tokenizer只要定义不同的分割符号集合(#0032)就可以了。例如 WhitespaceTokenizer只要告诉Next()“只要不是white space就是分割符号”就可以了(#0005~#0008)。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/alex197963/archive/2008/08/01/2752761.aspx
发表评论
-
设置JVM启动属性,设置tomcat远程调试端口
2013-02-12 17:08 963在eclipse中设置启动属性,或者在命令行运行时设置 ... -
Mysql不能连接
2011-01-11 11:07 1044com.mysql.jdbc.CommunicationsEx ... -
Java IO
2011-01-04 12:08 2227本篇主要讲述IO相关的 ... -
[J2SE]Map.Entry 类使用简介(转)
2010-12-10 09:30 846你是否已经对每次从Map中取得关键字然后再取得相应的值感觉厌倦 ... -
比较分析Vector,Arraylist,Hashtable,HashMap数据结构
2010-12-09 09:15 778线性表,链表,哈希表 ... -
JAVA jvm 参数 -Xms -Xmx -Xmn -Xss
2010-11-04 14:40 1153常见配置举例 堆大小 ... -
Error listenerStart
2010-11-04 14:37 795近日浏览论坛,发现好多人提问,都说在运行web程序时,服务器报 ... -
jvm内存调优经验总结
2010-11-04 14:37 807[color=blue][/color][size=x-sma ... -
java的final和static区别
2010-10-19 10:30 814final定义的变量可以看 ... -
Java设计模式中的11种
2010-10-14 17:35 790一:设计模式是最重要 ... -
ik-analyzer
2010-08-02 15:05 962IKAnalyzer是一个开源的,基于java语言开发的轻量级 ... -
Apache Tika文档处理工具
2010-08-02 13:58 2860随着计算机使用的日益普及以及互联网的无处不在,现在有各种语言的 ... -
JDK性能优化
2010-07-29 10:35 1567jvm的server版和client版在上面的表中,我们看到有 ... -
JDK和JRE的区别
2010-07-29 09:49 822简单的说JDK是面向开发人员使用的SDK,它提供了Java的开 ... -
JAVA Process类的简单学习
2010-07-08 14:59 1345(1)执行简单的DOS命令,如打开一个记事本 ... -
Java的多线程程序设计要点
2010-07-07 09:15 6471.多线程中有主内存和 ... -
Java打包指南-JAR文件包及jar命令详解
2010-07-06 17:28 760常常在网上看到有人询问:如何把 java 程序编译成 .exe ... -
javac编译包及包引用文件
2010-07-06 17:27 2254javac和java是sun提供的编译java文件和执行cla ... -
JAVA RMI实现过程分析
2010-07-06 14:35 1717JAVA RMI 快速入门实例 本实例为参考多篇文章写就而成 ... -
CompletionService
2010-07-05 16:00 956import java.util.concurrent. ...
相关推荐
开源全文搜索工具包Lucene2.9.1的使用。 1. 搭建Lucene的开发环境:在classpath中添加lucene-core-2.9.1.jar包 2. 全文搜索的两个工作: 建立索引文件,搜索索引. 3. Lucene的索引文件逻辑结构 1) 索引(Index)由...
新版本的IKAnalyzer3.0则发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。 IKAnalyzer3.0特性: 采用了特有的“正向迭代最细粒度切分算法“,具有60万字/秒的高速处理能力...
word源码java Elasticsearch 的 IK 分析 IK Analysis插件将Lucene IK分析器()集成到elasticsearch中,支持自定义字典。 分析器: ik_smart , ik_max_word ,分词器: ik_smart , ik_max_word 版本 IK版 ES版 掌握 ...
IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。...从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了
从3.0版本开 始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词 歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。 ...
Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来...
笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!此时此...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...
AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是...