Verwenden Sie in Java eine Zeichenfolge im Groß- und Kleinschreibung

Lesezeit: 6 Minuten

Benutzer-Avatar
randeepsp

Folgendes muss ich ändern ifist zu a switchcase beim Suchen nach a Stringum die zyklomatische Komplexität zu verbessern.

String value = some methodx;
if ("apple".equals(value)) {
    method1;
}

if ("carrot".equals(value)) {
    method2;
}

if ("mango".equals(value)) {
    method3;
}

if ("orange".equals(value)) {
    method4;
}

Aber ich bin mir nicht sicher, welchen Wert ich bekommen werde.

  • ‘if’ ist keine Schleife, sondern eine Anweisung zum Testen einer Bedingung

    – Habib

    20. April 2012 um 5:04 Uhr

  • if-Schleife? wirklich? Um die Switch-Anweisung zu verwenden, müssen Sie jdk7 installieren. stackoverflow.com/questions/338206/…

    – KV Prajapati

    20. April 2012 um 5:04 Uhr


  • PS.. Der Wechsel zu einer switch-Anweisung wird nichts für Ihre Komplexität tun.. Es ist immer noch die gleiche Anzahl von Pfaden. Nur anders umgesetzt.

    – bash05

    20. April 2012 um 5:25 Uhr

  • da kam effizienz in frage, afk sonst wenn wäre stattdessen ab dem zweiten “if” besser

    – ılǝ

    16. Mai 2013 um 1:29 Uhr


  • besser zu gebrauchen sonst wenn Leiter als mehrfach wenn ….

    – SweetWisher ツ

    21. Mai 2014 um 5:38 Uhr


Benutzer-Avatar
Nickdos

Java (vor Version 7) unterstützt Strings in switch/case nicht. Aber Sie können das gewünschte Ergebnis erzielen, indem Sie eine Aufzählung verwenden.

private enum Fruit {
    apple, carrot, mango, orange;
}

String value; // assume input
Fruit fruit = Fruit.valueOf(value); // surround with try/catch

switch(fruit) {
    case apple:
        method1;
        break;
    case carrot:
        method2;
        break;
    // etc...
}

  • Ich habe dafür gestimmt, aber … es wäre langsamer als Ihre if “Schleife”. Es ist AFK der beste Ansatz.

    – bash05

    20. April 2012 um 5:14 Uhr

  • Ich habe ein Problem, mein “Wert” ist keine Konstante und diese Lösung bereitet mir Probleme. Gibt es eine Lösung???

    – guelo

    18. Juni 2014 um 7:51 Uhr

  • „Wert“ ist in diesem Beispiel keine Konstante – er variiert je nach Benutzereingabe. Er sollte einer bekannten Liste möglicher Werte entsprechen (definiert durch die Aufzählung), muss es aber nicht, da jeder “unbekannte” Wert von der try/catch-Anweisung abgefangen und dort verarbeitet werden kann.

    – Nickdos

    18. Juni 2014 um 23:59 Uhr

  • Ein Schalter reduziert die zyklomatische Komplexität nicht (zumindest so, wie PMD sie berechnet). Sie müssen eine Aufzählung verwenden und Klassenreferenzen im “Befehlsstil” in eine Zuordnung oder die Methode in die Aufzählung selbst einfügen. Ich habe mich gestern mit einem ähnlichen Fall befasst.

    – Καrτhικ

    5. September 2014 um 16:34 Uhr

Benutzer-Avatar
chao

Lernen Sie zu verwenden else.

Seit value niemals gleich zwei ungleichen Zeichenfolgen auf einmal sein wird, gibt es nur 5 mögliche Ergebnisse — eines für jeden Wert, der Ihnen wichtig ist, plus eines für “keine der oben genannten”. Da Ihr Code jedoch die nicht bestandenen Tests nicht eliminiert, hat er 16 “mögliche” Pfade (2 ^ die Anzahl der Tests), von denen die meisten niemals befolgt werden.

Mit elsedie einzigen Pfade, die existieren, sind die 5, die tatsächlich passieren können.

String value = some methodx;
if ("apple".equals(value )) {
    method1;
}
else if ("carrot".equals(value )) {
    method2;
}
else if ("mango".equals(value )) {
    method3;
}
else if ("orance".equals(value )) {
    method4;
}

Oder beginnen Sie mit der Verwendung von JDK 7, das die Möglichkeit bietet, Zeichenfolgen in a zu verwenden switch Aussage. Natürlich wird Java nur kompilieren switch In ein if/else sowieso wie konstruieren…

  • Es führt tatsächlich einen Wechsel am Hashcode durch und führt dann if/else aus, um Hashcode-Kollisionen zu lösen.

    – Paul Jackson

    27. November 2013 um 14:35 Uhr

  • ansonsten ist langsam 🙁

    – Maveňツ

    11. August 2014 um 11:55 Uhr

  • @Mann: if ohne else ist im Durchschnitt noch langsamer. (Es würde jedes Mal jeden Vergleich versuchen. Die else ermöglicht es Ihnen, früher fertig zu werden, sobald Sie eine Übereinstimmung gefunden haben.) Der sauberste Weg wäre in der Tat, a zu verwenden switch, was Optimierungen wie die im Kommentar vor Ihrem erwähnte ermöglicht. Aber das ist keine Option in Java-Versionen vor 1.7.

    – chao

    11. August 2014 um 13:43 Uhr


  • Hier empfiehlt sich der Einsatz eines Schalters… docs.oracle.com/javase/7/docs/technotes/guides/language/…

    – Benutzer1156544

    27. November 2015 um 11:49 Uhr

