私はそのString[]
ような値を持っています:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
与えられたString s
、をVALUES
含むs
かどうかをテストする良い方法はありますか?
私はそのString[]
ような値を持っています:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
与えられたString s
、をVALUES
含むs
かどうかをテストする良い方法はありますか?
回答:
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
それぞれ使用します。
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
ArrayList
ません。java.util.ArrayList
返される実際のクラスは次のようにjava.util.Arrays.ArrayList<E>
定義されますpublic class java.util.Arrays {private static class ArrayList<E> ... {}}
。
参照配列は不良です。この場合、私たちはセットの後です。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"};
これは変更可能なstaticであり、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
-そしてそれは公開されることさえできます。)
(*ブランドについてもう少し説明すると、コレクションAPIには、不変のコレクション型がまだ見当たらないことが予想され、構文は、私の好みではまだ非常に冗長です。)
Arrays.asList
か)?
TreeSet
はになりますO(log n)
。HashSet
sは、バケット内の要素の平均数がほぼ一定になるようにスケーリングされます。少なくとも2 ^ 30までの配列の場合。たとえば、big-O分析が無視するハードウェアキャッシュの影響があるかもしれません。また、ハッシュ関数が効果的に機能していると想定しています。
Apache Commons LangArrayUtils.contains
から使用できます
public static boolean contains(Object[] array, Object objectToFind)
このメソッドが返すことに注意してください false
、渡された配列がの場合にnull
。
すべての種類のプリミティブ配列に使用できるメソッドもあります。
String[] fieldsToInclude = { "id", "name", "location" };
if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
// Do some stuff.
}
単に手で実装するだけです:
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
が大きい場合は、この条件を1回だけ評価する方が効率的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;
}
Collection.contains(Object)
Arrays
とArrayList
、これが必ずしも速く使用したバージョン以上であることが判明Arrays.asList(...).contains(...)
。を作成するオーバーヘッドArrayList
は非常に小さく、ArrayList.contains()
上に示したもの(JDK 7)よりもスマートなループ(実際には2つの異なるループを使用)を使用します。
1)リストの使用:
public static boolean useList(String[] arr, String targetValue) {
return Arrays.asList(arr).contains(targetValue);
}
2)セットの使用:
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
配列が並べ替えられていない場合は、すべてを反復処理し、それぞれに対してequalsを呼び出す必要があります。
配列がソートされている場合、バイナリ検索を実行できます。Arraysクラスに1つあります。
一般的に言えば、多数のメンバーシップチェックを行う場合は、すべてを配列ではなくセットに格納することをお勧めします。
価値があることについて、速度の3つの提案を比較するテストを実行しました。ランダムな整数を生成し、それらを文字列に変換して、配列に追加しました。次に、可能な最大の数値/文字列を検索しましたasList().contains()
。これは、の最悪のシナリオです。
10Kの配列サイズを使用すると、結果は次のようになります。
並べ替えと検索:15 バイナリ検索:0 asList.contains:0
100K配列を使用すると、結果は次のようになります。
並べ替えと検索:156 バイナリ検索: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));
}
}
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);
}
anyMatch
JavaDocはそれを追加している"...May not evaluate the predicate on all elements if not necessary for determining the result."
ので、一致を見つけた後に処理を続行する必要がない場合もあります。
Arraysクラスを使用して、値のバイナリ検索を実行できます。配列が並べ替えられていない場合は、同じクラスの並べ替え関数を使用して配列を並べ替え、検索する必要があります。
ObStupidAnswer(ただし、ここのどこかに教訓があると思います):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
実際、Tom Hawtinが提案したようにHashSet <String>を使用する場合、並べ替えを心配する必要はありません。速度は、事前に並べ替えられた配列でのバイナリ検索と同じで、おそらくさらに高速です。
すべては、コードのセットアップ方法に依存しますが、私が立っているところから見ると、順序は次のようになります。
上の未ソート配列:
ソートされた配列:
どちらにしても、勝利のためのHashSet。
考えられる解決策の1つ:
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");
}
}
}
開発者はしばしば次のことを行います:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
上記のコードは機能しますが、リストを最初に設定するために変換する必要はありません。リストをセットに変換するには、追加の時間が必要です。次のように簡単にできます。
Arrays.asList(arr).contains(targetValue);
または
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
最初のものは2番目のものより読みやすいです。
これを行うには、単純なループを使用するのが最も効率的です。
boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
Programcreekへの礼儀
Java 8つの使用ストリーム。
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);
限られた長さの配列の場合は、以下を使用します(camickrで指定)。これは、特に長い配列(線形検索)の場合、繰り返しチェックを行うと遅くなります。
Arrays.asList(...).contains(...)
要素のより大きなセットを繰り返しチェックする場合、高速パフォーマンスのため
配列は間違った構造です。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));
それ以外の場合は、独自のものを使用します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);
TreeSet
?HashSet
より高速(O(1))であり、順序付けは必要ありません。
これを試して:
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");
}
以下を使用します(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()
、他の場所でも使用されています。
これをチェックして
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
}
}
else
for を入力します(その配列で「AB」を探している場合、3つの値が「AB」ではないため、3回そこに移動します")。
Arrays.asList()->次に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.
}
Arrays.asList
O(n)ではありません。それは単なる軽量ラッパーです。実装を見てください。
使用する Array.BinarySearch(array,obj)
配列内の特定のオブジェクトを見つけるためにします。
例:
if (Array.BinarySearch(str, i) > -1)` → true --exists
false-存在しません
Array.BinarySearch
およびArray.FindIndex
.NETメソッドであり、Javaには存在しません。
The array must be sorted prior to making this call. If it is not sorted, the results are undefined.
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
a を使用すると、不必要なaの生成が防止されます。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 );
…
私はプリミティブ型byteとbyte []を使用して低レベルのJavaを扱っているので、これまでに得た最高のものはbytes-java からのものですhttps://github.com/patrickfav/bytes-javaは素晴らしい作品のようです
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));
}