Comment déterminer si un tableau contient une valeur particulière en Java?
j'ai un String[]
avec des valeurs comme:
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
étant donné String s
, y a-t-il une bonne façon de vérifier si VALUES
contient s
?
27 réponses
Arrays.asList(yourArray).contains(yourValue)
Attention: cela ne fonctionne pas pour les tableaux de primitives (voir les commentaires).
depuis java-8
vous pouvez maintenant utiliser un Stream
pour vérifier si un tableau de int
, double
ou long
contient une valeur (en utilisant respectivement un IntStream
, DoubleStream
ou LongStream
)
exemple
int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);
Juste pour effacer le code pour commencer avec. Nous avons (corrigé):
public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
c'est un statique mutable que FindBugs vous dira très vilain. Il devrait être privé:
private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};
(notez que vous pouvez en fait laisser tomber le bit new String[];
.)
ainsi, les tableaux de référence sont mauvais, et en particulier ici nous voulons un ensemble:
private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
new String[] {"AB","BC","CD","AE"}
));
(personnes Paranoïaques, comme moi, peuvent se sentir plus à l'aise si c'était enveloppé dans Collections.unmodifiableSet
- il pourrait même être rendu public.)
"Chaîne de caractères s, est-il un bon moyen de tester si les VALEURS contient s?"
VALUES.contains(s)
O (1).
vous pouvez utiliser ArrayUtils.contains
de Apache Commons Lang
public static boolean contains(Object[] array, Object objectToFind)
notez que cette méthode retourne false
si le tableau passé est null
.
il y a aussi des méthodes disponibles pour les tableaux primitifs de toutes sortes.
exemple:
String[] fieldsToInclude = { "id", "name", "location" };
if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
// Do some stuff.
}
je suis surpris que personne n'ait suggéré de simplement l'implémenter à la main:
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;
}
amélioration:
la condition v != null
est constante à l'intérieur de la méthode, elle évalue toujours à la même valeur booléenne pendant l'appel de méthode. Donc si l'entrée array
est grande, il est plus efficace d'évaluer cette condition qu'une seule fois et nous pouvons utiliser une condition simplifiée/plus rapide à l'intérieur de la boucle for
basée sur le résultat. La méthode améliorée 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;
}
si le tableau n'est pas trié, vous devrez itérer sur tout et faire un appel à égaux sur chacun.
si le tableau est trié, vous pouvez faire une recherche binaire, il y en a une dans la classe tableaux .
en général, si vous allez faire beaucoup de contrôles d'adhésion, vous pouvez vouloir stocker tout dans un ensemble, pas dans un tableau.
quatre différentes façons de vérifier si un tableau contient une valeur
1) En Utilisant La Liste:
public static boolean useList(String[] arr, String targetValue) {
return Arrays.asList(arr).contains(targetValue);
}
2) Utilisant Set:
public static boolean useSet(String[] arr, String targetValue) {
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
}
3) utilisant une boucle simple:
public static boolean useLoop(String[] arr, String targetValue) {
for (String s: arr) {
if (s.equals(targetValue))
return true;
}
return false;
}
4) Utilisant Des Matrices.binarySearch ():
le code ci-dessous est erroné, il est énuméré ici pour l'exhaustivité. binarySearch () ne peut être utilisé que sur des tableaux triés. Vous trouverez le résultat c'est bizarre ci-dessous. C'est la meilleure option lorsque le tableau est trié.
public static boolean binarySearch(String[] arr, String targetValue) {
int a = Arrays.binarySearch(arr, targetValue);
return a > 0;
}
Rapide Exemple:
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
pour ce que sa valeur j'ai couru un test comparant les 3 suggestions pour la vitesse. J'ai généré des entiers aléatoires, les ai convertis en chaîne et les ai ajoutés à un tableau. J'ai alors cherché le nombre/chaîne le plus élevé possible, ce qui serait le pire des scénarios pour asList().contenir.)(
Lorsqu'on utilise une taille de tableau de 10K les résultats où:
Sort & Search : 15 Binary Search : 0 asList.contains : 0
en utilisant un tableau de 100K les résultats où:
Sort & Search : 156 Binary Search : 0 asList.contains : 32
donc si la recherche binaire est la plus rapide, sinon asList().contient sera le chemin à parcourir. Si vous avez beaucoup de recherches, alors il peut être utile de trier le tableau de sorte que vous pouvez utiliser la recherche binaire. Tout dépend de votre application.
je pense que ce sont les résultats auxquels la plupart des gens s'attendraient. Voici le code d'essai:
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));
}
}
au lieu d'utiliser la syntaxe quick array initialsation, vous pourriez simplement l'initialiser comme une liste immédiatement de la même manière en utilisant les tableaux.méthode asList par exemple:
public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");
alors vous pouvez faire (comme ci-dessus): STRINGS.contains("the string you want to find");
avec Java 8, Vous pouvez créer un flux et vérifier si des entrées dans le flux correspondent à "s"
:
String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);
ou comme méthode générique:
public static <T> boolean arrayContains(T[] array, T value) {
return Arrays.stream(array).anyMatch(value::equals);
}
vous pouvez utiliser la classe de tableaux pour effectuer une recherche binaire pour la valeur. Si votre tableau n'est pas trié, vous devrez utiliser les fonctions de tri dans la même catégorie pour trier le tableau, puis la recherche à travers elle.
ObStupidAnswer (mais je pense qu'il y a une leçon ici quelque part):
enum Values {
AB, BC, CD, AE
}
try {
Values.valueOf(s);
return true;
} catch (IllegalArgumentException exc) {
return false;
}
en fait , si vous utilisez le HashSet comme Tom Hawtin l'a proposé, vous n'avez pas besoin de vous soucier du tri et votre vitesse est la même que pour la recherche binaire sur un tableau prédéfini, probablement encore plus rapide.
tout dépend de la façon dont votre code est configuré, évidemment, mais d'où je me tiens, l'ordre serait:
sur un tableau non trié:
- HashSet
- asList
- de type Binaire
sur un tableau trié:
- HashSet
- binaire
- asList
Donc de toute façon, HashSet ftw
si vous disposez de la bibliothèque de collections google, la réponse de Tom peut être grandement simplifiée en utilisant ImmutableSet (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html)
cela enlève vraiment beaucoup d'encombrement de l'initialisation proposée
private static final Set<String> VALUES = ImmutableSet.of("AB","BC","CD","AE");
une solution possible:
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");
}
}
}
les Développeurs souvent:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
Le code ci-dessus fonctionne, mais il n'est pas nécessaire de convertir une liste en premier. La conversion d'une liste en un ensemble demande du temps supplémentaire. Il peut aussi simple que:
Arrays.asList(arr).contains(targetValue);
ou
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
Le premier est plus lisible que la seconde.
Dans Java 8 utiliser les Flux.
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);
L'utilisation d'une boucle simple est la manière la plus efficace de le faire.
boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
gracieuseté de Programcreek
-
pour les tableaux de longueur limitée, utilisez ce qui suit (comme indiqué par camickr ). Ceci est lent pour les contrôles répétés, particulièrement pour les tableaux plus longs (recherche linéaire).
Arrays.asList(...).contains(...)
-
Pour des performances rapides si vous de vérifier à plusieurs reprises contre un plus grand ensemble d'éléments
-
un tableau est la mauvaise structure. Utiliser un
TreeSet
et y ajouter chaque élément. Il trie des éléments et a une méthode rapideexist()
(recherche binaire). -
Si les éléments de mettre en œuvre
Comparable
et vous voulez que leTreeSet
triés en conséquence:ElementClass.compareTo()
la méthode doit être compatible avecElementClass.equals()
: voir les Triades ne se présentent pas au combat? (Java Jeu manque un article)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));
-
sinon, utilisez votre propre
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);
-
La récompense: vérifier l'existence de certains éléments:
// Fast binary search through sorted elements (performance ~ log(size)): boolean containsElement = myElements.exists(someElement);
-
tableaux.asList () - > alors appeler la méthode contains () fonctionnera toujours, mais un algorithme de recherche est beaucoup mieux car vous n'avez pas besoin de créer un enveloppeur de liste léger autour du tableau, qui est ce que les tableaux.asList () si.
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.
}
Utiliser Array.BinarySearch(array,obj)
pour trouver l'objet donné dans le tableau ou non.
Ex:
if (Array.BinarySearch(str, i) > -1)
-->true --existe
faux-pas
je suis très en retard pour me joindre à cette discussion, mais puisque mon approche dans la résolution de ce problème, quand je l'ai affronté il y a quelques années, était un peu différente des autres réponses déjà publiées ici, je poste Cette solution que j'ai utilisée à ce moment-là, ici, au cas où quelqu'un la trouve utile: (la méthode contains()
est ArrayUtils.in()
dans ce code.)
objectifs.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 ;
}
}
comme vous pouvez le voir dans le code ci-dessus, qu'il ya d'autres méthodes d'utilité ObjectUtils.equals()
et ArrayUtils.indexOf()
, qui ont été utilisés à d'autres endroits aussi bien.
cela peut être aussi simple que:
String[] VALUE = new String[] {"AB","BC","CD","AE"};
Arrays.asList(VALUE).contains(s);
Cochez cette
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
}
}
essayez ceci:
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");
}
Si vous ne voulez pas qu'il soit sensible à la casse
Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);
Voici mon code simple en utilisant la classe Arrays du paquet util. Cela peut se faire de bien d'autres façons, mais pour répondre à la question, j'ai d'abord pensé à cette approche.
String a[] = {"abc","xyz","pqr"};
System.out.println(Arrays.asList(a).contains("abc")); //will return true
System.out.println(Arrays.asList(a).contains("abcd")); // will return false
crée un booléen initialement défini à false. Exécuter une boucle pour vérifier chaque valeur du tableau et comparer à la valeur de la vérification. Si jamais vous avez une correspondance, mettez boolean à true et arrêtez la boucle. Puis affirmer que le booléen est vrai.