Benutzer-Avatar
Suragch

Jeder benutzt mindestens Java7 jetzt rechts? Hier ist die Antwort auf das ursprüngliche Problem:

String myString = getFruitString();

switch (myString) {

    case "apple":
        method1();
        break;

    case "carrot":
        method2();
        break;

    case "mango":
        method3();
        break;

    case "orange":
        method4();
        break;
}

Anmerkungen

  • Die case-Anweisungen sind äquivalent zu using String.equals.
  • Wie üblich wird beim String-Matching zwischen Groß- und Kleinschreibung unterschieden.
  • Laut dem Dokumenteist dies im Allgemeinen schneller als die Verwendung von chained ifelse Aussagen (wie in cHaos Antwort).

Verwenden Sie eine Karte, um die zyklomatische Komplexität zu reduzieren:

Map<String,Callable<Object>> map = new HashMap < > ( ) ;
map . put ( "apple" , new Callable<Object> () { public Object call ( method1 ( ) ; return null ; } ) ;
...
map . get ( x ) . call ( ) ;

oder Polymorphismus

Nur um die Antwort von Emory konkret zu machen, der ausführbare Code ist der folgende:

  Map<String,Callable<USer>> map = new HashMap<String,Callable<User>>();
  map.put( "test" , new Callable<User> () { public User call (){ return fillUser("test" ); }} ) ;
  map.put( "admin" , new Callable<Utente> () { public Utente call (){  return fillUser("admin" ); }} ) ;

wobei der Benutzer ein POJO ist, und dann

  User user = map.get(USERNAME).call();

Endlich, das genannt Methode steht irgendwo:

 private User fillUser(String x){        
        User user = new User();
        // set something in User
        return user;
}

Benutzer-Avatar
Gemeinschaft

Java unterstützt keine Groß-/Kleinschreibung mit String. Ich denke dieser Link kann dir helfen. 🙂

Benutzer-Avatar
Benutzer unbekannt

Hier ist ein möglicher Weg vor 1.7, den ich nicht empfehlen kann:

public class PoorSwitch
{
    final static public int poorHash (String s) {
        long l = 0L;
        for (char c: s.toCharArray ()) {
            l = 97*l + c;
        }
        return (int) l;
    }

    public static void main (String args[])
    {
        String param = "foo";
        if (args.length == 1)
        {
            param = args[0];
        }
        // uncomment these lines, to evaluate your hash
        // test ("foo");
        // test ("bar");
        switch (poorHash (param)) {
            // this doesn't work, since you need a literal constant
            // so we have to evaluate our hash beforehand:
            // case poorHash ("foo"): {
            case 970596: {
                System.out.println ("Foo!");
                break;
            }
            // case poorHash ("bar"): {
            case 931605: {
                System.out.println ("Bar!");
                break;
            }
            default: {
                System.out.println ("unknown\t" + param);
                break;
            }
        }
    }

    public static void test (String s)
    {
        System.out.println ("Hash:\t " + s + " =\t" + poorHash (s));
    }
}

Vielleicht könnte man mit einem solchen Trick in einem generierten Code arbeiten. Sonst kann ich es nicht empfehlen. Nicht so sehr, dass mir die Möglichkeit einer Hash-Kollision Sorgen bereitet, aber wenn etwas verwechselt wird (Ausschneiden und Einfügen), ist es schwierig, den Fehler zu finden. 931605 ist keine gute Dokumentation.

Nehmen Sie es einfach als Proof of Concept, als Neugier.

  • Dies ähnelt dem, was eine HashMap intern macht. Aber eine HashMap hat Code, um mit der (entfernten) Möglichkeit einer Kollision umzugehen. Eine HashMap verbirgt die Komplexität und reduziert die zyklomatische Komplexität.

    – Erinnerung

    20. April 2012 um 16:18 Uhr

  • Eine HashMap hat, aber der Hashcode nicht. Sie könnten Recht haben, wenn Sie vorschlagen, den bewährten, getesteten Java “foo”.hashCode () zu verwenden, aber gibt es eine Garantie, dass er sich nie ändern wird? Ist der Wert/der Algorithmus wie bei einer öffentlichen API garantiert? Wenn Sie Ihren eigenen HashCode bereitstellen, haben Sie zumindest die Kontrolle darüber.

    – Benutzer unbekannt

    20. April 2012 um 16:48 Uhr

  • Dort ist eine Garantie dafür "foo".hashCode() gibt immer den gleichen Wert zurück. Einfach weil Java7+ Code verwendet wird switch over string wird zu Code kompiliert, der genau diese unveränderliche Eigenschaft annimmt. Es kann sich also in zukünftigen Versionen nicht ändern und es ist noch einfacher zu erkennen, dass sich der Algorithmus auch nicht von Java 1.0 auf Java 7 geändert hat. Aber Ihr Code sollte verwenden equals innerhalb der case Anweisungen zum Schutz vor Hash-Kollisionen.

    – Holger

    26. Juli 2018 um 18:01 Uhr


1070460cookie-checkVerwenden Sie in Java eine Zeichenfolge im Groß- und Kleinschreibung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy