2016-10-10 5 views
2

Ich bin neu in Java 8 und habe eine Bedingung, wo einige Prüfungen vorgenommen werden müssen, um ein Objekt zu erstellen. Ich benutze natürlich Streams dafür und habe eine harte Zeit damit verbracht, dies zu erledigen.Umgang mit verschachtelten if/else-Anweisungen mit Java 8 Streams

Eingabe ist ein HashMap-Objekt mit Schlüssel/Wert-Paaren und Ausgabe sollte darunter sein.

| userrole | userid | username | output | 
|------------|--------|----------|----------| 
| "" (blank) | 111 | amathews | 111  | 
| ""   |  | amathews | amathews | 
| Admin  | 111 | amathews | 111  | 
| Admin  | 111 | ""  | 111  | 
| Admin  |  | amathews | Admin | 

Dies ist, wie die prezidence Benutzer-ID> UserRole> Benutzername ist.

Jedes HashMap-Objekt enthält UserRole/Benutzername/BenutzerID als Schlüssel und seine Werte zusammen mit anderen Schlüssel/Wert-Paaren. Wir werden eine Menge verschachtelter if/else-Anweisungen haben, um diese Aufgabe vor einer Java-Version auszuführen.

Wir werden eine Menge verschachtelter if/else-Anweisungen haben, um diese Aufgabe in einer früheren Java-Version auszuführen.

Hier ist der Code, den ich bis jetzt habe.

map.entrySet().stream() 
     .filter(e -> e.getValue() instanceof String || e.getValue() instanceof Integer) 
     .filter(e -> e.getKey().contains("userrole") || e.getKey().contains("userid") || e.getKey().contains("username")) 
     .map(e -> e.getValue()) 
     .collect(Collectors.toList()); 

Ich weiß, dass die Art, wie ich Kartenfunktion im Stream geschrieben habe, auch nicht korrekt ist. Wie erreichen Sie dies in Java 8? Ich weiß nicht, wie ich den verschachtelten if/else Teil hier hinzufügen soll.

Bitte helfen Sie mir hier Ich bin fest und kann nicht weitermachen. Vielen Dank.

Edit: Sorry Wenn ich das Problem nicht genau angegeben hätte. Hier ist der Code snippiet.

public List<UserAction> getUserActionList(Map<String, String> map) 
    { 
     String userRole = map.get("userrole"); 
     String userName = map.get("username"); 
     String userId = map.get("userid"); 

     String output = null; 
     // if userrole, userid and username are not null/empty, then output is userid 
     if(!checkForNullEmpty(userRole) && !checkForNullEmpty(userId) && !checkForNullEmpty(userName)) 
      output = userId; 
     // if userrole and userid are null/empty and username is not empty/null, then output is username 
     else if(checkForNullEmpty(userRole) && checkForNullEmpty(userId) && !checkForNullEmpty(userName)) 
      output = userName; 
     // if userid and username are null/empty and userrole is not empty/null, then output is userrole 
     else if(!checkForNullEmpty(userRole) && checkForNullEmpty(userId) && checkForNullEmpty(userName)) 
      output = userRole; 

     List<UserAction> udList = new ArrayList<>(); 
     // Add the map and output into a UserAction object 
     udList.add(new UserAction(map, output)); 

     return udList; 

    } 

Ich hatte nur 3 Bedingungen hier nach der Tabelle behandelt. Also muss dies neu strukturiert werden um Java 8 Streams zu verwenden. Hoffe es macht jetzt Sinn.

+1

Was ist dein tatsächliches Problem? Funktioniert der von Ihnen gepostete Code nicht? Wenn nicht, warum nicht? Wenn es funktioniert, was genau fragst du? Vielleicht poste ausführbaren Code, der Beispieldaten hat und was der gewünschte Datentyp sein sollte – Bohemian

+0

Danke für Ihre Antwort. Ich habe das Snippet hinzugefügt hoffe es ist jetzt klar. – 15R6

+2

Ist garantiert, dass mindestens einer der Werte in der Karte gefunden wird? – Bohemian

