调用Arrays.asList(arr).contains(value)判断数组是否存在某个元素?

int32位 posted @ Sep 09, 2014 11:50:44 AM in java , 5947 阅读
转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!

这个问题很简单,就是在一个无序数组中判断某个元素是否存在,当然如果自己定义数据结构,可以使用trie,hash,如果不要求完全准确,允许误判,还能使用布隆!显然不能使用二分搜索,因为数组是无序的!当我们要经常搜索时,排序是必要的,或者使用其他数据结构。

这篇文章讨论了下http://www.programcreek.com/2014/04/check-if-array-contains-a-value-java/#more-12168,于是自己测试了下,下面是我的代码(必须使用java8版本以上):

import java.util.*;
interface StringPolicy {
	boolean contains(String[] arr, String value);
}
interface LongPolicy {
	boolean contains(long[] arr, long value);
}
class Policies {
	
    public static boolean useList(String[] arr, String value) {
        return Arrays.asList(arr).contains(value);
    }
    public static boolean useList(long[] arr, long value) {
    	return Arrays.asList(arr).contains(value);
    }
    public static boolean useSet(String[] arr, String value) {
        return new HashSet<>(Arrays.asList(arr)).contains(value);
    }
    public static boolean useSet(long[] arr, long value) {
        return new HashSet<>(Arrays.asList(arr)).contains(value);
    }
    public static boolean useLoop(String[] arr, String value) {
        for (String s : arr) {
            if (s.equals(value))
                return true;
        }
        return false;
    }
    public static boolean useLoop(long[] arr, long value) {
    	for (long l : arr) {
    		if (l == value)
    			return true;
    	}
    	return false;
    }
    public static boolean useStream(String[] arr, String value) {
    	return Arrays.stream(arr).anyMatch(value::equals);
    }
    public static boolean useStream(long[] arr, long value) {
    	return Arrays.stream(arr).anyMatch(l -> l == value);
    }
    public static boolean useParallelStream(String[] arr, String value) {
    	return Arrays.stream(arr).parallel().anyMatch(value::equals);
    }
    public static boolean useParallelStream(long[] arr, long value) {
    	return Arrays.stream(arr).parallel().anyMatch(l -> l == value);
    }
}
public class SearchDemo {
	public static void fill(String[] arr) {
        for(int i = 0; i < arr.length; ++i) {
            arr[i] = String.valueOf(i + 1);
        }
    }
	public static void fill(long[] arr) {
		for (int i = 0; i < arr.length; ++i) {
			arr[i] = i + 1;
		}
	}
	public static void fill(String[] arr, String value) {
		Arrays.fill(arr, value);
	}
	public static void fill(long[] arr, long value) {
		Arrays.fill(arr, value);
	}
	public static void test(String name, StringPolicy p, String[] arr, String value, int times) {
		long start = System.nanoTime();
		for (int i = 0; i < times; ++i) {
			p.contains(arr, value);
		}
		long end = System.nanoTime();
		long d = (end - start) / 1_000_000;
		System.out.printf("%s: %d\n", name, d);
	}
	public static void test(String name, LongPolicy p, long[] arr, long value, int times) {
		long start = System.nanoTime();
		for (int i = 0; i < times; ++i) {
			p.contains(arr, value);
		}
		long end = System.nanoTime();
		long d = (end - start) / 1_000_000;
		System.out.printf("%s: %d\n", name, d);
	}
	public static void main(String[] args) {
		String[] arr1 = new String[10_000];
		long[] arr2 = new long[10_000];
		fill(arr1);
		fill(arr2);
		System.out.println("******************* String **************************");
		test("useLoop", Policies::useLoop, arr1, "A", 10_000);
		test("useList", Policies::useList, arr1, "A", 10_000);
		test("useSet", Policies::useSet, arr1, "A", 10_000);
		test("useStream", Policies::useStream, arr1, "A", 10_000);
		test("useParallelStream", Policies::useParallelStream, arr1, "A", 10_000);
		System.out.println("******************* Long **************************");
		test("useLoop", Policies::useLoop, arr2, -1, 10_000);
		test("useList", Policies::useList, arr2, -1, 10_000);
		test("useSet", Policies::useSet, arr2, -1, 10_000);
		test("useStream", Policies::useStream, arr2, -1, 10_000);
		test("useParallelStream", Policies::useParallelStream, arr2, -1, 10_000);
	}

结果输出是:

数组大小为1k时的结果:
******************* String **************************
useLoop: 141
useList: 128
useSet: 859
useStream: 331
useParallelStream: 746
******************* Long **************************
useLoop: 87
useList: 7
useSet: 40
useStream: 311
useParallelStream: 835
数组大小为10k时的结果:
******************* String **************************
useLoop: 887
useList: 1005
useSet: 7889
useStream: 2489
useParallelStream: 2420
******************* Long **************************
useLoop: 644
useList: 10
useSet: 24
useStream: 2455
useParallelStream: 2748
当把数组大小提高到100k时,结果为:
******************* String **************************
useLoop: 10584
useList: 11597
useSet: 92295
useStream: 31249
useParallelStream: 17176
******************* Long **************************
useLoop: 6167
useList: 10
useSet: 33
useStream: 22633
useParallelStream: 21192
 
可以看出使用字符串时,使用循环的方式会比其他方式更快,但当判断基本数据类型时,使用List是最快的,往往使用Set都不是好方法,使用Stream也并没有提高速率。原文并没有说明!
 
转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!
  • 无匹配
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter