Java, Vereinfachte Überprüfung, ob das Array int int enthält


94

Grundsätzlich hat mein Partner gesagt, dass ich meinen Code kürzer machen könnte, indem ich auf andere Weise überprüfe, ob ein int-Array ein int enthält, obwohl er mir nicht sagt, was es ist: P.

Aktuell:

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}

Habe dies auch versucht, obwohl es aus irgendeinem Grund immer false zurückgibt.

public boolean contains(final int[] array, final int key) {
    return Arrays.asList(array).contains(key);
}

Könnte mir jemand helfen?

Danke dir.


8
Ihr Aufruf von Arrays.asList (...) nimmt ein vararg an, dh es wird die beliebige Anzahl von Argumenten, die Sie möglicherweise übergeben, in eine Liste eingeschlossen. In Ihrem Fall erhalten Sie eine Liste von Arrays mit einem einzelnen Element, und diese Liste enthält offensichtlich nicht das int.
Sarcan

Dein Kommentar bedeutet was jetzt?
Sarcan

überprüfen Hashsetanhand Wiederaufnahmeverfahren Mechanismus Antwort. Es ist der schnellste Weg.
Amit Deshpande

Ich sehe keinen Grund, Ihren ursprünglichen Code kürzer zu machen, da Ihr Argument ein primitives Array ist und Ihr Code sehr klar und direkt ist. ArrayListDie Implementierung macht das Gleiche.
Genzer

Ich würde Ihren Code nicht kürzer machen. (1) Arraylist macht das Gleiche wie Sie. (2) - Wichtiger ist, dass der Verkürzungscode mit Arrays.asList ein neues Objekt erstellt, was bei leistungskritischem Code problematisch sein kann. Das erste Code-Snippet ist das Beste, was Sie tun können.
Martin Podval

Antworten:


37

Hier ist die Java 8-Lösung

public static boolean contains(final int[] arr, final int key) {
    return Arrays.stream(arr).anyMatch(i -> i == key);
}

62

Sie könnten einfach ArrayUtils.containsvon verwenden Apache Commons Lang library.

public boolean contains(final int[] array, final int key) {     
    return ArrayUtils.contains(array, key);
}

1
Solange Sie ArrayUtils verwenden, gibt es einen Grund, ArrayUtils.contains
mjohnsonengr

2
Kein Grund :)
Reimeus

20
Es ist erwähnenswert, dass dies ArrayUtils.contains()Teil der Apache Commons LangBibliothek ist. Obwohl dies eine großartige Bibliothek ist, ist es wahrscheinlich immer noch keine gute Idee, eine externe Abhängigkeit hinzuzufügen, um zu überprüfen, ob das Array ein Element enthält: D
Krzysiek

1
ArrayUtils gehört der Vergangenheit an. Java 8+ und Guava haben ziemlich tolle Extras !!
TriCore

34

Es ist weil Arrays.asList(array)Rückkehr List<int[]>.arrayDas Argument wird als ein Wert behandelt, den Sie umbrechen möchten (Sie erhalten eine Liste der Ints-Arrays), nicht als vararg.

Beachten Sie, dass es funktioniert die Arbeit mit Objekttypen (nicht Primitiven):

public boolean contains(final String[] array, final String key) {
    return Arrays.asList(array).contains(key);
}

oder auch:

public <T>  boolean contains(final T[] array, final T key) {
    return Arrays.asList(array).contains(key);
}

Aber Sie können nicht haben List<int>und Autoboxing funktioniert hier nicht.


1
Warum funktioniert Autoboxing nicht, weil es als endgültig deklariert ist?
Subhashis

18

Guave bietet zusätzliche Methoden für primitive Typen. Darunter befindet sich eine Methode, die dieselben Argumente wie Ihre verwendet.

public boolean contains(final int[] array, final int key) {
    return Ints.contains(array, key);
}

