2010-11-26 13 views
9

Ich habe eine Zeichenfolge []. Ich möchte überprüfen, ob dieses Set einen anderen String [] enthält.Containment in einem Satz von Zeichenfolgen in Java überprüfen

Set<String[]> s = new HashSet<String[]>(); 
s.add(new String[] {"lucy", "simon"}); 
System.out.println(s.contains(new String[] {"lucy", "simon"})); 

Falsch wird jedoch gedruckt. Meine Vermutung ist, dass nur die Referenzen verglichen werden und nicht die tatsächlichen Strings. Es scheint, die einzige Option, die ich habe, ist eine Klasse zu erstellen, sagen Phrase, und implementieren hashCode() und equals() (die Arrays.hashCode(...) verwenden).

Gibt es eine andere Möglichkeit zu erreichen, was ich will?

Antwort

13

Ihre Vermutung ist richtig: Arrays ([]) implementieren keine Deep-Equals-Methode: Sie sind gleich, wenn sie dieselbe Instanz sind.

Die einfachste Lösung wäre:

Eine andere Art und Weise String[] durch List<String> ersetzt (aber ich empfehle es nicht) ist Ihr eigenes Set zu implementieren, die nicht auf Object.equals ist, sondern auf java.util.Arrays.equals(Object[]a, Object[]b)

+1

+1 für die tiefe gleich Erklärung – Barthelemy

11

Konvertieren, dass String[] zu List<String> und es sollte ziemlich gut funktionieren.

1

Verwenden Set<Set<String>> oder Set<List<String>> statt Set<String[]>

Code:

List<String> s1=Arrays.asList("1","2"),s2=Arrays.asList("1","2"); 
System.out.println(s1.equals(s2) + " "+s1.hashCode()+ " "+s2.hashCode()); 

Ausgang:

true 2530 2530 
1

Klingt wie Sie bereits Ihre Frage beantwortet. Eine Option ist wie bereits erwähnt. Die andere wären Set verwenden>, da die API für equals (Object) sagt:

Vergleicht das angegebene Objekt mit dieser Sammlung auf Gleichheit.

0

Ich hatte gerade eine Schleife durch und Call Arrays.equals:

etwas wie folgt aus:

boolean contains(Set<String[]> s, String[] item) { 
    for(String[] toCompare: s) { 
    if(Arrays.equals(toCompare, item)) { 
     return true; 
    } 
    } 
    return false; 
} 

nicht sicher, ob es das schnellste ist, aber es sollte den Job gut

3

Können sich die Elemente von String [] in verschiedenen Reihenfolgen befinden und trotzdem das gesamte Array als einem anderen Array gleichwertig betrachten, das dieselben Elemente in einer anderen Reihenfolge enthält? Wenn ja, wären Sie in der Tat besser dran, eine Container-Klasse zu implementieren und Equals und Hashcode zu überschreiben.

wenn nicht, und wenn die inneren Elemente wie Listen anstelle von Arrays speichert eine akzeptable Alternative ist, dann können Sie dies tun:

package com.stackoverflow; 


import java.util.Arrays; 
import java.util.HashSet; 
import java.util.List; 
import java.util.Set; 


public class StringContainment { 

    public static void main(final String[] args) { 
    final Set<String[]> s = new HashSet<String[]>(); 
    final Set<List<String>> s2 = new HashSet<List<String>>(); 

    s.add(new String[] {"lucy", "simon"}); 
    s2.add(Arrays.asList(new String[] { "lucy", "simon" })); 

    System.out.println(s.contains(new String[] {"lucy", "simon"})); // false 
    System.out.println(s2.contains(Arrays.asList(new String[] {"lucy", "simon"}))); // true 
    } 

} 

Die erste Prüfung falsch zurück, das zweite wahr. Dies könnte einfacher sein, wenn Sie Listen verwenden können.

Wenn Sie nicht können, können Sie dies immer noch verwenden, solange Sie diesen Vergleich nicht zu oft machen müssen (es ist definitiv keine gute Idee, leistungsmäßig).

0

Mit Java8 Stream Einführung können Sie es auf folgende Weise tun:

Boolean res = s.stream() 
    .anyMatch(elm -> elm.equals("lucy") || elm.equals("simon")); 
Verwandte Themen