持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
判断数组中是否包含某个元素
Java 中要判断某个数组是否包含某个元素
一般有如下方式:
arr 转为 list,然后使用 contains 判断
String[] strArr = new String[] { "a", "b", "c"};
String str = "c";
List<String> list = Arrays.asList(strArr);
boolean result = list.contains(str);
System.out.println(result); // true
使用循环判断
String[] strArr = new String[] { "a", "b", "c" };
String str = "c";
for (int i = 0; i < strArr.length; i++) {
if (strArr[i].equals(str)) {
System.out.println("该元素在数组中: i=" + i); // 该元素在数组中: i=2
}
}
使用 Apache Commons类库
String[] strArr = new String[] { "a", "b", "c" };
String str = "c";
boolean result = ArrayUtils.contains(strArr, str); // 推荐
System.out.println(result); // true
Go 中判断数组是否包含某个元素
循环实现
最常见的办法,对数组进行遍历,一个个比对,看是否能找到那个元素,找到了就返回 true 没找到返回false
func StringsContains(array []string, val string) bool {
for i := 0; i < len(array); i++ {
if array[i] == val {
return true
}
}
return false
}
使用反射进行实现
这个思路其实还行循环,但是可以比对任意类型的数据,判断元素是否在数组中。
func TestArrContainsItem(t *testing.T) {
arr := []string{"hello", "world"}
item := "hello"
item1 := "test"
assert.Equal(t, IsContains(arr, item), true)
assert.Equal(t, IsContains(arr, item1), false)
}
func IsContains(array interface{}, val interface{}) bool {
switch reflect.TypeOf(array).Kind() {
case reflect.Slice:
{
s := reflect.ValueOf(array)
for i := 0; i < s.Len(); i++ {
if reflect.DeepEqual(val, s.Index(i).Interface()) {
return true
}
}
}
}
return false
}
bench mark test
func BenchmarkContains(b *testing.B) {
sa := []string{"q", "w", "e", "r", "t"}
b.ResetTimer()
for n := 0; n < b.N; n++ {
IsContains(sa, "r")
}
}
func BenchmarkStringsContains(b *testing.B) {
sa := []string{"q", "w", "e", "r", "t"}
b.ResetTimer()
for n := 0; n < b.N; n++ {
StringsContains(sa, "r")
}
}
执行 Benchmark
go test -bench=.
执行结果:
➜ array git:(master) ✗ go test -bench=.
[[001 002 003] [11 22]]
[001 002 003]
002
goos: darwin
goarch: amd64
pkg: /GoProject/main/gobase/array
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkContains-12 3003925 402.8 ns/op
BenchmarkStringsContains-12 93780720 13.45 ns/op
PASS
ok
其实可以很明显的看到 StringsContains 方法平均每次 13.45ns,IsContains 每次 402ns 。 反射这个性能不好。 反射耗时长到原因可能如下:
- 内存分配导致 GC 问题
reflect使用了switch中使用了各种枚举
使用其他包 三方包 wgo
go get -u github.com/wxnacy/wgo
import "github.com/wxnacy/wgo/arrays"
方法包含如下:
// Contains Returns the index position of the val in array
func Contains(array interface{}, val interface{}) (index int)
// ContainsString Returns the index position of the string val in array
func ContainsString(array []string, val string) (index int)
// ContainsInt Returns the index position of the int64 val in array
func ContainsInt(array []int64, val int64) (index int)
// ContainsFloat Returns the index position of the float64 val in array
func ContainsFloat(array []float64, val float64) (index int)
// ContainsBool Returns the index position of the bool val in array
func ContainsBool(array []bool, val bool) (index int)
测试代码如下:
import(
"github.com/stretchr/testify/assert"
"github.com/wxnacy/wgo/arrays"
)
func TestArrContains_1(t *testing.T) {
var arr = []int64{1, 3, 4, 8, 12, 4, 9}
var i int
i = arrays.ContainsInt(arr, 8)
fmt.Println(i) // 3
assert.Equal(t, i, 3)
i = arrays.Contains(arr, int64(12))
fmt.Println(i)
assert.Equal(t, i, 4)
}
执行结果:
=== RUN TestArrContains_1
3
4
--- PASS: TestArrContains_1 (0.00s)
PASS