# mehrere Strings vergleichen



## bubka (10. Jan 2011)

hi,
wie kann man in Java mehrere Strings miteinander vergleichen? 
z.b. funktioniert sehr gut : String1.equals(String2);
ich kann ja auch sowas schreiben:  (String1.equals(String2) && String1.equals(String3))
geht es irgendwie so? String1.equals(String2).equals(string2); //**
?
P.S.-könnten Ihr mir auch vielleicht über die Geschichte über den ganzen Pünktchen erzählen? Das kapiere ich nicht ganz. Und warum funktioniert die //** Zeile nicht?


----------



## The_S (10. Jan 2011)

Nee, gibts nciht, aber du kannst ne kleine Methode verwenden


```
private boolean multiEquals(String ... str) {
    for (int i = 1; i < str.length; i++) {
      if (!str[i-1].equals(str[i])) {
        return false;
      }
    }
    return true;
  }
```


```
boolean equal = multiEquals(string1, string2, string3);
```

Was für eine Frage hast du den zu den "Pünktchen"? Prinzipiell sind das Methodenaufrufe die einer Klasse oder einem Objekt zugeordnet sind.

Was soll denn //** deiner Meinung nach bewirken?


----------



## bygones (10. Jan 2011)

die Frage ist doch bei multiEquals(string1, string2, string3) welche Strings du nun vergleichen willst ?

string1 -> string2 && string1 -> string3
string1 -> string2 && string2 -> string3

wie auch immer ein method chaining bei equals geht nicht, da der Rückgabewert boolean ist.


----------



## nrg (10. Jan 2011)

bygones hat gesagt.:


> string1 -> string2 && string1 -> string3
> string1 -> string2 && string2 -> string3



ist das nicht äquivalent?


----------



## bygones (10. Jan 2011)

jo könnte sein


----------



## The_S (10. Jan 2011)

Es sei denn einer ist null und es könnte somit eine Exception ausgelöst werden.


----------



## Landei (10. Jan 2011)

Der Universal-Massenvergleicher:


```
import java.util.*;

public static boolean allEqual(Object ... ts) {
  return ts.length == 0 || new HashSet<Object>(Arrays.asList(ts)).size() == 1;
}
```

OT: Wird Zeit, dass mal die Methode Arrays.asSet(T ... ts) eingeführt wird...


----------



## bubka (10. Jan 2011)

Landei hat gesagt.:


> Der Universal-Massenvergleicher:
> 
> 
> ```
> ...


Das sagt mir leider noch nicht. bin mit java nicht so weit


----------



## timbeau (10. Jan 2011)

HashSet enthält keine Duplikate. Wenn also alles gleich ist, verwirft HashSet alle außer dem ersten. Somit ist bei Gleichheit aller Objekte die Länge des HashSets 1 und dann wird true zurückgegeben.


----------



## Landei (10. Jan 2011)

bubka hat gesagt.:


> Das sagt mir leider noch nicht. bin mit java nicht so weit



Man darf auch Konstrukte verwenden, die man nicht versteht. Mache ich jeden Tag. Irgendwann kommt dann das Aha-Erlebnis.


----------



## Andi_CH (11. Jan 2011)

Landei hat gesagt.:


> Der Universal-Massenvergleicher:
> 
> 
> ```
> ...



Danke, das geniale Konstrukt habe ich noch nie gesehen.

Zum OT: Warum Arrays.asSet? Wieso nicht ein Set-Konstruktor Set(T ... ts)


----------



## The_S (11. Jan 2011)

Andi_CH hat gesagt.:


> Danke, das geniale Konstrukt habe ich noch nie gesehen.



Würd ich aus Performancegründen auch nicht unbedingt verwenden  .


----------



## nrg (11. Jan 2011)

The_S hat gesagt.:


> Würd ich aus Performancegründen auch nicht unbedingt verwenden  .



muss ich dir recht geben. ist zwar eine sehr schicke lösung von landei aber da sollte doch deine wesentlich performanter sein.


----------



## Andi_CH (11. Jan 2011)

The_S hat gesagt.:


> Würd ich aus Performancegründen auch nicht unbedingt verwenden  .



Java und Performance? Die ist relativ ;-) (Wenn ich daran denke was die VM so an Performance verbraucht) Wenn ich performant sein muss setzte ich dann doch noch lieber auf C/C++

Ausserdem ist die von The_S doch schon sehr performant und auch recht elegant

Aber ich will keinen Religionskrieg auslösen ;-)

Ausserdem hat "genial" immer zwei Seiten - genial einfach einzusetzen muss nicht automatisch performant sein. Die Software an der ich aktuell arbeite ist rein interaktiv - Die CPU macht eigentlich nichts anderes als auf Benutzeraktionen zu warten - also könnte ich so etwas locker einsetzen.


----------



## bygones (11. Jan 2011)

Landei hat gesagt.:


> Man darf auch Konstrukte verwenden, die man nicht versteht. Mache ich jeden Tag. Irgendwann kommt dann das Aha-Erlebnis.


kenn ich so bei meiner Frau


----------



## Landei (11. Jan 2011)

Ja, beim Vergleich von wenigen Objekten wird der Aufwand der Set-Konstruktion alles andere dominieren. Bei mehr Objekten fällt das aber kaum noch ins Gewicht. Ich habe das Gefühl, das man oft unterschätzt, wie leistungsfähig Sets sind (habe ich erst neulich bei einer Projekt-Euler-Aufgabe gemerkt, wo ich noch Duplikate aus meiner Lösung entfernen musste)


----------



## The_S (11. Jan 2011)

Gerade bei vielen Objekten sollte es doch zu Performanceproblemen kommen!? Klär mich bitte auf. Danke!


----------



## bygones (11. Jan 2011)

The_S hat gesagt.:


> Gerade bei vielen Objekten sollte es doch zu Performanceproblemen kommen!? Klär mich bitte auf. Danke!


was für PerPro ? HashSet ist nix anderes als ne Hashmap... d.h. der Konstruktor macht dann n puts in eine Map. Und das ist nicht wirklich kritisch


----------



## The_S (11. Jan 2011)

bygones hat gesagt.:


> was für PerPro ? HashSet ist nix anderes als ne Hashmap... d.h. der Konstruktor macht dann n puts in eine Map. Und das ist nicht wirklich kritisch



OK, wenn wirklich alle Elemente gleich sind, dann ist es nicht sehr viel langsamer (mal von dem ganzen Overhead mit Konvertierung von Array in Liste und den ganzen zusätzlichen Aufrufen beim adden/puten, die über ein einfaches equals hinausgehen, abgesehen). Aber wenn du bspw. 10.000 Elemente hast und da bereits das 2te ungleich dem 1ten ist, wird der Mechanismus für die verbleibenden 9.998 Elemente trotzdem ausgeführt, obwohl das gar nicht notwendig wäre.


----------



## bygones (11. Jan 2011)

worst case szenarien sind so und so immer kritisch zu betrachten bei PerPro diskussionen... 

Die Frage ist wie sehr schlagen diese "unnötigen" Vergleiche auf die Performance - und um das geht es ja. Performance wird immer mit Speicher/Zeitbedarf gleichgesetzt nicht mit redundanten Operationen.


----------



## The_S (11. Jan 2011)

Wobei man sich dann fragen sollte, warum nimmt man nicht gleich die andere Variante, die

1.) (imho) leichter verständlich (vor allem für Anfänger) und
2.) in jedem Fall performanter ist, sowie
3.) auch mit Worst-Case Szenarien keine Probleme hat.


----------



## timbeau (11. Jan 2011)

[DUKE]Mein CODE ist kürzer als deiner![/DUKE]

Umgedrehter S****-Vergleich 

Aber ich finde solche Codeschnipsel interessant, performant hin oder her.


----------



## Landei (11. Jan 2011)

Haskell (geht sicher noch besser):

```
allEq xs = and $ zipWith (==) xs $ tail xs
```

Und gar nicht mal so unperformant...


----------



## The_S (12. Jan 2011)

Landei hat gesagt.:


> Haskell (geht sicher noch besser):
> 
> ```
> allEq xs = and $ zipWith (==) xs $ tail xs
> ...



Was auch immer das ist  . Schaut ja fast wie Perl aus


----------



## Landei (12. Jan 2011)

Zugegeben, das sieht erst mal komisch aus. In Java-Syntax hätte man (mit Closures und wenn es die Funkitionen alle gäbe):


```
public static <T> boolean allEq(List<T> xs) {
  return and(zipWith(#(a:T, b:T) -> a.equals(b), xs, tail(xs)));
}
```

Eigentlich recht einfach zu verstehen: 
xs ist die Liste (sagen wir [A,B,C,D]), tail xs die Liste ohne das erste Element (also [B,C,D]). zipWith verbindet zwei Listen paarweise mit einer gegebenen Funkion, hier == (also in unserem Beispiel [A==B, B==C, C==D], überzählige Elemente werden ignoriert). Die Funktion and testet, ob alle Elemente einer booleschen Liste True sind.

Natürlich gibt es Sprachen, wo das ganze noch kürzer wird, wie J oder Golfscript.


----------

