在java中,如何确定数组是否包含特定值?

r7s23pms  于 2021-06-27  发布在  Java
关注(0)|答案(29)|浏览(359)

我有一个 String[] 价值观如下:

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

鉴于 String s ,是否有一个好的方法来测试 VALUES 包含 s ?

xvw2m8pv

xvw2m8pv16#

javase9的简明更新

引用数组不正确。对于这个案子,我们要找的是一套。自从JavaSE9以来 Set.of .

private static final Set<String> VALUES = Set.of(
    "AB","BC","CD","AE"
);

给定字符串s,有没有一种测试值是否包含s的好方法

VALUES.contains(s)

o(1)。
正确的类型,不可变,o(1)且简洁。很漂亮*

原始答案详细信息

首先要清除代码。我们已(更正):

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

这是一个可变的静态findbugs会告诉你是非常淘气。不要修改静态,也不要允许其他代码这样做。该字段至少应为私有字段:

private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

(注意,您实际上可以将 new String[]; 位。)
引用数组仍然不好,我们需要一个集合:

private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
     new String[] {"AB","BC","CD","AE"}
));

)偏执的人,比如我,如果把这件事包起来,可能会觉得更自在 Collections.unmodifiableSet -甚至可以公开。)
(*对于品牌来说,collections api仍然缺少不可变的集合类型,语法仍然过于冗长,这是可以预见的

v6ylcynt

v6ylcynt17#

使用简单的循环是最有效的方法。

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

对programcreek的礼遇

umuewwlo

umuewwlo18#

检查数组是否包含值的四种不同方法
使用 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() :
下面的代码是错误的,为了完整起见,这里列出了它。 binarySearch() 只能用于排序数组。你会发现下面的结果很奇怪。这是排序数组时的最佳选项。

public static boolean binarySearch(String[] arr, String targetValue) {  
    return Arrays.binarySearch(arr, targetValue) >= 0;
}

快速示例:

String testValue="test";
String newValueNotInList="newValue";
String[] valueArray = { "this", "is", "java" , "test" };
Arrays.asList(valueArray).contains(testValue); // returns true
Arrays.asList(valueArray).contains(newValueNotInList); // returns false
czq61nw1

czq61nw119#

Arrays.asList(yourArray).contains(yourValue)

警告:这不适用于基元数组(请参阅注解)。

由于java-8,您现在可以使用流了。

String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);

检查 int , double 或者 long 包含值使用 IntStream , DoubleStream 或者 LongStream 分别。

示例

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
ej83mcc0

ej83mcc020#

不必使用快速数组初始化语法,您可以直接使用arrays.aslist方法以类似的方式将其初始化为列表,例如:

public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");

然后你可以做(如上所述):

STRINGS.contains("the string you want to find");
jxct1oxe

jxct1oxe21#

对于长度有限的数组,请使用以下命令(由camickr给出)。这对于重复检查来说很慢,尤其是对于较长的数组(线性搜索)。

Arrays.asList(...).contains(...)

如果您反复检查一组较大的元素,则可以获得快速性能
数组是错误的结构。使用 TreeSet 并将每个元素添加到其中。它对元素进行排序并具有快速响应 exist() 方法(二进制搜索)。
如果元素实现 Comparable &你想要那个 TreeSet 相应排序: ElementClass.compareTo() 方法必须与兼容 ElementClass.equals() :看到三合会没有出现打架吗(java集(缺少项)

TreeSet myElements = new TreeSet();

// Do this for each element (implementing *Comparable*)
myElements.add(nextElement);

// *Alternatively*, if an array is forceably provided from other code:
myElements.addAll(Arrays.asList(myArray));

否则,用你自己的 Comparator :

class MyComparator implements Comparator<ElementClass> {
     int compareTo(ElementClass element1; ElementClass element2) {
          // Your comparison of elements
          // Should be consistent with object equality
     }

     boolean equals(Object otherComparator) {
          // Your equality of comparators
     }
}

// construct TreeSet with the comparator
TreeSet myElements = new TreeSet(new MyComparator());

// Do this for each element (implementing *Comparable*)
myElements.add(nextElement);

回报:检查某些元素的存在:

// Fast binary search through sorted elements (performance ~ log(size)):
boolean containsElement = myElements.exists(someElement);
iaqfqrcu

iaqfqrcu22#

使用Java8,您可以创建一个流并检查流中是否有匹配的条目 "s" :

String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);

或作为通用方法:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}
kknvjkwl

kknvjkwl23#

可以使用arrays类对值执行二进制搜索。如果数组没有排序,则必须使用同一类中的排序函数对数组进行排序,然后在其中进行搜索。

zzoitvuj

zzoitvuj24#

实际上,如果像tom hawtin建议的那样使用hashset,就不必担心排序问题,而且您的速度与预排序数组上的二进制搜索相同,甚至可能更快。
显然,这完全取决于代码的设置方式,但从我的立场来看,顺序是:
在未排序的数组上:
容器
aslist公司
排序二进制(&B)
在排序数组上:
容器
二元的
aslist公司
所以不管怎样,我都会赢的。

o7jaxewo

o7jaxewo25#

一种可能的解决方案:

import java.util.Arrays;
import java.util.List;

public class ArrayContainsElement {
  public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");

  public static void main(String args[]) {

      if (VALUES.contains("AB")) {
          System.out.println("Contains");
      } else {
          System.out.println("Not contains");
      }
  }
}
arknldoa

arknldoa26#

obstupidanswer(但我认为在这里有一个教训):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}
3yhwsihp

3yhwsihp27#

你可以用 ArrayUtils.contains 来自apache commons lang public static boolean contains(Object[] array, Object objectToFind) 请注意,此方法返回 false 如果传递的数组是 null .
还有一些方法可用于各种基本数组。

示例:

String[] fieldsToInclude = { "id", "name", "location" };

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}
polkgigr

polkgigr28#

如果你有googlecollections库,tom的答案可以通过使用immutableset简化很多(http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/immutableset.html)
这确实消除了初始化过程中的大量混乱

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");
1wnzp6jl

1wnzp6jl29#

值得一提的是,我做了一个测试,比较了3个关于速度的建议。我生成了随机整数,将它们转换成字符串并将它们添加到数组中。然后,我搜索了可能的最高数字/字符串,这对于 asList().contains() .
当使用10k数组大小时,结果是:

Sort & Search   : 15
Binary Search   : 0
asList.contains : 0

使用100k阵列时,结果是:

Sort & Search   : 156
Binary Search   : 0
asList.contains : 32

因此,如果按排序顺序创建数组,则二进制搜索速度最快,否则 asList().contains 会是最好的选择。如果您有许多搜索,那么对数组进行排序可能是值得的,这样您就可以使用二进制搜索。这完全取决于你的申请。
我认为这是大多数人所期待的结果。测试代码如下:

import java.util.*;

public class Test
{
    public static void main(String args[])
    {
        long start = 0;
        int size = 100000;
        String[] strings = new String[size];
        Random random = new Random();

        for (int i = 0; i < size; i++)
            strings[i] = "" + random.nextInt( size );

        start = System.currentTimeMillis();
        Arrays.sort(strings);
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Sort & Search : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Search        : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.asList(strings).contains( "" + (size - 1) ));
        System.out.println("Contains      : " + (System.currentTimeMillis() - start));
    }
}

相关问题