Sie können die Guavenversion auch statisch importieren.

Siehe Erklärte Guavenprimitive


18

Ein anderer Weg:

public boolean contains(final int[] array, final int key) {  
     Arrays.sort(array);  
     return Arrays.binarySearch(array, key) >= 0;  
}  

Dadurch wird das übergebene Array geändert. Sie hätten die Möglichkeit, das Array zu kopieren und am ursprünglichen Array zu arbeiten, dh int[] sorted = array.clone();
dies ist nur ein Beispiel für Funktionscode. Die Laufzeit ist wie O(NlogN)du bistO(N)


30
Ich denke, ich wäre überrascht, wenn eine containsMethode mein Array modifizieren würde.
Zong

@ ZongLi: Dies ist nur ein Beispiel für das OP. Aktualisiertes OP, wenn wir nicht auswählen
Cratylus

5
Aus javadoc von binarySearch (): "Der Rückgabewert ist genau dann> = 0, wenn der Schlüssel gefunden wird." also sollte Arrays.binarySearch (Array, Schlüssel)> = 0 zurückgegeben werden!
icza

Ergänzung: Der Rückgabewert von binarySearch () ist (- (Einfügemarke) - 1), wenn kein Schlüssel enthalten ist, der wahrscheinlich ein anderer Wert als -1 ist.
icza

Dies kann nicht sein, -1wenn es wahr sein soll. "Die Einfügemarke ist definiert als der Punkt, an dem der Schlüssel in die Liste eingefügt wird: der Index des ersten Elements, der größer als der Schlüssel ist, oder list.size (), wenn alle Elemente in der Liste kleiner als der angegebene Schlüssel sind. ". Muss sagen >= 0.
Brian

17

Ich weiß, dass es super spät ist, aber versuche es Integer[]stattdessen int[].


Das ist die Lösung.
Atheesh27

Upvote für die funktionierende Antwort, Danke Willy
ucMedia

1

1. einmalige Verwendung

List<T> list=Arrays.asList(...)
list.contains(...)

2. Verwenden Sie HashSet zur Leistungsüberlegung, wenn Sie mehr als einmal verwenden.

Set <T>set =new HashSet<T>(Arrays.asList(...));
set.contains(...)

1

Versuche dies:

public static void arrayContains(){
    int myArray[]={2,2,5,4,8};

    int length=myArray.length;

    int toFind = 5;
    boolean found = false;

    for(int i = 0; i < length; i++) {
        if(myArray[i]==toFind) {
            found=true;
        }
    }

    System.out.println(myArray.length);
    System.out.println(found); 
}

1

Sie können Ihr primitives int-Array mit dem folgenden Java 8-Code in eine Arrayliste von Ganzzahlen konvertieren.

List<Integer> arrayElementsList = Arrays.stream(yourArray).boxed().collect(Collectors.toList());

Verwenden Sie dann die contains()Methode, um zu überprüfen, ob die Liste ein bestimmtes Element enthält.

boolean containsElement = arrayElementsList.contains(key);

0

Dies funktionierte in Java 8

public static boolean contains(final int[] array, final int key)
{
return Arrays.stream(array).anyMatch(n->n==key);
}

Es sollte sofort bei der ersten Übereinstimmung zurückkehren. Stattdessen werden weiterhin alle Elemente im Array gescannt, selbst wenn die Übereinstimmung gefunden wurde. (Betrachten Sie eine Reihe von Billionen Gegenständen)
TriCore

Sie haben Recht, versuchen Sie, dass dieser öffentliche statische Boolesche Wert enthält (final int [] array, final int key) {return Arrays.stream (Array) .anyMatch (n-> n == key); }
Farhad Baghirov

Der Java 8-Stream anyMatch ist eine Kurzschlussoperation und scannt nicht alle Elemente im Array.
LordParsley

