set.go

// set project set.go
package set type Set interface {
Add(e interface{}) bool
Remove(e interface{})
Clear()
Contains(e interface{}) bool
Len() int
Same(other Set) bool
Elements() []interface{}
String() string
} // 将集合other添加到集合one中
func AddSet(one Set, other Set) {
if one == nil || other == nil || other.Len() == {
return
}
for _, v := range other.Elements() {
one.Add(v)
}
} // 判断集合 one 是否是集合 other 的超集
func IsSuperset(one Set, other Set) bool {
if one == nil || other == nil {
return false
}
oneLen := one.Len()
otherLen := other.Len()
if oneLen == || oneLen <= otherLen {
return false
}
if oneLen > && otherLen == {
return true
}
for _, v := range other.Elements() {
if !one.Contains(v) {
return false
}
}
return true
} // 生成集合 one 和集合 other 的并集
func Union(one Set, other Set) Set {
if one == nil && other == nil {
return nil
}
unionedSet := NewSimpleSet()
AddSet(unionedSet, one)
AddSet(unionedSet, other)
return unionedSet
} // 生成集合 one 和集合 other 的交集
func Intersect(one Set, other Set) Set {
if one == nil || other == nil {
return nil
}
intersectedSet := NewSimpleSet()
if one.Len() == || other.Len() == {
return intersectedSet
}
if one.Len() < other.Len() {
for _, v := range one.Elements() {
if other.Contains(v) {
intersectedSet.Add(v)
}
}
} else {
for _, v := range other.Elements() {
if one.Contains(v) {
intersectedSet.Add(v)
}
}
}
return intersectedSet
} // 生成集合 one 对集合 other 的差集
func Difference(one Set, other Set) Set {
if one == nil {
return nil
}
differencedSet := NewSimpleSet()
if other == nil || other.Len() == {
AddSet(differencedSet, one)
return differencedSet
}
for _, v := range one.Elements() {
if !other.Contains(v) {
differencedSet.Add(v)
}
}
return differencedSet
} // 生成集合 one 和集合 other 的对称差集
func SymmetricDifference(one Set, other Set) Set {
diffA := Difference(one, other)
if other == nil || other.Len() == {
return diffA
}
diffB := Difference(other, one)
return Union(diffA, diffB)
} // 返回一个HashSet
func NewSimpleSet() Set {
return NewHashSet()
} // 判断给定value是否为集合
func IsSet(value interface{}) bool {
if _, ok := value.(Set); ok {
return true
}
return false
}

hash_set.go

// hash_set
package set import (
"bytes"
"fmt"
) type HashSet struct {
m map[interface{}]bool
} // 创建和初始化HashSet的方法
func NewHashSet() *HashSet {
return &HashSet{m: make(map[interface{}]bool)}
} // 向HashSet中添加元素的方法
func (set *HashSet) Add(e interface{}) bool {
if !set.m[e] {
set.m[e] = true
return true
}
return false
} // 删除HashSet中指定的元素
func (set *HashSet) Remove(e interface{}) {
delete(set.m, e)
} // 清除HashSet中的所有元素
func (set *HashSet) Clear() {
set.m = make(map[interface{}]bool)
} // 判断HashSet是否包含指定元素
func (set *HashSet) Contains(e interface{}) bool {
return set.m[e]
} // 获取HashSet中元素值数量
func (set *HashSet) Len() int {
return len(set.m)
} // 判断两个Set类型值是否相同
func (set *HashSet) Same(other Set) bool {
if other == nil {
return false
}
if set.Len() != other.Len() {
return false
}
for key := range set.m {
if !other.Contains(key) {
return false
}
}
return true
} // 生成HashSet的一个快照
func (set *HashSet) Elements() []interface{} {
initialLen := len(set.m)
snapshot := make([]interface{}, initialLen)
actualLen :=
for key := range set.m {
if actualLen < initialLen {
snapshot[actualLen] = key
} else {
snapshot = append(snapshot, key)
}
actualLen++
}
if actualLen < initialLen {
snapshot = snapshot[:actualLen]
}
return snapshot
} // 获取HashSet自身字符串表示形式
func (set *HashSet) String() string {
var buf bytes.Buffer
buf.WriteString("Set{")
first := true
for key := range set.m {
if first {
first = false
} else {
buf.WriteString(" ")
}
buf.WriteString(fmt.Sprintf("%v", key))
}
buf.WriteString("}")
return buf.String()
}

功能测试:

set_test.go

// set_test
package set import (
"bytes"
"fmt"
"math/rand"
"runtime/debug"
"strings"
"testing"
"time"
) func testSetLenAndContains(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sLenAndContains...", typeName)
set, expectedElemMap := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
expectedLen := len(expectedElemMap)
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of %s value %d is not %d!\n",
set.Len(), typeName, expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
for k := range expectedElemMap {
if !set.Contains(k) {
t.Errorf("ERROR: The %s value %v do not contains %v!",
set, typeName, k)
t.FailNow()
}
}
} func testSetAdd(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sAdd...", typeName)
set := newSet()
var randElem interface{}
var result bool
expectedElemMap := make(map[interface{}]bool)
for i := ; i < ; i++ {
randElem = genRandElement()
t.Logf("Add %v to the %s value %v.\n", randElem, typeName, set)
result = set.Add(randElem)
if expectedElemMap[randElem] && result {
t.Errorf("ERROR: The element adding (%v => %v) is successful but should be failing!\n",
randElem, set)
t.FailNow()
}
if !expectedElemMap[randElem] && !result {
t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",
randElem, set)
t.FailNow()
}
expectedElemMap[randElem] = true
}
t.Logf("The %s value: %v.", typeName, set)
expectedLen := len(expectedElemMap)
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of %s value %d is not %d!\n",
set.Len(), typeName, expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
for k := range expectedElemMap {
if !set.Contains(k) {
t.Errorf("ERROR: The %s value %v do not contains %v!",
set, typeName, k)
t.FailNow()
}
}
} func testSetRemove(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sRemove...", typeName)
set, expectedElemMap := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
var number int
for k, _ := range expectedElemMap {
if number% == {
t.Logf("Remove %v from the HashSet value %v.\n", k, set)
set.Remove(k)
if set.Contains(k) {
t.Errorf("ERROR: The element removing (%v => %v) is failing!\n",
k, set)
t.FailNow()
}
delete(expectedElemMap, k)
}
number++
}
expectedLen := len(expectedElemMap)
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", set.Len(), expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
for _, v := range set.Elements() {
if !expectedElemMap[v] {
t.Errorf("ERROR: The HashSet value %v contains %v but should not contains!", set, v)
t.FailNow()
}
}
} func testSetClear(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sClear...", typeName)
set, _ := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
t.Logf("Clear the HashSet value %v.\n", set)
set.Clear()
expectedLen :=
if set.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", set.Len(), expectedLen)
t.FailNow()
}
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
} func testSetElements(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sElements...", typeName)
set, expectedElemMap := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
elems := set.Elements()
t.Logf("The elements of %s value is %v.\n", typeName, elems)
expectedLen := len(expectedElemMap)
if len(elems) != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", len(elems), expectedLen)
t.FailNow()
}
t.Logf("The length of elements is %d.\n", len(elems))
for _, v := range elems {
if !expectedElemMap[v] {
t.Errorf("ERROR: The elements %v contains %v but should not contains!", set, v)
t.FailNow()
}
}
} func testSetSame(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sSame...", typeName)
set, _ := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
t.Logf("The length of %s value is %d.\n", typeName, set.Len())
set2 := newSet()
t.Logf("Clone the HashSet value %v...\n", set)
for _, v := range set.Elements() {
set2.Add(v)
}
result := set2.Same(set)
if !result {
t.Errorf("ERROR: Two sets are not same!")
}
t.Logf("Two sets are same.")
} func testSetString(t *testing.T, newSet func() Set, typeName string) {
t.Logf("Starting Test%sString...", typeName)
set, _ := genRandSet(newSet)
t.Logf("Got a %s value: %v.", typeName, set)
setStr := set.String()
t.Logf("The string of %s value is %s.\n", typeName, setStr)
var elemStr string
for _, v := range set.Elements() {
elemStr = fmt.Sprintf("%v", v)
if !strings.Contains(setStr, elemStr) {
t.Errorf("ERROR: The string of %s value %s do not contains %s!",
typeName, setStr, elemStr)
t.FailNow()
}
}
} // ----- Set 公用函数测试 ----- func TestIsSuperset(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestIsSuperset...")
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set2 := NewSimpleSet()
for _, v := range set.Elements() {
set2.Add(v)
}
for extraElem := genRandElement(); ; {
if set2.Add(extraElem) {
break
} else {
time.Sleep( * time.Millisecond)
}
}
if !IsSuperset(set2, set) {
t.Errorf("ERROR: The HashSet value %v is not a superset of %v!\n", set2, set)
t.FailNow()
} else {
t.Logf("The HashSet value %v is a superset of %v.\n", set2, set)
}
for extraElem := genRandElement(); ; {
if set.Add(extraElem) {
break
} else {
time.Sleep( * time.Millisecond)
}
}
if IsSuperset(set2, set) {
t.Errorf("ERROR: The HashSet value %v should not be a superset of %v!\n", set2, set)
t.FailNow()
} else {
t.Logf("The HashSet value %v is not a superset of %v.\n", set2, set)
}
} func TestUnion(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestUnion...")
set, _ := genRandSet(func() Set { return NewSimpleSet() })
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
uSet := Union(set, set2)
t.Logf("The set value (2): %v", set2)
for _, v := range set.Elements() {
if !uSet.Contains(v) {
t.Errorf("ERROR: The union set value %v do not contains %v!",
uSet, v)
t.FailNow()
}
}
for _, v := range set2.Elements() {
if !uSet.Contains(v) {
t.Errorf("ERROR: The union set value %v do not contains %v!",
uSet, v)
t.FailNow()
}
}
t.Logf("The set value %v is a unioned set of %v and %v", uSet, set, set2)
} func TestIntersect(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestIntersect...")
commonElem := genRandElement()
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set.Add(commonElem)
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
set2.Add(commonElem)
t.Logf("The set value (2): %v", set2)
iSet := Intersect(set, set2)
for _, v := range iSet.Elements() {
if !set.Contains(v) {
t.Errorf("ERROR: The set value %v do not contains %v!",
set, v)
t.FailNow()
}
if !set2.Contains(v) {
t.Errorf("ERROR: The set value %v do not contains %v!",
set2, v)
t.FailNow()
}
}
t.Logf("The set value %v is a intersected set of %v and %v", iSet, set, set2)
} func TestDifference(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestDifference...")
commonElem := genRandElement()
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set.Add(commonElem)
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
set2.Add(commonElem)
t.Logf("The set value (2): %v", set2)
dSet := Difference(set, set2)
for _, v := range dSet.Elements() {
if !set.Contains(v) {
t.Errorf("ERROR: The set value %v do not contains %v!",
set, v)
t.FailNow()
}
if set2.Contains(v) {
t.Errorf("ERROR: The set value %v contains %v!",
set2, v)
t.FailNow()
}
}
t.Logf("The set value %v is a differenced set of %v to %v", dSet, set, set2)
} func TestSymmetricDifference(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestSymmetricDifference...")
commonElem := genRandElement()
set, _ := genRandSet(func() Set { return NewSimpleSet() })
set.Add(commonElem)
t.Logf("The set value: %v", set)
set2, _ := genRandSet(func() Set { return NewSimpleSet() })
set2.Add(commonElem)
t.Logf("The set value (2): %v", set2)
sdSet := SymmetricDifference(set, set2)
for _, v := range sdSet.Elements() {
if set.Contains(v) && set2.Contains(v) {
t.Errorf("ERROR: The element %v can not be a common element of %v to %v!",
v, set, set2)
t.FailNow()
}
}
t.Logf("The set value %v is a symmetric differenced set of %v to %v", sdSet, set, set2)
} // ----- 随机测试对象生成函数 ----- func genRandSet(newSet func() Set) (set Set, elemMap map[interface{}]bool) {
set = newSet()
elemMap = make(map[interface{}]bool)
var enough bool
for !enough {
e := genRandElement()
set.Add(e)
elemMap[e] = true
if len(elemMap) >= {
enough = true
}
}
return
} func genRandElement() interface{} {
seed := rand.Int63n()
switch seed {
case :
return genRandInt()
case :
return genRandString()
case :
return struct {
num int64
str string
}{genRandInt(), genRandString()}
default:
const length =
arr := new([length]interface{})
for i := ; i < length; i++ {
if i% == {
arr[i] = genRandInt()
} else {
arr[i] = genRandString()
}
}
return *arr
}
} func genRandString() string {
var buff bytes.Buffer
var prev string
var curr string
for i := ; buff.Len() < ; i++ {
curr = string(genRandAZAscii())
if curr == prev {
continue
} else {
prev = curr
}
buff.WriteString(curr)
}
return buff.String()
} func genRandAZAscii() int {
min := // A
max := // Z
rand.Seed(time.Now().UnixNano())
return min + rand.Intn(max-min)
} func genRandInt() int64 {
return rand.Int63n()
}

