我有一个String[]像这样的值:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Run Code Online (Sandbox Code Playgroud)
鉴于String s,有没有一种好的方法来测试是否VALUES包含s?
cam*_*ckr 2828
Arrays.asList(yourArray).contains(yourValue)
Run Code Online (Sandbox Code Playgroud)
警告:这不适用于基元数组(请参阅注释).
String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);
Run Code Online (Sandbox Code Playgroud)
要检查的阵列是否int,double或long包含一个值使用IntStream,DoubleStream或LongStream分别.
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
Run Code Online (Sandbox Code Playgroud)
Tom*_*ine 346
只是为了开始清除代码.我们已经(更正):
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Run Code Online (Sandbox Code Playgroud)
这是一个可变的静态,FindBugs会告诉你这是非常顽皮的.它应该是私人的:
private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
Run Code Online (Sandbox Code Playgroud)
(注意,你实际上可以放弃这new String[];一点.)
所以,参考数组很糟糕,特别是在这里我们需要一个集合:
private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
new String[] {"AB","BC","CD","AE"}
));
Run Code Online (Sandbox Code Playgroud)
(偏执狂的人,比如我自己,如果被包裹起来,可能会感到更放心Collections.unmodifiableSet- 甚至可以公之于众.)
"鉴于String,有没有一种很好的方法来测试VALUES是否包含s?"
VALUES.contains(s)
Run Code Online (Sandbox Code Playgroud)
O(1).
Int*_*cer 195
您可以使用ArrayUtils.contains从Apache的百科全书郎
public static boolean contains(Object[] array, Object objectToFind)
请注意,false如果传递的数组是,则此方法返回null.
还有适用于各种原始数组的方法.
String[] fieldsToInclude = { "id", "name", "location" };
if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
// Do some stuff.
}
Run Code Online (Sandbox Code Playgroud)
icz*_*cza 156
只需简单地手工实现:
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;
}
Run Code Online (Sandbox Code Playgroud)
改进:
的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;
}
Run Code Online (Sandbox Code Playgroud)
Sir*_*dda 69
1)使用List:
public static boolean useList(String[] arr, String targetValue) {
return Arrays.asList(arr).contains(targetValue);
}
Run Code Online (Sandbox Code Playgroud)
2)使用Set:
public static boolean useSet(String[] arr, String targetValue) {
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
}
Run Code Online (Sandbox Code Playgroud)
3)使用简单的循环:
public static boolean useLoop(String[] arr, String targetValue) {
for (String s: arr) {
if (s.equals(targetValue))
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
4)使用Arrays.binarySearch():
下面的代码是错误的,这里列出的是完整性.binarySearch()只能用于排序数组.你会发现下面的结果很奇怪.这是排序数组时的最佳选择.
public static boolean binarySearch(String[] arr, String targetValue) {
int a = Arrays.binarySearch(arr, targetValue);
return a > 0;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
cam*_*ckr 49
为了它的价值,我进行了一项测试,比较了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));
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*des 37
您也可以使用Arrays.asList方法以类似的方式直接将其初始化为List,而不是使用快速数组初始化语法,例如:
public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");
Run Code Online (Sandbox Code Playgroud)
然后你可以做(如上所述):
STRINGS.contains("the string you want to find");
Run Code Online (Sandbox Code Playgroud)
ass*_*ias 35
使用Java 8,您可以创建流并检查流中的任何条目是否匹配"s":
String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);
Run Code Online (Sandbox Code Playgroud)
或者作为通用方法:
public static <T> boolean arrayContains(T[] array, T value) {
return Arrays.stream(array).anyMatch(value::equals);
}
Run Code Online (Sandbox Code Playgroud)
Tom*_*ine 18
ObStupidAnswer(但我认为这里有一个教训):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
Run Code Online (Sandbox Code Playgroud)
小智 13
实际上,如果您使用HashSet <String>,因为Tom Hawtin建议您不必担心排序,并且您的速度与预先排序的数组上的二进制搜索相同,可能更快.
这一切都取决于您的代码的设置方式,显然,但从我的立场来看,订单将是:
在未排序的数组上:
在排序的数组上:
无论哪种方式,HashSet为胜利.
jho*_*ges 11
如果你有谷歌馆藏库,可以通过使用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");
Run Code Online (Sandbox Code Playgroud)
小智 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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
开发人员经常这样做:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
Run Code Online (Sandbox Code Playgroud)
上面的代码可以工作,但是不需要先将列表转换为set.将列表转换为集合需要额外的时间.它可以很简单:
Arrays.asList(arr).contains(targetValue);
Run Code Online (Sandbox Code Playgroud)
要么
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
Run Code Online (Sandbox Code Playgroud)
第一个比第二个更可读.
使用简单的循环是最有效的方法.
boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
小智 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);
Run Code Online (Sandbox Code Playgroud)
自 Java 9 以来
数组 VALUES 可能包含重复项的最短解决方案
List.of(VALUES).contains(s);
Run Code Online (Sandbox Code Playgroud)
对于有限长度的数组,请使用以下内容(由camickr给出)。对于重复检查,这很慢,特别是对于较长的数组(线性搜索)而言。
Arrays.asList(...).contains(...)
Run Code Online (Sandbox Code Playgroud)为了提高性能,如果您反复检查较大的一组元素
数组是错误的结构。使用a TreeSet并将每个元素添加到其中。它对元素进行排序并具有快速的exist()方法(二进制搜索)。
如果元素实现Comparable&您想要相应地TreeSet排序:
ElementClass.compareTo()方法必须与兼容ElementClass.equals():请参阅三合会未露面打架?(Java Set缺少项目)
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));
Run Code Online (Sandbox Code Playgroud)否则,请使用您自己的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);
Run Code Online (Sandbox Code Playgroud)回报:检查某些元素的存在:
// Fast binary search through sorted elements (performance ~ log(size)):
boolean containsElement = myElements.exists(someElement);
Run Code Online (Sandbox Code Playgroud)使用以下内容(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);
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
正如您在上面的代码中看到的那样,还有其他实用方法ObjectUtils.equals()和ArrayUtils.indexOf(),它们也在其他地方使用过。
小智 5
如果你不希望它区分大小写
Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
Run Code Online (Sandbox Code Playgroud)
小智 5
使用下面 -
String[] values = {"AB","BC","CD","AE"};
String s = "A";
boolean contains = Arrays.stream(values).anyMatch(v -> v.contains(s));
Run Code Online (Sandbox Code Playgroud)