如何检查一个数组(未排序)中是否包含某个特定的值?在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. SQL语法集锦一:显示每个类别最新更新的数据

    本文转载http://www.cnblogs.com/lxblog/archive/2012/09/28/2707504.html (1)显示每个类别最新更新的数据 在项目中经常遇到求每个类别最新显示 ...

  2. [Usaco2006 Nov]Corn Fields牧场的安排 壮压DP

    看到第一眼就发觉是壮压DP 然后就三进制枚举子集吧. 这题真是壮压入门好题... 对于dp[i][j] 表示第i行,j状态下前i行的分配方案数. 那么dp[i][j]肯定是从i-1行转过来的 那么由于 ...

  3. iOS 应用性能测试的相关方法、工具及技巧

    用户不喜欢等待.他们不关心也不应该关心一个应用初始化的时候需要什么,他们只想尽快地完成他们的任务.你的应用应该几乎是瞬间启动的,其界面应当如丝般顺滑.在充满竞争的软件市场中,应用的性能是关键的优势之一 ...

  4. runtime重写description方法打印model属性和值

    在开发过程中, 往往会有很多的model来装载属性. 而在开发期间经常会进行调试查看model里的属性值是否正确. 那么问题来了, 在objective-c里使用NSLog("%@" ...

  5. 需要重新启动计算机.必须重新启动计算机才能安装 SQL Server

    在开始运行中输入regedit找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager 在右边窗口找到PendingFi ...

  6. HIdernate入门

    简介: Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使 ...

  7. PHP获取用户访问IP地址的5种方法

    IP地址获得的五种方法: <?php //方法1: $ip = $_SERVER["REMOTE_ADDR"]; echo $ip; //方法2: $user_IP = ($ ...

  8. JAVA 循环在一个数字前面填充0.小例子

    输入结果 00000000000567 String bala="567"; 固定长度是14位,怎么循环在bala前面填充00000000000 System.out.printl ...

  9. 概述ASP.NET缓存机制

    PetShop之ASP.NET缓存机制 如果对微型计算机硬件系统有足够的了解,那么我们对于Cache这个名词一定是耳熟能详的.在CPU以及主板的芯片中,都引入了这种名为高速缓冲存储器(Cache)的技 ...

  10. [条形码] BarCodeToHTML条码生成类 (转载)

    点击下载 BarCodeToHTML.zip 过多的我就不多说了大家直接看代码吧,这是一个帮助大家生成条码的类,大小大家可以自由的设定 /// <summary> /// 类说明:条码生成 ...