2017-11-02 1 views
2

Also habe ich eine Liste und für jedes Element in der Liste muss ich "etwas tun" basierend auf jedem Listenelement.Java 8 - Verschachtelt wenn innerhalb einer Schleife

Die Liste besteht aus Codes und es gibt insgesamt 5 Codes. Die Liste kann einige oder alle Codes enthalten.

Bisher habe ich die forEach verwendet und ich habe das, wenn die Bedingungen im Inneren wie unten geschrieben -

List<Category> categories = getCategories(); 

categories.stream().forEach(category -> { 
      if(category.equals(Category.A)) { 
       // do something 
      } else if(category.equals(Category.B)) { 
       // do something 
      } else if(category.equals(Category.C)) { 
       // do something 
      } else if(category.equals(Category.D)) { 
       // do something 
      } else if(category.equals(Category.E)) { 
       // do something 
      } 
     }); 

Ich bin bei Refactoring diese suchen. Kann jemand bitte schauen, wie das besser gemacht werden kann?

+4

In eine Methode 'void doSomething()', die jede Kategorie überschreibt und dann einfach 'category.doSomething()' schreibt, kann man '// etwas tun' setzen. – luk2302

+2

Erstellen Sie eine Loopkup-Tabelle. Siehe [diese Frage] (https://stackoverflow.com/questions/4480334/how-to-call-a-method-stored-in-a-hashmap-java) für Informationen. – pritaeas

+2

Welcher Vergleich ist 'category.equals (Category.A)'? – nullpointer

Antwort

1

Zunächst nicht mehrzeiligen lambdas verwenden und neue Methode (mit Schalter) erstellen:

private void doSomethingBasedOnCategory(Category category) { 
    switch(category) { 
     case A: // do something 
       break; 
     case B: // do something 
       break; 
     case C: // do something 
       break; 
     case D: // do something 
       break; 
     case E: // do something 
       break; 
    } 
} 

Dann verwenden Sie es in Ihrem Lambda:

getCategories() 
    .stream() 
    .forEach(category -> doSomethingBasedOnCategory(category); 

Eine andere Möglichkeit ist statisch zu erstellen Karte vorgefüllt mit Schlüsseln (die Category.X sein werden) und Werten (die Funktionen bereit sein werden zu verwenden)

+0

Konnte auch Methodenverweis 'this :: doSomethingBasedOnCategory' verwenden – Lino

+0

Dies macht Sinn. Ich denke ich werde das benutzen. Vielen Dank! – Zuke

+0

@Zuke können Sie auch akzeptieren, um die Frage zu schließen. – ByeBye

1

Das einzige, was ich verbessern würde, ist eine switch-Anweisung zu verwenden:

switch(category){  
    case Category.A: 
     // do Something 
    break; 
} 

Wie mentionend von luk2302 dies nur funktioniert, wenn Kategorie eine Enumeration ist.

+1

Was ist, wenn 'Category' einfach eine reguläre Klasse ist, keine enum !? – luk2302

+0

Dann wird es nicht funktionieren, denke ich. Der Autor hat diese Information nicht wirklich bereitgestellt. Es ist einen Versuch wert. – Basti

+0

Kategorie ist ein Enum, also wird das funktionieren. Ich wollte entweder den verschachtelten if oder switch verwenden, aber der Grund, warum ich das fragte, war zu sehen, ob es irgendeine Möglichkeit gab, Lambda-Funktionen zu verwenden, um dies zu tun. – Zuke

1

Sie können der Category Klasse eine doSomething Klasse hinzufügen und sie einfach in der .forEach aufrufen.

Zum Beispiel:

public class Category { 

    // any other methods/variable/constructors 

    public void doSomething() { 
     //do something 
    } 
} 

Dann können Sie es so nennen:

categories.stream().forEach(Category::doSomething); 

Wenn die // do something kein gemeinsames Verhalten hat, können Sie das, wenn ein Teil im Inneren des doSomething Methode bewegen.

+0

Kategorie ist ein Enum. Ich könnte das Login in der Enum-Klasse schreiben, aber ich möchte die Logik getrennt halten. Dies wäre definitiv meine Implementierung gewesen, wenn es eine Klasse wäre. Vielen Dank! – Zuke

Verwandte Themen