我有一个String[],其值如下:

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

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


当前回答

如果数组未排序,则必须遍历所有内容,并对每个内容调用equals。

如果数组已排序,则可以执行二进制搜索,Arrays类中有一个。

一般来说,如果要进行大量的成员身份检查,您可能希望将所有内容存储在集合中,而不是存储在数组中。

其他回答

开发人员通常会:

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

上面的代码可以工作,但不需要先将列表转换为set。将列表转换为集合需要额外的时间。它可以简单到:

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

or

for (String s : arr) {
    if (s.equals(targetValue))
        return true;
}

return false;

第一个比第二个更可读。

Java SE 9的简明更新

引用数组不正确。对于这种情况,我们需要一套。从Java SE 9开始,我们有Set.of。

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

“给定字符串s,是否有测试VALUES是否包含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"};

(注意,实际上可以删除新的String[];位。)

引用数组仍然不好,我们需要一个集合:

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

(偏执狂的人,比如我自己,如果这是用Collections.unmodifiedSet包装的话,可能会更放心——然后甚至可以公开。)

(*在品牌方面,集合API仍然可以预见地缺少不可变的集合类型,语法对于我的口味来说仍然过于冗长。)

只需手动执行即可:

public static <T> boolean contains(final T[] array, final T v) {
    for (final T e : array)
        if (e == v || v != null && v.equals(e))
            return true;

    return false;
}

改进:

v!=null条件在方法中是常量。在方法调用期间,它始终计算为相同的布尔值。因此,如果输入数组很大,只计算一次这个条件会更有效,我们可以根据结果在for循环中使用简化/更快的条件。改进的contains()方法:

public static <T> boolean contains2(final T[] array, final T v) {
    if (v == null) {
        for (final T e : array)
            if (e == null)
                return true;
    } 
    else {
        for (final T e : array)
            if (e == v || v.equals(e))
                return true;
    }

    return false;
}

您可以直接使用Arrays.asList方法以类似的方式将其初始化为List,而不是使用快速数组初始化语法,例如:

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

然后您可以执行(如上所述):

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

在下面使用-

    String[] values = {"AB","BC","CD","AE"};
    String s = "A";
    boolean contains = Arrays.stream(values).anyMatch(v -> v.contains(s));