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

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

一、四种不同的方法去检查一个数组包含特定的值

1) 用List

public static boolean useList(String[] arr, String targetValue) {

return Arrays.asList(arr).contains(targetValue);

}

2)             用Set

public static boolean useSet(String[] arr, String targetValue) {

Set<String> set = new HashSet<String>(Arrays.asList(arr));

return set.contains(targetValue);

}

3)             用简单的循环

public static boolean useLoop(String[] arr, String targetValue) {

for(String s: arr){

if(s.equals(targetValue))

return true;

}

return false;

}

4)             用Arrays.binarySearch()

下面的代码是错误的,列出来是为了完备性。BinarySearch()只能用在排序的数组上。你会觉得下面的代码运行的结果是怪异的。

public static boolean useArraysBinarySearch(String[] arr, String targetValue) {

int a =  Arrays.binarySearch(arr, targetValue);

if(a > 0)

return true;

else

return false;

}

二、时间复杂度

下面的近似的时间测量。下面的基本方法是测试查找一个数量为5、1k、10K。这种处理也许是不精确的,但是很清晰也很简单。

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:  13

useSet:  72

useLoop:  5

useArraysBinarySearch:  9

用大数组(1K):

String[] arr = new String[1000];

Random s = new Random();

for(int i=0; i< 1000; i++){

arr[i] = String.valueOf(s.nextInt());

}

结果:

useList:  112

useSet:  2055

useLoop:  99

useArrayBinary:  12

用更大的数组(10K)

String[] arr = new String[10000];

Random s = new Random();

for(int i=0; i< 10000; i++){

arr[i] = String.valueOf(s.nextInt());

}

结果:

useList:  1590

useSet:  23819

useLoop:  1526

useArrayBinary:  12

很明显,用简单的循环方法比用任何集合更有效。很多开发者用第一种方法,但是它是不高效的。传递数组给另外一个集合,在操作前,需要转换所有元素。

如果一个数组是排序的。如果Arrays.binarySearch()方法被使用。

在这种情况下,由于数组是没有排序的,所以它不能使用。

实际上,如果你真的需要去高效查找一个值是否在一个数组或集合中,一个排序的list或tree 可以在O(log(n))或hashset 可以在O(1)完成。

时间: 2024-10-13 04:51:30

七、如何在Java中高效检查一个数组是否含有一个值的相关文章

如何在JAVA中实现一个固定最大size的hashMap

如何在JAVA中实现一个固定最大size的hashMap 利用LinkedHashMap的removeEldestEntry方法,重载此方法使得这个map可以增长到最大size,之后每插入一条新的记录就会删除一条最老的记录. import java.util.LinkedHashMap; import java.util.Map; public class MaxSizeHashMap<K, V> extends LinkedHashMap<K, V> { private fina

如何在Java中执行Hive命令或HiveQL

这里所说的在Java中执行Hive命令或HiveQL并不是指Hive Client通过JDBC的方式连接HiveServer(or HiveServer2)执行查询,而是简单的在部署了HiveServer的服务器上执行Hive命令.当然这是一个简单的事情,平常我们通过Hive做简单的数据分析实验的时候,都是直接进入Hive执行HiveQL,那我们为什么还要在程序中执行呢? 这里涉及到了一个问题,通过进入Hive执行HiveQL,我们只能将分析结果打印到屏幕或是存入临时表,那如果我们想吧分析结果写

如何在Java中调用Python代码

有时候,我们会碰到这样的问题:与A同学合作写代码,A同学只会写Python,而不会Java, 而你只会写Java并不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方设法“调用对方的代码”. 下面我将举一些简单的小例子,借此说明:如何在Java中调用Python代码. 看懂这篇文章只需要具备: 熟悉Java的基本语法 懂一点点Python 主要内容如下: 什么是Jython? 一个HelloPython程序 在Jvm中执行Python脚本 仅在Java中调用Python

用代码说话:如何在Java中实现线程

并发编程是Java语言的重要特性之一,"如何在Java中实现线程"是学习并发编程的入门知识,也是Java工程师面试必备的基础知识.本文从线程说起,然后用代码说明如何在Java中实现线程. 一.什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,也可以使用多线程对运算密集型任务提速.如果使用得当,线程可以有效地降低程序的开发和运维成本,同时能够提升程序的性能. 二.线程和进程有什么区别? 线程是进程的子集,

如何在java中使用sikuli进行自动化测试

很早之前写过一篇介绍sikuli的文章.本文简单介绍如何在java中使用sikuli进自动化测试. 图形脚本语言sikuli sikuli IDE可以完成常见的单击.右击.移动到.拖动等鼠标操作,java引用sikuli-script.jar同样可以执行这些常见的鼠标操作,因此即可方便的编写java实现识别图片并模拟点击/拖动目标控件. sikuli-script.jar:http://download.csdn.net/download/hqd1986/4557974 将sikuli-scri

Java基础---如何在Java中注释(十)

如何在Java中使用注释 在编写程序时,经常需要添加一些注释,用以描述某段代码的作用. 一般来说,对于一份规范的程序源代码而言,注释应该占到源代码的 1/3 以上.因此,注释是程序源代码的重要组成部分,一定要加以重视哦! Java 中注释有三种类型:单行注释.多行注释.文档注释 运行结果: 看:被注释的代码块在程序运行时是不会被执行的~~ 我们可以通过 javadoc 命令从文档注释中提取内容,生成程序的 API 帮助文档. 打开首页,查看下生成的 API 文档 PS:使用文档注释时还可以使用

Java基础---Java中的二维数组(三十四)

Java 中的二维数组 所谓二维数组,可以简单的理解为是一种"特殊"的一维数组,它的每个数组空间中保存的是一个一维数组. 那么如何使用二维数组呢,步骤如下: 1. 声明数组并分配空间 或者 如: 2. 赋值 二维数组的赋值,和一维数组类似,可以通过下标来逐个赋值,注意索引从 0 开始 也可以在声明数组的同时为其赋值 如: 3. 处理数组 二维数组的访问和输出同一维数组一样,只是多了一个下标而已.在循环输出时,需要里面再内嵌一个循环,即使用二重循环来输出二维数组中的每一个元素.如: 运行

java中的二维数组

简单讲:java中的二维数组就是"特殊的一维数组",称为一维数组中的一维数组. 只不过元素是一维数组而已. 也是有两种初始化方式:静态初始化和动态初始化. 访问最后一个元素: int[] []a=? a[a.length-1][a[a.length-1].length-1]这个表示是最后一个元素 遍历二维数组: for(int i=0;i<a.length;i++){     for(int j=0;j<a[i].length;j++){         System.ou

【Stackoverflow好问题】java中,如何判断数组Array是否包含指定的值

问题 java中,如何判断数组Array是否包含指定的值 精华回答 1. Arrays.asList(...).contains(...) 2. 使用 Apache Commons Lang包中的ArrayUtils.contains String[] fieldsToInclude = { "id", "name", "location" }; if ( ArrayUtils.contains( fieldsToInclude, "i