我有一个String[]
,其价值如下:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
鉴于String s
,是否有一种测试VALUES
是否包含s
的好方法?
答案 0 :(得分:2710)
Arrays.asList(yourArray).contains(yourValue)
警告:这不适用于基元数组(请参阅注释)。
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
要检查int
,double
或long
数组是否包含值,请分别使用IntStream
,DoubleStream
或LongStream
。< / p>
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
答案 1 :(得分:334)
只需清除代码即可。我们已经(更正):
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
中,可能会感到更放心 - 甚至可以将其公之于众。)
“给定字符串s,是否有一种测试VALUES是否包含s的好方法?”
VALUES.contains(s)
O(1)。
更新:自Java SE 9起,我们有Set.of
。
private static final Set<String> VALUES = Set.of(
"AB","BC","CD","AE"
);
正确类型,不可变, O(1)和简洁。美丽。
(为了更多关于品牌,收藏API可以预见仍然缺少不可变的集合类型,而且根据我的口味,语法仍然过于冗长。)
答案 2 :(得分:188)
您可以使用Apache Commons Lang
中的ArrayUtils.contains
public static boolean contains(Object[] array, Object objectToFind)
请注意,如果传递的数组为false
,则此方法返回null
。
还有各种原始数组可用的方法。
String[] fieldsToInclude = { "id", "name", "location" };
if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
// Do some stuff.
}
答案 3 :(得分:151)
只需简单地手工实施:
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
条件在方法内是常量。它始终在方法调用期间计算为相同的布尔值。因此,如果输入array
很大,则仅评估此条件一次更有效,并且我们可以基于结果在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;
}
答案 4 :(得分:68)
如果数组未排序,则必须迭代所有内容并在每个数组上调用equals。
如果数组已排序,您可以进行二分查找,Arrays类中有一个。
一般来说,如果要进行大量的成员资格检查,您可能希望将所有内容存储在Set中,而不是存储在数组中。
答案 5 :(得分:66)
Four Different Ways to Check If an Array Contains a Value
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 binarySearch(String[] arr, String targetValue) {
int a = Arrays.binarySearch(arr, targetValue);
return a > 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
答案 6 :(得分:48)
为了什么值得,我进行了一项测试,比较了3个速度建议。我生成了随机整数,将它们转换为String并将它们添加到数组中。然后我搜索了最高可能的数字/字符串,这对于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));
}
}
答案 7 :(得分:34)
使用Java 8,您可以创建一个流并检查流中的任何条目是否与"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);
}
答案 8 :(得分:33)
您也可以使用Arrays.asList方法以类似的方式直接将其初始化为List,而不是使用快速数组初始化语法,例如:
public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");
然后你可以做(如上所述):
STRINGS.contains("the string you want to find");
答案 9 :(得分:26)
您可以使用Arrays class对值执行二进制搜索。如果您的数组未排序,则必须使用同一类中的排序函数对数组进行排序,然后搜索它。
答案 10 :(得分:18)
ObStupidAnswer(但我认为这里有一个教训):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
答案 11 :(得分:13)
实际上,如果你使用HashSet&lt; String&gt;正如Tom Hawtin建议您不必担心排序,并且您的速度与预先排序的数组上的二进制搜索相同,可能更快。
这一切都取决于您的代码的设置方式,显然,但从我的立场来看,订单将是:
在未排序的数组上:
在排序数组上:
无论哪种方式,胜利的HashSet。
答案 12 :(得分:11)
如果你有google集合库,可以使用ImmutableSet(http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet)简化Tom的答案。 HTML)
这确实从建议的初始化
中消除了很多混乱private static final Set<String> VALUES = ImmutableSet.of("AB","BC","CD","AE");
答案 13 :(得分:10)
一种可能的解决方案:
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");
}
}
}
答案 14 :(得分:8)
开发人员经常这样做:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
上面的代码有效,但不需要先将列表转换为set。将列表转换为集合需要额外的时间。它可以很简单:
Arrays.asList(arr).contains(targetValue);
或
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
第一个比第二个更可读。
答案 15 :(得分:7)
在 Java 8 中使用Streams。
List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
答案 16 :(得分:7)
使用简单的循环是最有效的方法。
boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
答案 17 :(得分:5)
对于有限长度的数组,请使用以下内容(由 camickr 指定)。重复检查的速度很慢,尤其是对于较长的阵列(线性搜索)。
Arrays.asList(...).contains(...)
如果您反复检查更多元素
,以获得快速性能数组是错误的结构。使用 TreeSet
并将每个元素添加到其中。它对元素进行排序,并具有快速exist()
方法(二进制搜索)。
如果元素实现Comparable
&amp;您希望TreeSet
相应地排序:
ElementClass.compareTo()
方法必须与ElementClass.equals()
兼容:请参阅Triads not showing up to fight? (Java Set missing an item)
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);
答案 18 :(得分:4)
试试这个:
ArrayList<Integer> arrlist = new ArrayList<Integer>(8);
// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);
boolean retval = arrlist.contains(10);
if (retval == true) {
System.out.println("10 is contained in the list");
}
else {
System.out.println("10 is not contained in the list");
}
答案 19 :(得分:4)
使用以下内容(此代码中的contains()
方法为ArrayUtils.in()
):
ObjectUtils.java
public class ObjectUtils{
/**
* A null safe method to detect if two objects are equal.
* @param object1
* @param object2
* @return true if either both objects are null, or equal, else returns false.
*/
public static boolean equals(Object object1, Object object2){
return object1==null ? object2==null : object1.equals(object2);
}
}
ArrayUtils.java
public class ArrayUtils{
/**
* Find the index of of an object is in given array, starting from given inclusive index.
* @param ts Array to be searched in.
* @param t Object to be searched.
* @param start The index from where the search must start.
* @return Index of the given object in the array if it is there, else -1.
*/
public static <T> int indexOf(final T[] ts, final T t, int start){
for(int i = start; i < ts.length; ++i)
if(ObjectUtils.equals(ts[i], t))
return i;
return -1;
}
/**
* Find the index of of an object is in given array, starting from 0;
* @param ts Array to be searched in.
* @param t Object to be searched.
* @return indexOf(ts, t, 0)
*/
public static <T> int indexOf(final T[] ts, final T t){
return indexOf(ts, t, 0);
}
/**
* Detect if the given object is in the given array.
* @param ts Array to be searched in.
* @param t Object to be searched.
* @return If indexOf(ts, t) is greater than -1.
*/
public static <T> boolean in(final T[] ts, final T t){
return indexOf(ts, t) > -1 ;
}
}
正如您在上面的代码中所看到的,还有其他实用方法ObjectUtils.equals()
和ArrayUtils.indexOf()
,它们也在其他地方使用过。
答案 20 :(得分:3)
检查
String[] VALUES = new String[] {"AB","BC","CD","AE"};
String s;
for(int i=0; i< VALUES.length ; i++)
{
if ( VALUES[i].equals(s) )
{
// do your stuff
}
else{
//do your stuff
}
}
答案 21 :(得分:3)
使用Array.BinarySearch(array,obj)
查找数组中的给定对象。
示例:
if (Array.BinarySearch(str, i) > -1)` → true --exists
false - 不存在
答案 22 :(得分:3)
Arrays.asList() - &gt;然后调用contains()方法将始终有效,但搜索算法要好得多,因为您不需要在数组周围创建一个轻量级的列表包装器,这就是Arrays.asList()所做的。
public boolean findString(String[] strings, String desired){
for (String str : strings){
if (desired.equals(str)) {
return true;
}
}
return false; //if we get here… there is no desired String, return false.
}
答案 23 :(得分:3)
如果您不希望它区分大小写
Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
答案 24 :(得分:2)
最短的解决方案
数组 VALUES
可能包含重复项
从 Java 9 开始
List.of(VALUES).contains(s);
答案 25 :(得分:1)
尝试使用Java 8谓词测试方法
这里是一个完整的例子。
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
public static final List<String> VALUES = Arrays.asList("AA", "AB", "BC", "CD", "AE");
public static void main(String args[]) {
Predicate<String> containsLetterA = VALUES -> VALUES.contains("AB");
for (String i : VALUES) {
System.out.println(containsLetterA.test(i));
}
}
}
http://mytechnologythought.blogspot.com/2019/10/java-8-predicate-test-method-example.html
https://github.com/VipulGulhane1/java8/blob/master/Test.java
答案 26 :(得分:1)
当我使用基本类型byte和byte []处理低级Java时,到目前为止,我得到的最好的结果是 bytes-java https://github.com/patrickfav/bytes-java似乎是一件很不错的工作
答案 27 :(得分:0)
创建一个最初设置为false的布尔值。运行循环以检查数组中的每个值,并与要检查的值进行比较。如果你得到一个匹配项,将boolean设置为true并停止循环。然后断言布尔值为真。
答案 28 :(得分:0)
使用 Spliterator
防止不必要的生成 List
boolean found = false; // class variable
String search = "AB";
Spliterator<String> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
while( (! found) && spl.tryAdvance(o -> found = o.equals( search )) );
found == true
(如果数组中包含search
此做用于基元数组
public static final int[] VALUES = new int[] {1, 2, 3, 4};
boolean found = false; // class variable
int search = 2;
Spliterator<Integer> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
…
答案 29 :(得分:-2)
您可以通过两种方法进行检查
A)通过将数组转换为字符串,然后通过.contains方法检查所需的字符串
String a=Arrays.toString(VALUES);
System.out.println(a.contains("AB"));
System.out.println(a.contains("BC"));
System.out.println(a.contains("CD"));
System.out.println(a.contains("AE"));
B)这是一种更有效的方法
Scanner s=new Scanner(System.in);
String u=s.next();
boolean d=true;
for(int i=0;i<VAL.length;i++)
{
if(VAL[i].equals(u)==d)
System.out.println(VAL[i] +" "+u+VAL[i].equals(u));
}