如何检查一个数组(未排序)中是否包含某个特定的值?在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. C#面向对象基础:virtual方法,abstract方法,区别

    virtual 关键字用于修饰方法.属性.索引器或事件声明,并使它们可以在派生类中被重写.默认情况下,类中的方法是非虚的,非虚的方法不能在子类中被覆盖(override),但是可以隐藏(new),但这 ...

  2. Cas Server中各配置文件介绍

    Cas Server中所有的配置文件都是放在WEB-INF目录及其子目录下的. 在WEB-INF/classes下的配置文件有: l  cas-theme-default.properties:该文件 ...

  3. Java三大主流框架概述(转载)

    转自:http://www.douban.com/note/320140839/ Struts.Hibernate和Spring是我们Java开发中的常用关键,他们分别针对不同的应用场景给出最合适的解 ...

  4. 了解node.js

    转载自http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb 当我向人们介绍nod ...

  5. careercup-数组和字符串1.4

    1.4 编写一个方法,将字符串中的空格全部替换为“%20“.假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的”真实“长度. C++实现代码: #include<iostream> ...

  6. 使用dom4j对xml文件进行增删改查

    1.使用dom4j技术对dom_demo.xml进行增删改查 首选要下载dom4j的jar包 在官网上找不到,网上搜索了一下在这个链接:http://sourceforge.net/projects/ ...

  7. Cocos2d-x中常用粒子编辑器ParticleDesigner测试例子

    打开 ParticleDesigner 随意选择一种效果 选择save. 类型选择 cocosd(plist)类型保存至桌面 命名为myplist导出至桌面 选择右侧Emitter Config可设置 ...

  8. ASP.NET中如何实现负载均衡

    ASP.NET站点中做负载均衡: 基于HTTP协议我们可能发现我们要解决两点问题: 第一,做到负载均衡,我们需要一个负载均衡器. 可以通过DNS轮询来做,在DNS服务器上配置为每次对我们做负载均衡的同 ...

  9. nodejs 中koa框架下的微信公众号开发初始篇

    最近在搞微信公众号开发,后端采用的是nodejs下的koa框架,初识后端的菜鸟,自己搞难度太大了,网上找了很多文章,采用的中间件大都是express框架下的,不过好在爬了许多坑之后总算看见点曙光了,遂 ...

  10. 复杂对象创建终结者(Builder Pattern)

    捣鼓了很长时间,终于对建造者模式有初步理解,现在写篇记录下.缘起就是创建的对象比较复杂,需按功能分散.类似造一辆汽车,作为汽车厂家,你需要造车身,造轮胎等,精髓在于领导者(Director),领导者指 ...