zoukankan      html  css  js  c++  java
  • 七、如何在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)完成。

  • 相关阅读:
    Best Time to Buy and Sell Stock
    Remove Nth Node From End of List
    Unique Paths
    Swap Nodes in Pairs
    Convert Sorted Array to Binary Search Tree
    Populating Next Right Pointers in Each Node
    Maximum Subarray
    Climbing Stairs
    Unique Binary Search Trees
    Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/seaspring/p/5268369.html
Copyright © 2011-2022 走看看