hash_set_test.go

// hash_set_test
package set import (
"fmt"
"runtime/debug"
"strings"
"testing"
) func TestHashSetCreation(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
t.Log("Starting TestHashSetCreation...")
hs := NewHashSet()
t.Logf("Create a HashSet value: %v\n", hs)
if hs == nil {
t.Errorf("The result of func NewHashSet is nil!\n")
}
isSet := IsSet(hs)
if !isSet {
t.Errorf("The value of HashSet is not Set!\n")
} else {
t.Logf("The HashSet value is a Set.\n")
}
} func TestHashSetLenAndContains(t *testing.T) {
testSetLenAndContains(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetAdd(t *testing.T) {
testSetAdd(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetRemove(t *testing.T) {
testSetRemove(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetClear(t *testing.T) {
testSetClear(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetElements(t *testing.T) {
testSetElements(t, func() Set { return NewHashSet() }, "HashSet")
} func TestHashSetSame(t *testing.T) {
testSetSame(t, func() Set { return NewHashSet() }, "HashSet")
} func TestSetString(t *testing.T) {
testSetString(t, func() Set { return NewHashSet() }, "HashSet")
} func testSetOp(t *testing.T) {
defer func() {
if err := recover(); err != nil {
debug.PrintStack()
t.Errorf("Fatal Error: %s\n", err)
}
}()
fmt.Println()
t.Logf("Starting TestHashSetOp...")
hs := NewHashSet()
if hs.Len() != {
t.Errorf("ERROR: The length of original HashSet value is not 0!\n")
t.FailNow()
}
randElem := genRandElement()
expectedElemMap := make(map[interface{}]bool)
t.Logf("Add %v to the HashSet value %v.\n", randElem, hs)
hs.Add(randElem)
expectedElemMap[randElem] = true
expectedLen := len(expectedElemMap)
if hs.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)
t.FailNow()
}
var result bool
for i := ; i < ; i++ {
randElem = genRandElement()
t.Logf("Add %v to the HashSet value %v.\n", randElem, hs)
result = hs.Add(randElem)
if expectedElemMap[randElem] && result {
t.Errorf("ERROR: The element adding (%v => %v) is successful but should be failing!\n",
randElem, hs)
t.FailNow()
}
if !expectedElemMap[randElem] && !result {
t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",
randElem, hs)
t.FailNow()
}
expectedElemMap[randElem] = true
}
expectedLen = len(expectedElemMap)
if hs.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)
t.FailNow()
}
for k, _ := range expectedElemMap {
if !hs.Contains(k) {
t.Errorf("ERROR: The HashSet value %v do not contains %v!", hs, k)
t.FailNow()
}
}
number :=
for k, _ := range expectedElemMap {
if number% == {
t.Logf("Remove %v from the HashSet value %v.\n", k, hs)
hs.Remove(k)
if hs.Contains(k) {
t.Errorf("ERROR: The element adding (%v => %v) is failing!\n",
randElem, hs)
t.FailNow()
}
delete(expectedElemMap, k)
}
number++
}
expectedLen = len(expectedElemMap)
if hs.Len() != expectedLen {
t.Errorf("ERROR: The length of HashSet value %d is not %d!\n", hs.Len(), expectedLen)
t.FailNow()
}
for _, v := range hs.Elements() {
if !expectedElemMap[v] {
t.Errorf("ERROR: The HashSet value %v contains %v!", hs, v)
t.FailNow()
}
}
hs2 := NewHashSet()
for k, _ := range expectedElemMap {
hs2.Add(k)
}
if !hs.Same(hs2) {
t.Errorf("ERROR: HashSet value %v do not same %v!\n", hs, hs2)
t.FailNow()
}
str := hs.String()
t.Logf("The string of HashSet value %v is '%s'.\n", hs, str)
for _, v := range hs.Elements() {
if !strings.Contains(str, fmt.Sprintf("%v", v)) {
t.Errorf("ERROR: '%s' do not contains '%v'!", str, v)
t.FailNow()
}
}
}

Go语言实现HashSet的更多相关文章

  1. Go目录

    1. Go语言获取项目当前路径 2. Go语言TCP/UDP Socket编程 3. Go语言实现HashSet

  2. Haskell语言学习笔记(77)Data.HashSet

    安装 unordered-containers $ cabal install unordered-containers Installed unordered-containers-0.2.9.0 ...

  3. [Java语言] HashMap,HashSet,Hashtable,Vector,ArrayList 的关系 <转>

    这么几个比较常用的但是比较容易混淆的概念同出于 java.util 包.本文仅作几个类的浅度解析. (本文基于JDK1.7,源码来自openjdk1.7.) ├── Collection │ ├── ...

  4. 学Android开发,入门语言java知识点

    学Android开发,入门语言java知识点 Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学 ...

  5. Spring表达式语言 之 5.3 SpEL语法(拾肆)

    5.3  SpEL语法 5.3.1  基本表达式 一.字面量表达式: SpEL支持的字面量包括:字符串.数字类型(int.long.float.double).布尔类型.null类型. 类型 示例 字 ...

  6. Apache Thrift - 可伸缩的跨语言服务开发框架

    To put it simply, Apache Thrift is a binary communication protocol 原文地址:http://www.ibm.com/developer ...

  7. 微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同。

    微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同. .NET Collection 函数库的 Has ...

  8. 【原创】关于hashcode和equals的不同实现对HashMap和HashSet集合类的影响的探究

    这篇文章做了一个很好的测试:http://blog.csdn.net/afgasdg/article/details/6889383,判断往HashSet(不允许元素重复)里塞对象时,是如何判定set ...

  9. 笔记整理——C语言-http-1

    http 传输原理及格式 - friping - ITeye技术网站 - Google Chrome (2013/4/1 14:02:36) http 传输原理及格式 博客分类: 其他 应用服务器浏览 ...

随机推荐

  1. ruby正则匹配回车换行符

    如果你使用/^.*$/这种正则是匹配不到回车换行符的. 所以应该像下面这么写: /^[\s\S]*$/

  2. [读书笔记]C#学习笔记二: 委托和事件的用法及不同.

    前言:  C#委托是什么 c#中的委托可以理解为函数的一个包装, 它使得C#中的函数可以作为参数来被传递, 这在作用上相当于C++中的函数指针. C++用函数指针获取函数的入口地址, 然后通过这个指针 ...

  3. paip.-Djava.library.path -Djava.ext.dirs= 的区别

    paip.-Djava.library.path  -Djava.ext.dirs= 的区别 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专 ...

  4. 浅析JVM中的GC日志

    目录 一.GC日志的格式分析 二.运行时开启GC日志 一.GC日志的格式分析 在讲述GC日志之前,我们先来运行下面这段代码 package com.example; public class Test ...

  5. WindowsPhone8拍照功能实现简介

    WindowsPhone作为一款智能手机操作系统,支持APP中拍照是必不可少的,目前在WP8上的拍照主要有以下三种途径: 1.使用CameraCaptureTask: 2.使用PhotoCamera类 ...

  6. 轻松了解Spring中的控制反转和依赖注入(二)

    紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...

  7. 通过rinetd实现端口转发来访问内网的服务

    通过rinetd实现端口转发来访问内网的服务 一.   问题描述 通过外网来访问内网的服务 二.   环境要求 需要有一台能够外网访问的机器做端口映射,通过数据包转发来实现外部访问阿里云的内网服务 三 ...

  8. Solr调研总结

    http://wiki.apache.org/solr/ Solr调研总结 开发类型 全文检索相关开发 Solr版本 4.2 文件内容 本文介绍solr的功能使用及相关注意事项;主要包括以下内容:环境 ...

  9. Lucene 4.X 倒排索引原理与实现: (1) 词典的设计

    词典的格式设计 词典中所保存的信息主要是三部分: Term字符串 Term的统计信息,比如文档频率(Document Frequency) 倒排表的位置信息 其中Term字符串如何保存是一个很大的问题 ...

  10. Lotus开发性能优化

    之前也总结过一篇关于性能的文章,地址在http://www.cnblogs.com/carysun/archive/2008/08/09/BasicPerformance.html,今天又看到DW上又 ...