如何检查一个数组(未排序)中是否包含某个特定的值?在Java中,这是一个非常有用并又很常用的操作。同时,在StackOverflow中,有时一个得票非常高的问题。在得票比较高的几个回答中,时间复杂度差别也很大。

1、不同的实现方式

使用list

 public static boolean useList(String[] arr, String targetValue) {
return Arrays.asList(arr).contains(targetValue);
}

使用set

 public static boolean useSet(String[] arr, String targetValue) {
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
}

使用循环

 public static boolean useLoop(String[] arr, String targetValue) {
for (String s : arr) {
if (s.equals(targetValue)) {
return true;
}
}
return false;
}

使用Arrays.binarySearch

  此法为二分搜索法,故查询前需要用sort()方法将数组排序,如果数组没有排序,则结果是不确定的,另外

  如果数组中含有多个指定值的元素,则无法保证找到的是哪一个。

 public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
int a = Arrays.binarySearch(arr, targetValue);
if (a > 0) {
return true;
} else {
return false;
}
}

2、时间复杂度

使用如下代码来粗略比较不同实现间的时间复杂度。虽然不是很精确,但是思路确实正确的。我们将看看数组在有5、1k、10k个元素的情况下的不同表现。

5个

 public static void main(String[] args) {
String[] arr = new String[]{"CD", "BC", "EF", "DE", "AB"}; // use list
long startTime = System.nanoTime();
for (int i = 0; i < 100000; i++) {
useList(arr, "A");
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println("useList: " + duration / 1000000); // use set
startTime = System.nanoTime();
for (int i = 0; i < 100000; i++) {
useSet(arr, "A");
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("useSet: " + duration / 1000000); // use loop
startTime = System.nanoTime();
for (int i = 0; i < 100000; i++) {
useLoop(arr, "A");
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("useLoop: " + duration / 1000000); // use Arrays . binarySearch ()
startTime = System.nanoTime();
for (int i = 0; i < 100000; i++) {
useArraysBinarySearch(arr, "A");
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("useArrayBinary: " + duration / 1000000);
}

结果

useList:  12
useSet: 65
useLoop: 2
useArrayBinary: 7

1k个元素

 int length = 1000;
String[] arr = new String[length]; Random s = new Random();
for (int i = 0; i < length; i++) {
arr[i] = String.valueOf(s.nextInt());
}

结果

useList:  115
useSet: 2010
useLoop: 97
useArrayBinary: 9

10k个元素

 int length = 10000;
String[] arr = new String[length]; Random s = new Random();
for (int i = 0; i < length; i++) {
arr[i] = String.valueOf(s.nextInt());
}

结果

useList:  1678
useSet: 25609
useLoop: 1802
useArrayBinary: 10

从上面的结果可以清晰看到,使用简单循环的相比使用其他集合操作更高效。很多很多开发人员使用第一种方法,但是它并不是最高效的。将数组转化成其他的任何集合类型都需要先将所有元素读取到集合类中,才能对这个集合类型做其他的事情。

当使用Arrays.binarySearch()方法时,数组必须是排好序的。如果数组不是排好序的,则不能使用这个方法。

事实上,如果你真的需要高效地检查一个数组或者集合中是否包含一个值,一个排好序的数组或者树可以达到O(log(n))的时间复杂度,HashSet甚至能达到O(1)的时间复杂度

转自http://www.diguage.com/archives/112.html

Java 高效检查一个数组中是否包含某个值的更多相关文章

  1. 在Java中如何高效的判断数组中是否包含某个元素

    原文出处: hollischuang(@Hollis_Chuang) 如何检查一个数组(无序)是否包含一个特定的值?这是一个在Java中经常用到的并且非常有用的操作.同时,这个问题在Stack Ove ...

  2. java中如何高效的判断数组中是否包含某个元素---

    package zaLearnpackage; import org.apache.commons.lang3.ArrayUtils; import java.util.Arrays; import ...

  3. 灵魂拷问:如何检查Java数组中是否包含某个值 ?

    在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题.比如说:如何检查Java数组中是否包含某个值 ?像这类灵魂拷问的主题,非常值得深入地研究一下. 另外,我想要告诉大家的是, ...

  4. js判断数组中是否包含某个值

    /** * 判断数组中是否包含某个值 * @param arr 数组 * @param str 值 * @returns {boolean} */ function contains(arr, str ...

  5. node js 判断数组中是否包含某个值

    判断数组中是否包含某个值这里有四种方法.用的测试数据: let arr=["a","b","c"]; let arr2={"a&q ...

  6. 七、如何在Java中高效检查一个数组是否含有一个值

    如何检查一个数组(非排序的)是否包含特定的值.这是个非常有用或经常被在Java中使用.这是个在Stack Overflow中高得票的问题.在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非 ...

  7. Java 正则判断一个字符串中是否包含中文

    使用正则判断一个字符串中是否包含中文或者中文字符 代码实现如下: import java.util.regex.Matcher; import java.util.regex.Pattern; /** ...

  8. Js 判断数组中是否包含某个值

    includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false. JavaScript Array includes() 方法

  9. 用JAVA写查询一个字符串中是否包含另外一个字符串以及出现的次数

    package JAVA; import java.awt.List;import java.util.ArrayList;/** *  * @author 梁小鱼 * */public class ...

随机推荐

  1. javascript中通过className灵活查找元素 例如我们要把根据class来进行修改样式

    一.背景:一个表单中,要修改一些li中有class=box的样式,将它的background设置为red红色.一般的做法是我们可以先找到父级元素 ,然后由父级元素找到所有相关tagName,最后,来一 ...

  2. 屌丝程序猿赚钱之道 之APP

    假设你已经通过APP赚到了钱,那么本文对你而言没有意义.倒是希望你可以给我们诸多建议. 通过制作APP或者说手机应用赚钱,相信是非常多程序猿希望做的事情.也确实有一些人通过APP赚到了钱. 对于程序猿 ...

  3. C# 枚举 字符串 转换

    普通方法 这种方法尽管很SB但确实可以解决问题 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { st ...

  4. NSString、NSMutableString基本使用

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助.欢迎给作者捐赠,支持郝萌主.捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下 ...

  5. oracle多表查询

    多表查询首先要避免笛卡尔集,要避免笛卡尔集,那么查询条件不得少于表的个数-1. 1.显示雇员名,雇员工资以及雇员所在的部门: 2.显示部门号为10的部门名.员工名和工资: 3.显示各个雇员的姓名,工资 ...

  6. [学习笔记]设计模式之Adapter

    写在前面 为方便读者,本文已添加至索引: 设计模式 学习笔记索引 Adapter(适配器)模式主要解决接口不匹配的问题.为此,让我们要回到最初Builder模式创建平行世界时,白雪公主和小霍比特人的谜 ...

  7. 解析嵌套json字符串,一个json字符串中嵌套另一个json字符串

    我现在有一个字符串是这样: { "msg": { ", "attrName": "sensorData", "trans ...

  8. c#不重复的排序方法

    public int getRandom(int num) { Thread.Sleep(5); // Random ro = new Random(unchecked((int)DateTime.N ...

  9. .net+easyui系列--验证框

    1.允许从 0 到 10个字符 <input id="vv" class="easyui-validatebox" data-options=" ...

  10. [DEncrypt] HashEncode--哈希加密帮助类 (转载)

    点击下载 HashEncode.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.HashEncode 得到随机哈希加密字符串2.HashEncode 得到一个随机数值3.HashEncod ...