Antwort

3

Wenn mindestens einer der Werte garantiert ist, können Sie es wie folgt Refactoring könnten:

public List<UserAction> getUserActionList(Map<String, String> map) { 
    return Stream.of("userid", "username", "userrole") 
     .map(map::get) 
     .filter(s -> !checkForNullEmpty(s)) 
     .limit(1) 
     .map(output -> new UserAction(map, output)) 
     .collect(Collectors.toList()); 
} 

Wenn es nicht ist gewährleistet, dass mindestens ein Wert ungleich Null sein wird, ist es ein wenig hässliche aber nicht so schlecht:

+0

Vielen Dank für diese @ Bohemian. Ich versuche nur zu verstehen, wie das funktioniert. Zuerst versuchen wir, einen Strom von benötigten Schlüsseln zu erzeugen, dann werden wir die Werte dafür vom Kartenobjekt erhalten, die leeren/leeren filtern, dann eins begrenzen, um einen Wert zu erhalten, ein UserAction-Objekt erzeugen und sammle endlich alle Objekte in eine Liste .. was ich nicht verstanden habe ist wie es priorisiert wird Benutzer-ID> Benutzer-Rolle> Benutzername ?? Bedeutung wie in der Tabelle Ich habe mit den Bedingungen, wie in meinem Code-Snippet dargestellt. Also wird das verschachtelt, wenn/sonst richtig ... – 15R6

+1

@ 15R6 du hast es im Grunde genommen, aber bemerke '.limit (1)'. Dies bedeutet, dass der Stream nach dem ersten gesammelten Element stoppt. Alle Elemente im Stream nach dem ersten Treffer werden nicht einmal durchgezogen. Zum Beispiel, wenn 'map.get" userid ")' einen Wert zurückgibt, wird 'map.get() 'nicht erneut aufgerufen. Ströme feuern den ganzen Weg durch ein Element nach dem anderen. Sie gehen nicht mit allen Elementen durch, bevor Sie mit dem nächsten Schritt fortfahren. Hoffe, das hat geholfen. – Bohemian

1

Es ist nicht wirklich klar über die Aufgabe, die Sie erreichen müssen, aber in der Regel alles, was Sie in Ihren if Erklärungen zu schreiben, müssen Sie mit filter() Methode von Stream API tun können. Dann haben Sie in map() Methode die genaue Logik, die mit den Daten getan werden muss (z. B. das Umwandeln in einen anderen Typ oder das Abrufen von Werten, die benötigt werden). collect() Methode wird verwendet, um ein Ergebnis aus der Stream, z. Liste, Satz, Karte, einzelnes Objekt oder irgendetwas anderes. Zum Beispiel:

map.entrySet().stream() 
       .filter(e -> { 
        // filter the data here, so if isStrOrInt or containsUserData is false - we will not have it in map() method 
        boolean isStrOrInt = e.getValue() instanceof String || e.getValue() instanceof Integer; 
        boolean containsUserData = e.getKey().contains("userrole") || e.getKey().contains("userid") || e.getKey().contains("username"); 
        return isStrOrInt && containsUserData; 
       }) 
       .map(e -> { 
        if (e.getKey().contains("userrole")) { 
         // do something 
        } 
        // some more logic here 
        return e.getValue(); 
       }) 
       .collect(Collectors.toList()); 
       // or e.g. .reduce((value1, value2) -> value1 + value2); 

Wenn Sie ein einzelnes Objekt am Ende erstellen müssen, würden Sie wahrscheinlich brauchen reduce() Methode. Ich empfehle Ihnen, reduction operations, allgemeine Informationen über Stream API zu überprüfen, um zu verstehen, wie sie funktionieren.

+0

Danke für Ihre Antwort @yuriy. Ja, ich habe verstanden, was du geantwortet hast. Ich werde es auch so versuchen. Haben Sie noch einen weiteren Vorschlag, nachdem Sie die bearbeitete Frage mit dem Code-Snippet gelesen haben? – 15R6

Verwandte Themen