@LordParsley Über dem Ziel des Codes steht, das Element im Array zu überprüfen und nicht alle Elemente des Arrays zu scannen.
Farhad Baghirov

Entschuldigung, ich sehe, dass die Antwort bearbeitet wurde. Ich habe nur wiederholt, dass es korrekt ist, da nicht alle gescannt werden müssen, wenn es einen Teilweg findet.
LordParsley

0

Mit java.util.Arraysclass können Sie das Array T[?]in ein List<T>Objekt mit folgenden Methoden transformieren contains:

Arrays.asList(int[] array).contains(int key);

-1

Abhängig davon, wie groß Ihr Array von int sein wird, erzielen Sie eine viel bessere Leistung, wenn Sie Sammlungen verwenden und .containsnicht einzeln über das Array iterieren:

import static org.junit.Assert.assertTrue;
import java.util.HashSet;

import org.junit.Before;
import org.junit.Test;

public class IntLookupTest {

int numberOfInts = 500000;
int toFind = 200000;
int[] array;

HashSet<Integer> intSet;

@Before
public void initializeArrayAndSet() {
    array = new int[numberOfInts];
    intSet = new HashSet<Integer>();
    for(int i = 0; i < numberOfInts; i++) {
        array[i] = i;
        intSet.add(i);
    }
}

@Test
public void lookupUsingCollections() {
    assertTrue(intSet.contains(toFind));
}

@Test
public void iterateArray() {
    assertTrue(contains(array, toFind));

}

public boolean contains(final int[] array, final int key) {
    for (final int i : array) {
        if (i == key) {
            return true;
        }
    }
    return false;
}
}

-1

Lösung Nr. 1

Da die ursprüngliche Frage nur eine vereinfachte (und keine schnellere) Lösung wünscht, ist hier eine einzeilige Lösung:

public boolean contains(int[] array, int key) {
    return Arrays.toString(array).matches(".*[\\[ ]" + key + "[\\],].*");
}

Erläuterung: Javadoc von Arrays.toString()Zuständen, bei denen das Ergebnis in eckigen Klammern steht und benachbarte Elemente durch die Zeichen "," (ein Komma gefolgt von einem Leerzeichen) getrennt sind. Darauf können wir also zählen. Zuerst konvertieren wir arrayin eine Zeichenfolge und prüfen dann, ob keydiese Zeichenfolge enthalten ist. Natürlich können wir keine "Subnummern" akzeptieren (z. B. "1234" enthält "23"), daher müssen wir nach Mustern suchen, denen keyeine öffnende Klammer oder ein Leerzeichen vorangestellt ist, gefolgt von einer schließenden Klammer oder einem Komma.

Hinweis: Das verwendete Regexp-Muster behandelt auch negative Zahlen ordnungsgemäß (deren Zeichenfolgendarstellung mit einem Minuszeichen beginnt).

Lösung Nr. 2

Diese Lösung ist bereits veröffentlicht, enthält jedoch Fehler. Daher poste ich die richtige Lösung:

public boolean contains(int[] array, int key) {
    Arrays.sort(array);
    return Arrays.binarySearch(array, key) >= 0;
}

Auch diese Lösung hat einen Nebeneffekt: Sie modifiziert die array(sortiert sie).


String Handlig ist in der Regel teuer, warum sollte jemand Ints als String behandeln?
Denys Vitali

@DenysVitali Weil op bereits eine funktionierende, effiziente Lösung hat und er nach einer kürzeren Lösung sucht . Und diese sind kürzer. Bei dieser Frage geht es nicht um Leistung.
icza

Ich hätte die Frage dann falsch
Denys Vitali

-5

Versuchen Integer.parseInt()Sie dies zu tun .....

public boolean chkInt(final int[] array){
    int key = false;

    for (Integer i : array){


          try{

                   Integer.parseInt(i);
                   key = true;
                   return key;

             }catch(NumberFormatException ex){

                   key = false;

                   return key;

              }


     }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.