# README
common-lang-in-go
Java 程序员编写的类似 common-lang 工具包 包名就是要用大驼峰,不想改成 go 规范的包名。自己写的任性
Thanks
Licenses for Open Source Development
how to use
go get github.com/sjsdfg/common-lang-in-go
StringUtils
- IsEmpty(str string) bool
- IsNotEmpty(str string) bool
- IsAllEmpty(list ...string) bool
- IsAnyEmpty(list ...string) bool
- IsAnyNoneEmpty(list ...string) bool
- IsBlank(str string) bool
- IsNotBlank(str string) bool
- IsZero(str string) bool
- IsNotZero(str string) bool
- IsAnyZero(list ...string) bool
- IsAllZero(list ...string) bool
- IsAnyNoneZero(list ...string) bool
- Equal(str1, str2 string) bool
- EqualIgnoreCase(str1, str2 string) bool
- EqualsAny(str string, list ...string) bool
- EqualsAnyIgnoreCase(str string, list ...string) bool
- IsDigital(str string) bool
- DefaultIfEmpty(str, defaultStr string) string
- If(condition bool, ifTrue, ifFalse string) string
- Truncate(str string, startIndex, endIndex int) string
CollectionUtils
match functions
- AllMatch(list interface{}, action matchFunc) bool
- AnyMatch(list interface{}, action matchFunc) bool
- NoneMatch(list interface{}, action matchFunc) bool
Use Case
func TestAllMatch(t *testing.T) {
testCase := []string{"a", "a", "a"}
assert.Equal(t, true, AllMatch(testCase, func(index int) bool {
return testCase[index] == "a"
}))
testCase = []string{"a", "a", "b"}
assert.Equal(t, false, AllMatch(testCase, func(index int) bool {
return testCase[index] == "a"
}))
}
func TestAnyMatch(t *testing.T) {
testCase := []string{"a", "a", "b"}
assert.Equal(t, true, AnyMatch(testCase, func(index int) bool {
return testCase[index] == "b"
}))
testCase = []string{"a", "a", "b"}
assert.Equal(t, false, AnyMatch(testCase, func(index int) bool {
return testCase[index] == "c"
}))
}
func TestNoneMatch(t *testing.T) {
testCase := []string{"a", "a", "b"}
assert.Equal(t, true, NoneMatch(testCase, func(index int) bool {
return testCase[index] == "c"
}))
testCase = []string{"a", "a", "b"}
assert.Equal(t, false, NoneMatch(testCase, func(index int) bool {
return testCase[index] == "b"
}))
}
empty judgement
- IsEmpty(collection interface{})
- IsNotEmpty(collection interface{}) bool
map function
这个是由于没有 Java Stream 里面的 map,导致每次提取某一类型的字段成为数组,写的代码十分冗余。所以抽象出来的。
由于不支持泛型,只能书写基本类型的方法调用。不过我的个人场景就是提取某一个字段(尤其是 id),目前还够用。
- MapToStringSlice(list interface{}, action func(index int) string) []string
- MapToIntSlice(list interface{}, action func(index int) int) []int
- MapToInt64Slice(list interface{}, action func(index int) int64) []int64
- MapToFloat64Slice(list interface{}, action func(index int) float64) []float64
- MapToFloat32Slice(list interface{}, action func(index int) float32) []float32
Use Case
func TestMapToStringSlice(t *testing.T) {
students := createStudents()
timer := TimeUtils.NewTimer()
reflectSlice := MapToStringSlice(students, func(i int) string {
return students[i].name
})
t.Logf("MapToStringSlice cost %d nanos", timer.GetDurationInNanos())
timer.Reset()
nativeSlice := NativeMapToStringSlice(students)
t.Logf("NativeMapToStringSlice cost %d nanos", timer.GetDurationInNanos())
assert.Equal(t, nativeSlice, reflectSlice)
}
iterate
- ForEach(list interface{}, action func(index int)):之前写 Java 写惯了,觉得使用 return 代替 continue 是可读性更高的代码,因为可以提早返回减少代码的嵌套接口。因此抽象出了该方法
func TestForEach(t *testing.T) {
students := createStudents()
ForEach(students, func(index int) {
t.Log(students[index])
})
ForEach(students, func(index int) {
students[index].name = "testing"
})
ForEach(students, func(index int) {
assert.Equal(t, "testing", students[index].name)
})
}
注意
以上方法类型为 FunctionName(list interface{}, action func(index int))
均可以替换为 FunctionName(len int, action func(index int))
比如 ForEach 的实现可以为
func ForEach(len int, action func(i int)) {
for i := 0; i < len; i++ {
action(i)
}
}
这个版本的运行效率更高。但是考虑到边界检查的安全性问题,我还是更倾向于传入 list 进来,通过反射来获取列表的长度。相关代码可查看 https://github.com/sjsdfg/common-lang-in-go/blob/faster/CollectionUtils/collection_utils.go
Float32Utils
- Max(list ...float32) float32
- Min(list ...float32) float32
- If(condition bool, ifTrue, ifFalse float32) float32
- Abs(a float32) float32
- Equal(a, b float32) bool
Float64Utils
- Max(list ...float64) float64
- Min(list ...float64) float64
- If(condition bool, ifTrue, ifFalse float64) float64
- Abs(a float64) float64
- Equal(a, b float64) bool
Int64Utils
- Max(list ...int64) int64
- Min(list ...int64) int64
- If(condition bool, ifTrue, ifFalse int64) int64
- Abs(a int64) int64
IntUtils
- Max(list ...int) int
- Min(list ...int) int
- If(condition bool, ifTrue, ifFalse int64) int
- Abs(a int) int
TimeUtils
- Max(list ...time.Time) time.Time
- Min(list ...time.Time) time.Time
- If(condition bool, ifTrue, ifFalse int64) time.Time
上面的 XxxUtils
根据类型进行抽象,提供了最大值最小值的方法。并且因为 go 语言没有提供三目表达式,提供了 If
方法出来。可以边写出来可读性更高的代码
最佳实践
// 待实现 主要是想配合 IDEA 的 live template 和 Postfix completion 进行快捷键的搭配。
这样可以更好的使用该库。
Benchmark
CollectionUtils
CollectionUtils#IsEmpty
goos: darwin
goarch: amd64
pkg: github.com/sjsdfg/common-lang-in-go/CollectionUtils
BenchmarkIsEmpty 22247214 54.3 ns/op
BenchmarkIsEmpty-2 23466332 51.7 ns/op
BenchmarkIsEmpty-4 23064122 51.4 ns/op
BenchmarkIsEmpty-8 23634132 51.5 ns/op
BenchmarkNativeIsEmpty
BenchmarkNativeIsEmpty 20717202 53.7 ns/op
BenchmarkNativeIsEmpty-2 23106975 50.9 ns/op
BenchmarkNativeIsEmpty-4 22869487 51.1 ns/op
BenchmarkNativeIsEmpty-8 23977856 51.1 ns/op
PASS
CollectionUtils#MapToStringSlice
BenchmarkMapToStringSlice
BenchmarkMapToStringSlice 4942840 292 ns/op
BenchmarkMapToStringSlice-2 4770552 263 ns/op
BenchmarkMapToStringSlice-4 4740819 302 ns/op
BenchmarkMapToStringSlice-8 5007906 238 ns/op
BenchmarkNativeMapToStringSlice
BenchmarkNativeMapToStringSlice 10728244 113 ns/op
BenchmarkNativeMapToStringSlice-2 10394302 113 ns/op
BenchmarkNativeMapToStringSlice-4 10965626 112 ns/op
BenchmarkNativeMapToStringSlice-8 10831770 113 ns/op
PASS
# Packages
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author