0

    如何检查 Java 数组中是否包含某个值?

    2023.10.25 | admin | 119次围观

    在逛 programcreek 的时候,我发现了一些专注细节但价值连城的主题。比如说:如何检查Java数组中是否包含某个值 ?像这类灵魂拷问的主题,非常值得深入地研究一下。

    另外,我想要告诉大家的是,作为程序员,我们千万不要轻视这些基础的知识点。因为基础的知识点是各种上层技术共同的基础java获取当天零点的时间戳,只有彻底地掌握了这些基础知识点,才能更好地理解程序的运行原理,做出更优化的产品。

    我曾在某个技术论坛上分享过一篇非常基础的文章,结果遭到了无数的嘲讽:“这么水的文章不值得分享。”我点开他的头像进入他的主页,发现他从来没有分享过一篇文章,不过倒是在别人的博客下面留下过不少的足迹,大多数都是冷嘲热讽。我就纳闷了,技术人不都应该像我这样低调谦逊吗?怎么戾气这么重!

    好了,让我们来步入正题。如何检查数组(未排序)中是否包含某个值 ?这是一个非常有用并且经常使用的操作。我想大家的脑海中应该已经浮现出来了几种解决方案,这些方案的时间复杂度可能大不相同。

    我先来提供四种不同的方法,大家看看是否高效。

    1)使用 List

    public static boolean useList(String[] arr, String targetValue) {
    return Arrays.asList(arr).contains(targetValue);
    }

    Arrays 类中有一个内部类 ArrayList(可以通过 Arrays.asList(arr) 创建该实例),其 contains 方法的源码如下所示。

    public boolean contains(Object o) {
    return indexOf(o) != -1;
    }
    public int indexOf(Object o) {
    E a = this.a;
    if (o == ) {
    for (int i = 0; i < a.length; i++)
    if (a[i] == )
    return i;
    } else {
    for (int i = 0; i < a.length; i++)
    if (o.equals(a[i]))
    return i;
    }
    return -1;
    }

    从上面的源码可以看得出,contains 方法调用了 indexOf 方法,如果返回 -1 则表示 ArrayList 中不包含指定的元素,否则就包含。其中 indexOf 方法用来获取元素在 ArrayList 中的下标,如果元素为 ,则使用“==”操作符进行判断,否则使用 equals 方法进行判断。

    PS:关于“==”操作符和 equals 方法,可以参照我另外一篇文章《如何比较 Java 的字符串?》

    2)使用 Set

    public static boolean useSet(String[] arr, String targetValue) {
    Set set = new HashSet(Arrays.asList(arr));
    return set.contains(targetValue);
    }

    HashSet 其实是通过 HashMap 实现的java获取当天零点的时间戳,当使用 new HashSet(Arrays.asList(arr)) 创建并初始化了 HashSet 对象后,其实是在 HashMap 的键中放入了数组的值,只不过 HashMap 的值为默认的一个摆设对象。大家感兴趣的话,可以查看一下 HashSet 的源码。

    我们来着重看一下 HashSet 的 contains 方法的源码。

    public boolean contains(Object o) {
    return map.containsKey(o);
    }

    public boolean containsKey(Object key) {
    return getNode(hash(key), key) != ;
    }

    从上面的源码可以看得出,contains 方法调用了 HashMap 的 containsKey 方法,如果指定的元素在 HashMap 的键中,则返回 true;否则返回 false。

    3)使用一个简单的循环

    public static boolean useLoop(String[] arr, String targetValue) {
    for (String s : arr) {
    if (s.equals(targetValue))
    return true;
    }
    return false;
    }

    for-each 循环中使用了 equals 方法进行判断——这段代码让我想起了几个词,分别是简约、高效、清晰。

    4)使用 Arrays.binarySearch

    public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
    int a = Arrays.binarySearch(arr, targetValue);
    if (a > 0)
    return true;
    else
    return false;
    }

    不过,binarySearch 只适合查找已经排序过的数组。

    由于我们不确定数组是否已经排序过,所以我们先来比较一下前三种方法的时间复杂度。由于调用 1 次的时间太短,没有统计意义,我们就模拟调用 100000 次,具体的测试代码如下所示。

    String arr = new String{"沉", "默", "王", "二", "真牛逼"};
    // 使用 List
    long startTime = System.nanoTime;
    for (int i = 0; i < 100000; i++) {
    useList(arr, "真牛逼");
    }
    long endTime = System.nanoTime;
    long duration = endTime - startTime;
    System.out.println("useList: " + duration / 1000000);

    // 使用 Set
    startTime = System.nanoTime;
    for (int i = 0; i < 100000; i++) {
    useSet(arr, "真牛逼");
    }
    endTime = System.nanoTime;
    duration = endTime - startTime;
    System.out.println("useSet: " + duration / 1000000);

    // 使用一个简单的循环
    startTime = System.nanoTime;
    for (int i = 0; i < 100000; i++) {
    useLoop(arr, "真牛逼");
    }
    endTime = System.nanoTime;
    duration = endTime - startTime;
    System.out.println("useLoop: " + duration / 1000000);

    版权声明

    本文仅代表作者观点。
    本文系作者授权发表,未经许可,不得转载。

    发表评论