luncene 查询字符串的解析—QueryParser类
http://blog.csdn.net/hongfu_/article/details/1933366
搜索流程中的第二步就是构建一个Query。下面就来介绍Query及其构建。
当用户输入一个关键字,搜索引擎接收到后,并不是立刻就将它放入后台开始进行关键字的检索,而应当首先对这个关键字进行一定的分析和处理,使之成为一种后台可以理解的形式,只有这样,才能提高检索的效率,同时检索出更加有效的结果。那么,在Lucene中,这种处理,其实就是构建一个Query对象。
就Query对象本身言,它只是Lucene的search包中的一个抽象类,这个抽象类有许多子类,代表了不同类型的检索。如常见的TermQuery就是将一个简单的关键字进行封装后的对象,类似的还有BooleanQuery,即布尔型的查找。
IndexSearcher对象的search方法中总是需要一个Query对象(或是Query子类的对象),本节就来介绍各种Query类。
11.4.1 按词条搜索—TermQuery
TermQuery是最简单、也是最常用的Query。TermQuery可以理解成为“词条搜索”,在搜索引擎中最基本的搜索就是在索引中搜索某一词条,而TermQuery就是用来完成这项工作的。
在Lucene中词条是最基本的搜索单位,从本质上来讲一个词条其实就是一个名/值对。只不过这个“名”是字段名,而“值”则表示字段中所包含的某个关键字。
要使用TermQuery进行搜索首先需要构造一个Term对象,示例代码如下:
Term aTerm = new Term("contents", "java");
然后使用aTerm对象为参数来构造一个TermQuery对象,代码设置如下:
Query query = new TermQuery(aTerm);
这样所有在“contents”字段中包含有“java”的文档都会在使用TermQuery进行查询时作为符合查询条件的结果返回。
下面就通过代码11.4来介绍TermQuery的具体实现过程。
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
public static void main(String[] args) throws Exception
Document doc1 = new Document();
doc1.add(Field.Text("name", "word1 word2 word3"));
doc1.add(Field.Keyword("title", "doc1"));
IndexWriter writer = new IndexWriter("c://index", new StandardAnalyzer(), true);
IndexSearcher searcher = new IndexSearcher("c://index");
query = new TermQuery(new Term("name","word1"));
hits = searcher.search(query);
// 再次构造一个TermQuery对象,只不过查询的字段变成了"title"
query = new TermQuery(new Term("title","doc1"));
hits = searcher.search(query);
public static void printResult(Hits hits, String key) throws Exception
System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
System.out.println("找到" + hits.length() + "个结果");
for (int i = 0; i < hits.length(); i++)
String dname = d.get("title");
System.out.print(dname + " ");
在代码11.4中使用TermQuery进行检索的运行结果如图11-8所示。
注意:字段值是区分大小写的,因此在查询时必须注意大小写的匹配。
从图11-8中可以看出,代码11.4两次分别以“word1”和“doc1”为关键字进行检索,并且都只得到了一个检索结果。
11.4.2 “与或”搜索—BooleanQuery
public void add(Query query, boolean required, boolean prohibited);
注意:BooleanQuery是可以嵌套的,一个BooleanQuery可以成为另一个BooleanQuery的条件子句。
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
public class BooleanQueryTest1
public static void main (String [] args) throws Exception {
Document doc1 = new Document();
doc1.add(Field.Text("name", "word1 word2 word3"));
doc1.add(Field.Keyword("title", "doc1"));
Document doc2 = new Document();
doc2.add(Field.Text("name", "word1 word4 word5"));
doc2.add(Field.Keyword("title", "doc2"));
Document doc3 = new Document();
doc3.add(Field.Text("name", "word1 word2 word6"));
doc3.add(Field.Keyword("title", "doc3"));
IndexWriter writer = new IndexWriter("c://index", new StandardAnalyzer(), true);
IndexSearcher searcher = new IndexSearcher("c://index");
query1 = new TermQuery(new Term("name","word1"));
query2 = new TermQuery(new Term("name","word2"));
query.add(query1, true, false);
query.add(query2, true, false);
hits = searcher.search(query);
printResult(hits, "word1和word2");
public static void printResult(Hits hits, String key) throws Exception
System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
System.out.println("找到" + hits.length() + "个结果");
for (int i = 0; i < hits.length(); i++)
String dname = d.get("title");
System.out.print(dname + " ");
代码11.5首先构造了两个TermQuery,然后构造了一个BooleanQuery的对象,并将两个TermQuery当成它的查询子句加入Boolean查询中。
由前面的示例可以看出由于加入的两个子句都选用了true&false的组合,因此它们两个都是需要被满足的,也就构成了实际上的“与”关系,运行效果如图11-9所示。
query.add(query1, false, false);
query.add(query2, false, false);
图11-9 BooleanQuery测试1 图11-10 BooleanQuery测试2
由于布尔型的查询是可以嵌套的,因此可以表示多种条件下的组合。不过,如果子句的数目太多,可能会导致查找效率的降低。因此,Lucene给出了一个默认的限制,就是布尔型Query的子句数目不能超过1024。
11.4.3 在某一范围内搜索—RangeQuery
有时用户会需要一种在一个范围内查找某个文档,比如查找某一时间段内的所有文档,此时,Lucene提供了一种名为RangeQuery的类来满足这种需求。
RangeQuery表示在某范围内的搜索条件,实现从一个开始词条到一个结束词条的搜索功能,在查询时“开始词条”和“结束词条”可以被包含在内也可以不被包含在内。它的具体用法如下:
RangeQuery query = new RangeQuery(begin, end, included);
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.RangeQuery;
public static void main (String [] args) throws Exception {
Document doc1 = new Document();
doc1.add(Field.Text("time", "200001"));
doc1.add(Field.Keyword("title", "doc1"));
Document doc2 = new Document();
doc2.add(Field.Text("time", "200002"));
doc2.add(Field.Keyword("title", "doc2"));
Document doc3 = new Document();
doc3.add(Field.Text("time", "200003"));
doc3.add(Field.Keyword("title", "doc3"));
Document doc4 = new Document();
doc4.add(Field.Text("time", "200004"));
doc4.add(Field.Keyword("title", "doc4"));
Document doc5 = new Document();
doc5.add(Field.Text("time", "200005"));
doc5.add(Field.Keyword("title", "doc5"));
IndexWriter writer = new IndexWriter("c://index", new StandardAnalyzer(), true);
writer.setUseCompoundFile(true);
IndexSearcher searcher = new IndexSearcher("c://index");
Term beginTime = new Term("time","200001");
Term endTime = new Term("time","200005");
query = new RangeQuery(beginTime, endTime, false);
hits = searcher.search(query);
printResult(hits, "从200001~200005的文档,不包括200001和200005");
//再构造一个RangeQuery对象,检索条件中包含边界值
query = new RangeQuery(beginTime, endTime, true);
hits = searcher.search(query);
printResult(hits, "从200001~200005的文档,包括200001和200005");
public static void printResult(Hits hits, String key) throws Exception
{System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
for (int i = 0; i < hits.length(); i++) {
String dname = d.get("title");
System.out.print(dname + " " );
构建的Document的“time”字段值均介于200001~200005之间,其检索结果如图11-11所示。
从图11-11中可以看出,在代码11.6中使用RangeQuery共进行了两次检索,第一次的检索条件中不包括边界值,第二次的检索条件中包括边界值。
11.4.4 使用前缀搜索—PrefixQuery
PrefixQuery就是使用前缀来进行查找的。通常情况下,首先定义一个词条Term。该词条包含要查找的字段名以及关键字的前缀,然后通过该词条构造一个PrefixQuery对象,就可以进行前缀查找了。
下面以代码11.7为例来介绍使用PrefixQuery进行检索的运行过程。
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.RangeQuery;
public class PrefixQueryTest {
public static void main(String[] args) throws Exception {
Document doc1 = new Document();
doc1.add(Field.Text("name", "David"));
doc1.add(Field.Keyword("title", "doc1"));
Document doc2 = new Document();
doc2.add(Field.Text("name", "Darwen"));
doc2.add(Field.Keyword("title", "doc2"));
Document doc3 = new Document();
doc3.add(Field.Text("name", "Smith"));
doc3.add(Field.Keyword("title", "doc3"));
Document doc4 = new Document();
doc4.add(Field.Text("name", "Smart"));
doc4.add(Field.Keyword("title", "doc4"));
IndexWriter writer = new IndexWriter("c://index",
new StandardAnalyzer(), true);
writer.setUseCompoundFile(true);
IndexSearcher searcher = new IndexSearcher("c://index");
Term pre1 = new Term("name", "Da");
Term pre2 = new Term("name", "da");
Term pre3 = new Term("name", "sm");
query = new PrefixQuery(pre1);
hits = searcher.search(query);
printResult(hits, "前缀为'Da'的文档");
query = new PrefixQuery(pre2);
hits = searcher.search(query);
printResult(hits, "前缀为'da'的文档");
query = new PrefixQuery(pre3);
hits = searcher.search(query);
printResult(hits, "前缀为'sm'的文档");
public static void printResult(Hits hits, String key) throws Exception
{System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
for (int i = 0; i < hits.length(); i++) {
String dname = d.get("title");
System.out.print(dname + " ");
11.4.5 多关键字的搜索—PhraseQuery
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
public class PhraseQueryTest {
public static void main(String[] args) throws Exception {
Document doc1 = new Document();
doc1.add(Field.Text("content", "david mary smith robert"));
doc1.add(Field.Keyword("title", "doc1"));
IndexWriter writer = new IndexWriter("c://index",
new StandardAnalyzer(), true);
writer.setUseCompoundFile(true);
IndexSearcher searcher = new IndexSearcher("c://index");
Term word1 = new Term("content", "david");
Term word2 = new Term("content","mary");
Term word3 = new Term("content","smith");
Term word4 = new Term("content","robert");
// 第一种情况,两个词本身紧密相连,先设置坡度为0,再设置坡度为2
hits = searcher.search(query);
printResult(hits, "'david'与'mary'紧紧相隔的Document");
hits = searcher.search(query);
printResult(hits, "'david'与'mary'中相隔两个词的短语");
// 第二种情况,两个词本身相隔两个词,先设置坡度为0,再设置坡度为2
hits = searcher.search(query);
printResult(hits, "'david'与'robert'紧紧相隔的Document");
hits = searcher.search(query);
printResult(hits, "'david'与'robert'中相隔两个词的短语");
public static void printResult(Hits hits, String key) throws Exception
{System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
for (int i = 0; i < hits.length(); i++) {
String dname = d.get("title");
System.out.print(dname + " ");
从图11.8中可以看出,代码11.8共进行了4次检索测试,并且分两组分别对检索结果进行对比。
11.4.6 使用短语缀搜索—PhrasePrefixQuery
接下来看看在代码11.9中是如何使用PhrasePrefixQuery来实现的。
代码11.9 PhrasePrefixQueryTest.java
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PhrasePrefixQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.RangeQuery;
public class PhrasePrefixQueryTest {
public static void main(String[] args) throws Exception {
Document doc1 = new Document();
doc1.add(Field.Text("content", "david mary smith robert"));
doc1.add(Field.Keyword("title", "doc1"));
IndexWriter writer = new IndexWriter("c://index",
new StandardAnalyzer(), true);
IndexSearcher searcher = new IndexSearcher("c://index");
Term word1 = new Term("content", "david");
Term word2 = new Term("content", "mary");
Term word3 = new Term("content", "smith");
Term word4 = new Term("content", "robert");
//生成PhrasePrefixQuery对象,初始化为null
PhrasePrefixQuery query = null;
query = new PhrasePrefixQuery();
query.add(new Term[]{word1, word2});
hits = searcher.search(query);
printResult(hits, "存在短语'david robert'或'mary robert'的文档");
public static void printResult(Hits hits, String key) throws Exception
{System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
for (int i = 0; i < hits.length(); i++) {
String dname = d.get("title");
System.out.print(dname + " ");
从图11-14中可以看出,使用PhrasePrefixQuery可以非常容易的实现相关短语的检索功能。
11.4.7 相近词语的搜索—FuzzyQuery
FuzzyQuery是一种模糊查询,它可以简单地识别两个相近的词语。下面以11.10为例进行详细介绍。
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
public static void main(String[] args) throws Exception {
Document doc1 = new Document();
doc1.add(Field.Text("content", "david"));
doc1.add(Field.Keyword("title", "doc1"));
Document doc2 = new Document();
doc2.add(Field.Text("content", "sdavid"));
doc2.add(Field.Keyword("title", "doc2"));
Document doc3 = new Document();
doc3.add(Field.Text("content", "davie"));
doc3.add(Field.Keyword("title", "doc3"));
IndexWriter writer = new IndexWriter("c://index",
new StandardAnalyzer(), true);
IndexSearcher searcher = new IndexSearcher("c://index");
Term word1 = new Term("content", "david");
query = new FuzzyQuery(word1);
hits = searcher.search(query);
printResult(hits,"与'david'相似的词");
public static void printResult(Hits hits, String key) throws Exception
{System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
for (int i = 0; i < hits.length(); i++) {
String dname = d.get("title");
System.out.print(dname + " ");
从图11-15中可以看出,使用FuzzyQuery可以检索到索引中所有包含与“david”相近词语的文档。
11.4.8 使用通配符搜索—WildcardQuery
Lucene也提供了通配符的查询,这就是WildcardQuery。下面以代码11.11为例进行介绍。
代码11.11 WildcardQueryTest.java
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.WildcardQuery;
public class WildcardQueryTest {
public static void main(String[] args) throws Exception {
Document doc1 = new Document();
doc1.add(Field.Text("content", "whatever"));
doc1.add(Field.Keyword("title", "doc1"));
Document doc2 = new Document();
doc2.add(Field.Text("content", "whoever"));
doc2.add(Field.Keyword("title", "doc2"));
Document doc3 = new Document();
doc3.add(Field.Text("content", "however"));
doc3.add(Field.Keyword("title", "doc3"));
Document doc4 = new Document();
doc4.add(Field.Text("content", "everest"));
doc4.add(Field.Keyword("title", "doc4"));
IndexWriter writer = new IndexWriter("c://index",
new StandardAnalyzer(), true);
IndexSearcher searcher = new IndexSearcher("c://index");
Term word1 = new Term("content", "*ever");
Term word2 = new Term("content", "wh?ever");
Term word3 = new Term("content", "h??ever");
Term word4 = new Term("content", "ever*");
query = new WildcardQuery(word1);
hits = searcher.search(query);
query = new WildcardQuery(word2);
hits = searcher.search(query);
query = new WildcardQuery(word3);
hits = searcher.search(query);
query = new WildcardQuery(word4);
hits = searcher.search(query);
public static void printResult(Hits hits, String key) throws Exception
{System.out.println("查找 /"" + key + "/" :");
System.out.println("没有找到任何结果");
for (int i = 0; i < hits.length(); i++) {
String dname = d.get("title");
System.out.print(dname + " ");
由上述代码可以看出,通配符“?”代表1个字符,而“*”则代表0至多个字符。不过通配符检索和上面的FuzzyQuery由于需要对字段关键字进行字符串匹配,所以,在搜索的性能上面会受到一些影响。
对于搜索引擎(比如Google和百度)来讲,很多情况下只需要用户在输入框内输入所需查询的内容,然后再单击“搜索”就可以了,其余的事情全部交给搜索引擎去处理,最后搜索引擎会把检索到的结果显示出来。那么搜索引擎是怎样处理用户输入得符号串的呢?
在Lucene中,这项工作就交给了QueryParser类来完成,它的作用就是把各种用户输入的符号串转为一个内部的Query或者一个Query组。虽然Lucene提供的API允许使用者创建各种各样的Query(查询语句),但它同时也允许通过QueryParser(查询分析器)生成各种各样的Query子对象。这使得Lucene的查询功能更加灵活和强大。
11.5.1 QueryParser的简单用法
QueryParser实际上就是一个解析用户输入的工具,可以通过扫描用户输入的字符串,生成Query对象,以下是一个代码示例:
query = QueryParser.parse(keywords,fieldName,new StandardAnalyzer());
用户输入关键字的格式以及QueryParser所理解的含义如表11-2所示。
表11-2 输入关键字格式和QueryParser理解的含义
格 式 |
含 义 |
“David” |
在默认的字段中检索“David”关键字 |
“content:David” |
在“content”字段中检索“David”关键字 |
“David Mary”或“David OR Mary” |
在默认字段中检索David和Mary关键字,它们是“或”关系 |
“+David +Mary”或“David AND Mary” |
在默认字段中检索David和Mary关键字,它们是“与”关系 |
“content:David –title:Manager”或“content:David AND NOT title:Manager” |
在content字段中包括关键字David但在title字段中不包含关键字Manager |
“(David OR Mary) AND Robert” |
在默认字段中包含David或Mary关键字,但一定要包含Robert关键字 |
Davi* |
在默认字段中检索前缀为Davi |
“content:"David is a manager"” |
在“content”字段中包含短语“David is a manager” |
11.5.2 QueryParser的“与”和“或”
通过表11-1可以了解,当用户输入两个关键字时,QueryParser默认它们之间的关系为“或”关系。如果用户需要改变这种逻辑关系,则可采用下面的方法:
QueryParser parser = new QueryParser(fieldName, new StandardAnalyzer());
parser.setOperator(QueryParser.DEFAULT_OPERATOR_AND);
这样构建的QueryParser实例在对用户输入进行扫描时,就会用空格分开的关键字理解为“与”,其实也就是构建了一个“与”关系的布尔型查询。
luncene 查询字符串的解析—QueryParser类相关推荐
- Nodejs--querystring (URL 查询字符串)
2019独角兽企业重金招聘Python工程师标准>>> querystring 模块提供了一些实用函数,用于解析与格式化 URL 查询字符串 querystring.parse(st ...
- 解析php变量,php使用parse_str实现查询字符串解析到变量中的方法
本文实例讲述了php使用parse_str实现查询字符串解析到变量中的方法.分享给大家供大家参考,具体如下: parse_str()函数可实现把字符串解析到变量中,这意味着实现了字符串与变量之间的一种 ...
- 在JavaScript中解析查询字符串[重复]
本文翻译自:Parse query string in JavaScript [duplicate] Possible Duplicate: 可能重复: How can I get query str ...
- java解析mdb文件_Access MDB文件解析查询,Access数据库解析工具类MdbUtils
Access MDB文件解析查询,Access数据库解析工具类MdbUtils ================================ ©Copyright 蕃薯耀 2018年9月18日 h ...
- Gin 框架学习笔记(01)— 自定义结构体绑定表单、绑定URI、自定义log、自定义中间件、路由组、解析查询字符串、上传文件、使用HTTP方法
要实现一个 API 服务器,首先要考虑两个方面:API 风格和媒体类型.Go 语言中常用的 API 风格是 RPC 和 REST,常用的媒体类型是 JSON.XML 和 Protobuf.在 Go A ...
- NPM酷库:qs,解析URL查询字符串
NPM酷库,每天两分钟,了解一个流行NPM库. Node.js 标准库中有一个库叫querystring,这个库用来处理URL查询字符串: const querystring = require('q ...
- 用于将带有查询字符串的复杂对象传递到Web API方法的自定义模型绑定器
目录 介绍 查询复杂对象的字符串字段 使用和测试FieldValueModelBinder类 FieldValueModelBinder如何工作? 获取源字段和值 将字段部分与对象属性匹配 解析枚举类 ...
- mysql源代码解析经典类——THD类
1.1 线程类THD概述 对于每个客户端连接,我们使用THD作为线程/连接描述符创建一个单独的线程. 1.2 位置 #include <sql_class.h> 嵌套类 //表示只读可连接 ...
- [Android开发] Json解析工具类,一个类搞定Json的解析
一.简介 利用递归的方式反射解析到bean里面 二.详细代码 1. Json格式 例如服务器指定规定json格式为: {"code": "--" , // 返回 ...
最新文章
- Mason 简单笔记
- 将PS/2接口鼠标改造成USB接口鼠标
- LINQ to XML .Net 3.5 中的新XML对象
- nginx可以负载均衡多个tomcat,nginx主机挂了怎么办?Keepalived
- 微信开发学习日记(二):3个案例
- java 简单图片浏览器_Java实现简单的图片浏览器
- 《深入理解分布式事务》第四章 分布式事务的基本概念和理论知识
- AI PRO I 第4章 译文 Behavior Selection Algorithms An Overview
- Angular Js 判断对象不为空对象的三种方法
- 一句话菜刀 php eval,如何基于菜刀PHP一句话实现单个文件批量上传?
- Java使用JNA调用SWMM模型的DLL
- 使用pano2vr生成html5全景页面
- 可以下载solidworks2007 完整版的连接
- 四、音频如何从USB输入输出
- luogu P2706 巧克力
- java 根据word文档模板导出word
- 纹理分析及其在医学成像中的应用
- 4.3 51单片机-串口通信
- 微信聊天记录备份:当前网络状况复杂和连接失败的解决办法
- Geek的卸载存在小小缺憾
热门文章
- 2021-10-11 寻找二叉树结点的前驱或后继结点(用到parent指针)
- 2021-9-下旬 数据结构-线性表-链表-java代码实现(复习用)
- 前端面试中常见的算法问题
- 读书几年收藏的编程利器网站,给大家分享出来
- java.util.Map中put,computeIfAbsent与putIfAbsent区别
- 顺序栈实现括号匹配的检验(C语言实现)【栈】
- mapinfo制作地图_Mapinfo操作不太会?看这篇就够了
- python字符编码转换_Python字符和字符值(ASCII或Unicode码值)转换方法
- c语言 sizeof size_t,C/C++中的sizeof运算符和size_t类型的详解
- xp mysql字符集与乱码_mysql字符集(GBK、GB2312、UTF8)与中文乱码的原因及解决