Wie filterst du geschachtelte Schleifen mit Java 8 streams und Filter?

Wie filterst du geschachtelte Schleifen mit java8-streams und Filter?

Angenommen ich habe eine Liste mit Autos (List<Car>), jedes Auto mit einer Liste der Motoren (List<Engine>), jeden Motor mit einem List<Parts>.
In regulären Java-dieser Struktur kann beschrieben werden als:

for(Car car : cars) {
    for (Engine engine : car.getEngines()) {
        for (Part part : engine.getParts()) {
            //...
        }
    }
}

Nehme an, dass ich Sie initialisieren die Liste der Autos:

List<Car> cars =  new ArrayList<Car>(Arrays.asList(new Car(), new Car(), new Car()));
cars.get(0).setEngines(null);
cars.get(1).setEngines(new ArrayList<Engine>());
cars.get(2).setEngines(new ArrayList<Engine>() {{
    add(new Engine());
    add(null);
    add(new Engine());  
}});

Wenn ich will, um null-Werte herausfiltern von List<Engine> würde, dann würde ich das tun

cars.stream().filter(p -> p.getEngines() != null).forEach(System.out::println);

Wenn ich will, um filter leer aus arraylists der Liste, dann würde ich das tun

cars.stream().filter(p -> !p.getEngines().isEmpty()).forEach(System.out::println);

Aber wie Entferne ich die null - Engine im 3. Auto und noch zwei andere Motoren, befestigt, um die ursprüngliche Verzeichnis-Struktur? In anderen Worten, können wir gehen in die 2., 3., N-TEN Stufe der Hierarchie mit Java-8-Filter oder tun die Filter funktionieren nur auf der obersten Ebene? Ich habe auch versucht zu verwenden .anyMatch() ohne viel Glück.

nur weiter zu verdeutlichen, betrachten wir das folgende Beispiel:
Ich habe 3 Autos in meiner garage. Jedes Auto hat 3 Platzhalter für den Motor. Jeder Motor hat 3 Platzhalter für die Teile, aus denen sich der Motor:

Car #1: 
 Engine#1: part1, part2, part3
 Engine#2: null, part2, empty
 Engine#3: part1, null, part3
Car #2: 
 Engine#1: part1, part2, part3
 empty:    null, null, null
 null:     null, null, null
Car #3: 
 Engine#1: null, empty, part3
 Engine#2: null, part2, empty
 Engine#3: part1, null, part3

Frage: wie verwenden wir Java 8 .filter, so dass, wenn nach dem filtern bekomme ich die folgende:

Car #1: 
 Engine#1: part1, part2, part3
 Engine#2: part2, 
 Engine#3: part1, part3
Car #2: 
 Engine#1: part1, part2, part3
Car #1: 
 Engine#1: part3
 Engine#2: part2,
 Engine#3: part1,part3

=======================

Ein weiteres Beispiel

Jungs, ich hoffe, daß dieses Beispiel, das ich gerade gemacht, bis klarer ist:.. im Wesentlichen ist es die gleiche wie oben, nur es ist Ausführlicher und statt Autos, die wir denken können, die Banken zu minimieren Abstraktion. Für die übersichtlichkeit habe ich alle Felder der öffentlichkeit, ich hoffe, Sie nicht mind.

Angenommen, ich bin verbunden mit 4 Banken in meiner 'bank Geldbeutel"

Bank#1:

Ich körperlich bank hier. Ich bin gezwungen zu haben 3 Konten, aber nur 2 gefüllt mit etwas Geld und 3. ist noch offen (dh null)

Bank #2:

Ich Plane, die bank hier. Account-support-Struktur wird erstellt (leere ArrayList), aber keine Konten Hinzugefügt werden

Bank #3:

Ich füllte einige marketing-form. Sie haben mich in Ihrem CRM, aber keine Konten jemals geöffnet werden

Bank #4:

Diese bank abgebrannt, es ist ein Artefakt Platzhalter in der Brieftasche, die null ist.

Folgende code beschreibt diese:

public class Bank_Wallet {

    public static void main(String[] args) {
        List<Bank> banks = new ArrayList<Bank>(Arrays.asList(new Bank(), new Bank(), new Bank(), null));
        //1st bank with physical accounts, but one of them is null
        banks.get(0).accounts = Arrays.asList(new Account(), null, new Account());
        //2nd bank with empty accounts  
        banks.get(1).accounts = new ArrayList<Account>();

        System.out.println("RAW original");
        banks.stream().forEach(System.out::println);

        System.out.println("\nFiltered result...   ");
        banks.stream()//get stream
                .filter(p -> p != null) //get rid of null banks
                .filter(p -> p.accounts != null) //get rid of null accounts
                .filter(p -> !p.accounts.isEmpty()) //get rid of empty accounts
                //.filter(p->p.accounts. ?????? ??) ?? how do I remove null account from the remaining bank entry?
                .forEach(System.out::println);

    }//main
}


Die Rennklassen sind hier:

public class Bank {
    public String name;
    public static int counter = 0;
    public List<Account> accounts;

    public Bank() {
        this.name = "Bank: #" + Bank.counter++;
    }

    @Override
    public String toString() {
        return "Bank [name=" + this.name + ", accounts=" + this.accounts + "]";
    }

public class Account {
    public String name;
    public static int counter;

    public Account() {
        this.name = "Account: " + Account.counter++;
    }

    @Override
    public String toString() {
        return "Account [name=" + this.name + "]";
    }

}

wenn Sie diesen code ausführen, werden Sie sehen, dass nach der vorgeschlagenen filtern alle, ich bin mit der linken, ist

Bank [name=Bank: #0, accounts=[Account [name=Account: 0], null, Account [name=Account: 1]]]

Frage:
Was die anderen filter muss ich tun, fügen Sie den code ein, um das obige Ergebnis nicht zeigen null-im-Konten und haben doch die Allgemeine Struktur (Bank->Konto>usw.>etc)

Bank [name=Bank: #0, accounts=[Account [name=Account: 0], Account [name=Account: 1]]]
  • führen Sie anzeigen über jeden Eintrag der äußeren Liste. Die Karte sollte die Funktion filtern Sie heraus, was Sie nicht wollen.
  • Könnten Sie etwas konkreter in dem, was Sie zu erreichen versuchen, mit Ihren Schleifen ? Ich denke, Andreas hob ein guter Punkt, zeigt mir, dass ich zu viele Annahmen über das, was du suchst, denn deine Frage ist nicht spezifisch genug. Geben Sie uns nur ein Beispiel für die Eingabe zusammen mit der gewünschten Ausgabe
  • So, das Sie drucken möchten, das ganze Auto unter Ausschluss jeglicher null/leer-Komponenten?
  • Ist, dass etwas angezeigt werden oder so etwas erhoben werden ?
  • ja das ganze Auto Struktur (Liste) mit null-Werte/Leergut herausgefiltert in verschiedene Tiefe Ebenen, die mit java 8 filter
  • Wenn Sie sich auf Car.toString() gibt es nichts, was Sie tun können, mit Bächen oder sogar Schleifen heraus zu filtern, sub-Komponenten. Sie haben entweder implementieren toString() anders, oder drucken Sie Komponenten iterativ.
  • es kann gesammelt werden, wie auch angezeigt. Gesammelt wird viel bevorzugt.
  • ja, dass ist das, was ich derzeit habe: ich habe 3 for-Schleifen und bekommen es heraus gefiltert, die Art und Weise, aber obwohl java 8 filter vielleicht schon eine bessere Lösung
  • das sammeln dieser würde entweder mutieren die Autos oder neue zu erstellen, welche wird erwartet ?
  • Wussten Sie, dass, nutzen Sie einfach das Ergebnis der Arrays.asList überall dort, wo ein List ist erforderlich, D. H., dass Sie nicht überladen Sie Ihren code mit gazillion verschiedene versuche anlegen und füllen ArrayLists?
  • Die "Klarstellung" ist eher verwirrend. Was bedeutet es, wenn ein "Teil" ist mit der Bezeichnung "leer" und wie "leer" oder sogar null Listen enthält drei null Elemente?
  • Jungs, gebt mir ein paar Stunden - ich komme wieder mit einem Beispiel mit Ausführlicher Erklärung des Problems. Sorry für die Verwirrung...
  • Hast du auch dieses problem lösen?

InformationsquelleAutor JavaFan | 2016-06-27
Schreibe einen Kommentar