Liste filtern nach Prädikaten verschiedener Typen

looparda

Top Contributor
Ich möchte gern Listen mit Hilfe von mehreren Prädikaten filtern. Meine Anforderungen dabei:
  1. die Funktion zum Filtern ist gleich für Listen verschiedener Typen (bspw. gleich für List<Thread> und List<Comment>)
  2. die Prädikate sind anwendbar auf mehrere Typen (durch Implementierung des Interfaces HasXXX)
  3. die Typen der Prädikate, die zum Filtern in die Methode gesteckt werden werden von den Elementen des Liste implementiert.
Ich habe ein kleines Beispiel gebastelt. Im ersten Schritt sollen List<Thread> und List<Comment> mit Hilfe eines gemeinsamen Prädikats gefiltert werden. Hierzu wird als Beispiel auf die Länge des Autorennamens gefiltert.
Java:
public interface HasAuthorName {
    String getAuthorName();
}

public interface HasApprovedStatus {
    boolean isApproved();
}

public class Thread implements HasAuthorName
//, HasApprovedStatus
{
    private final Author author;
    private final boolean isApproved;

    public Thread(Author author, boolean isApproved) {
        this.author = author;
        this.isApproved = isApproved;
    }

    @Override
    public String getAuthorName() {
        return author.getName();
    }


//    @Override
    public boolean isApproved() {
        return isApproved;
    }
}

public class Comment implements HasAuthorName {
    private final Author author;

    public Comment(Author author) {
        this.author = author;
    }

    @Override
    public String getAuthorName() {
        return author.getName();
    }
}

public abstract class Filter {

    private Filter() {}

    public static <T extends HasAuthorName> List<T> filter(List<T> list, Predicate<HasAuthorName>... predicates) {
        return list.stream()
                   .filter(Arrays.stream(predicates).reduce($ -> true, Predicate::and))
                   .collect(Collectors.toList());
    }

}
Das ist super. Ich kann Listen mit Threads und Comments gleichermaßen filtern.
Java:
class FilterTest {

    private static List<Thread> threads;
    private static List<Comment> comments;

    private Predicate<HasAuthorName> authorNameLongerThan4CharsPredicate = o -> o.getAuthorName().length() > 4;
    //private Predicate<HasApprovedStatus> approvedStatusPredicate = HasApprovedStatus::isApproved;

    @BeforeAll
    static void setUp() {

        final Author a1 = new Author("Lisa");
        final Author a2 = new Author("Theo");
        final Author a3 = new Author("Alfred");

        comments = Collections.unmodifiableList(Lists.list(
                new Comment(a1),
                new Comment(a2),
                new Comment(a3)
        ));

        threads = Collections.unmodifiableList(Lists.list(
                new Thread(a1, true),
                new Thread(a1, false)
        ));
    }


    @Test
    void testNamePredicate() {
        assertThat(authorNameLongerThan4CharsPredicate.test(() -> "a")).isFalse();
        assertThat(authorNameLongerThan4CharsPredicate.test(() -> "abcd")).isFalse();
        assertThat(authorNameLongerThan4CharsPredicate.test(() -> "abcde")).isTrue();
    }

    //@Test
    //void testApprovedPredicate() {
    //    assertThat(approvedStatusPredicate.test(new Thread(new Author(""), true))).isTrue();
    //    assertThat(approvedStatusPredicate.test(new Thread(new Author(""), false))).isFalse();
    //}

    @Test
    void filterAuthorNames() {
        assertThat(Filter.filter(comments, authorNameLongerThan4CharsPredicate)).hasSize(1);
        assertThat(Filter.filter(threads, authorNameLongerThan4CharsPredicate)).hasSize(0);
    }

    //@Test
    //void filterCombined() {
    //    assertThat(Filter.filter(comments, authorNameLongerThan4CharsPredicate)).hasSize(1);
    //    assertThat(Filter.filter(threads, authorNameLongerThan4CharsPredicate, approvedStatusPredicate)).hasSize(0);
    //}
}
Allerdings möchte ich Listen nach verschiedenen Prädikaten filtern. (Die auskommentierten Stellen ergänzen ein weiteres Attribut zum Filtern). Ich bekomme meine filter-Methode jedoch nicht dazu verschiedene Prädikate zu akzeptieren. Es ist logisch, da die Liste momentan an <T extends HasAuthorName> Elemente gebunden ist. Ich komme leider nicht weiter, wie ich das erreichen kann.
Ich habe das Projekt in den Anhang gepackt, falls jemand probieren möchte.
 

Anhänge

  • FilterPredicate.zip
    58,6 KB · Aufrufe: 0

MoxxiManagarm

Top Contributor
Das ist kein guter Ansatz für jedes Attribut ein neues Interface einzuführen. Am besten du erstellst genau ein Interface, welches genau eine Filtermethode enthält, sagen wir canBeDisplayed. Jede Klasse implementiert diese Methode dann selbst. Equals muss auch jede Klasse selbst definieren.
 

mrBrown

Super-Moderator
Mitarbeiter
Allerdings möchte ich Listen nach verschiedenen Prädikaten filtern. (Die auskommentierten Stellen ergänzen ein weiteres Attribut zum Filtern). Ich bekomme meine filter-Methode jedoch nicht dazu verschiedene Prädikate zu akzeptieren. Es ist logisch, da die Liste momentan an <T extends HasAuthorName> Elemente gebunden ist. Ich komme leider nicht weiter, wie ich das erreichen kann.
Ich habe das Projekt in den Anhang gepackt, falls jemand probieren möchte.
Man müsste in der Filter-Klasse ein bisschen mit Generics spielen, was ginge wäre etwas sowas:

Java:
public static <T> List<T> filter(List<? extends T> list, Predicate<? super T>... predicates) {
    return list.stream()
            .filter(t -> Arrays.stream(predicates).allMatch(p -> p.test(t)))
            .collect(Collectors.toList());
}



Das ist kein guter Ansatz für jedes Attribut ein neues Interface einzuführen. Am besten du erstellst genau ein Interface, welches genau eine Filtermethode enthält, sagen wir canBeDisplayed. Jede Klasse implementiert diese Methode dann selbst. Equals muss auch jede Klasse selbst definieren.
Den Vergleich mit equals finde ich schwierig, ob ein Objekte "gültig" ist, ist ja nicht vom Objekt kontrollierbar, sondern hängt von den Bedingungen, die von außen kommen, ab. Ist eher vergleichbar mit Comparable/Comparator, wo es auch völlig üblich ist, das ganze außerhalb der Klasse zu definieren.

Wenn es am Ende wirklich ein Interface pro Attribut gibt, fände ich das zwar auch nicht so schön, glaube aber auch nicht, dass es darauf hinausläuft. Klingt eher danach, dass es am Ende ein paar zu der Domäne passende Interfaces gibt, damit hätte ich kein wirkliches Problem.
 

looparda

Top Contributor
Vielen Dank, so hatte ich es mir vorgestellt und auch selbst versucht. Predicates.and wurde mir jedoch immer angemeckert und deswegen dachte ich, dass ich auf dem Holzweg sei.

Ich hatte mich an PECS erinnert und dachte somit die Liste müsste nach der Regel definitiv List<? super T> list lauten. Hatte ich aber auch falsch erinnert, da Producer das Lesen meint.

Der Hintergrund ist, dass ich eine Schicht über meine generierten Models legen möchte, weil sie sich ändern werden. Im Prinzip ein einfaches Delegate auf die richtigen Methoden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
MiMa Filtern von TableView Liste Allgemeine Java-Themen 2
J Zeichenketten-Liste filtern Allgemeine Java-Themen 6
Fynn29 Liste sortieren ohne Array und ohne vorgegebene Sortierung Allgemeine Java-Themen 5
B Liste aller Kombintionen mit Einschränkungen Allgemeine Java-Themen 8
TheSepp Wie kann man Leerzeichen aus einer Array liste entfernen? Allgemeine Java-Themen 10
B Liste ändern während Iteration über Diese? Allgemeine Java-Themen 16
D Erste Schritte Liste erweitern Allgemeine Java-Themen 11
sserio Variablen Liste erstellt und ein Problem mit dem Index Allgemeine Java-Themen 6
L allgemein Strings händisch in Liste sortieren Allgemeine Java-Themen 47
M einfach verkettete Liste verstehen Allgemeine Java-Themen 23
Drachenbauer wie kann ich alle instanzen einer Klasse durchsehen, ohne, dass diese in einer Liste erzeugt wurden? Allgemeine Java-Themen 11
Gaudimagspam Skip Liste erstellen in Java Allgemeine Java-Themen 3
G Java Editor Löschen doppelter Zahlen einer Liste Allgemeine Java-Themen 2
bueseb84 Spring Boot Entity mit Liste Allgemeine Java-Themen 4
MiMa Werte in liste speichern? Allgemeine Java-Themen 3
Curtis_MC Collections Liste anhand mehrere Kriterien sortieren Allgemeine Java-Themen 6
K verkettete Liste Allgemeine Java-Themen 3
G Liste (UsageStats) sortieren (Android) Allgemeine Java-Themen 5
T Google Links in einer Liste Allgemeine Java-Themen 4
OSchriever Einfach verkettete Liste ändern Allgemeine Java-Themen 43
L Liste überschreibt alte Elemte Allgemeine Java-Themen 10
H Länge einer verketteten Liste Allgemeine Java-Themen 4
E Erstellen einer Liste mit einer maximalen Menge an Elementen Allgemeine Java-Themen 13
P Element einer Liste wurde hinzugefügt, aber es gibt keinen Zugriff Allgemeine Java-Themen 2
S Methoden Liste soll Methode aus innerer Klasse aufrufen Allgemeine Java-Themen 4
L Erste Schritte Liste von Datums filter nach Monate Allgemeine Java-Themen 4
Y Liste in Stream Packen Allgemeine Java-Themen 1
K Einfache Verkettete Liste mit Node Allgemeine Java-Themen 3
perlenfischer1984 Reflection : Element in generische Liste hinzufügen Allgemeine Java-Themen 4
perlenfischer1984 Liste mit generics zurück liefern Allgemeine Java-Themen 8
S Verkettete (Teil)Liste sortieren ( rekursiv bis n) Allgemeine Java-Themen 2
G Liste zwischen zwei Kalenderdaten erstellen Allgemeine Java-Themen 3
B Wie vergleiche ich Strings in einer Liste? Allgemeine Java-Themen 5
Viktim Threads Liste In unterschiedlichen Threads bearbeiten Allgemeine Java-Themen 23
A Collections Inhalt einer Liste mit Inhalt anderer Liste vergleichen ? Allgemeine Java-Themen 7
I Abstrakte Datentypen - Liste Allgemeine Java-Themen 9
D Datentypen Klassenattribut aus Objekt in generischer Liste Allgemeine Java-Themen 15
P Liste zu Objekt umwandeln Allgemeine Java-Themen 4
Z In die Liste kann ich nichts adden Allgemeine Java-Themen 16
C Liste checken auf MINDESTENS ein Objekt | Bukkit Allgemeine Java-Themen 3
M liste von listen anders ausgeben Allgemeine Java-Themen 1
B Per Buttonklicks einer Liste Wörter hinzufügen - Wie umsetzen? Allgemeine Java-Themen 11
H Liste sortieren anhand optionalem Property Allgemeine Java-Themen 3
L Liste führt sich nicht weiter Allgemeine Java-Themen 5
A Input/Output Liste der Dateien in einem Ordner in einer Jar Datei erhalten Allgemeine Java-Themen 11
J Fragen zu generischer doppelt verketteter Liste (bei fehlendem Grundverständnis) Allgemeine Java-Themen 1
B Prüfen, ob ein Element in der Liste nicht existiert Allgemeine Java-Themen 3
B Klassen JTable mit einer Liste Allgemeine Java-Themen 0
X HTTP Auslesen der Ergebnisse von einer Webseite und in eine Liste packen Allgemeine Java-Themen 1
A Auslesen einer Datei sowie ausgeben als Liste in App Allgemeine Java-Themen 5
E Liste löscht sich selbstständig Allgemeine Java-Themen 5
H Liste von Objekten generisch sortieren Allgemeine Java-Themen 0
D Liste anhand Standardnormalverteilung befüllen Allgemeine Java-Themen 1
M Threads synchroner Zugriff (add/delete/read) auf eine Liste Allgemeine Java-Themen 6
T Datentypen Eine Liste - verschiedenen Klassen - eine Abstracte Klasse Allgemeine Java-Themen 3
M Werte aus DB in Liste speichern ohne mehrfach speicherung Allgemeine Java-Themen 18
G Liste anzahl der gleichen Objekte Allgemeine Java-Themen 6
S Pattern.Match Suche: For Schleife einbinden und in Liste schreiben Allgemeine Java-Themen 3
O aus Liste ein beliebiges Element auswählen Allgemeine Java-Themen 7
J Liste aller Com-Ports - zweistellige Ports? Allgemeine Java-Themen 15
O MVC - wo Liste der ComboBox-Items ermitteln Allgemeine Java-Themen 3
MiMa Liste von Pfaden in eine textArea schreiben Allgemeine Java-Themen 7
K kontinuierlich aktuelle Bestellsystem-Liste mit farbigem Status Allgemeine Java-Themen 2
A Auswählbare Liste Allgemeine Java-Themen 2
D Sortieren von Liste zu unperformant Allgemeine Java-Themen 6
N Liste gesucht Allgemeine Java-Themen 2
Z Sortiertes Einfügen in doppelt verkettete Liste Allgemeine Java-Themen 5
S Probleme beim Auslesen einer Liste Allgemeine Java-Themen 8
O JSON String bauen aus Liste Allgemeine Java-Themen 2
M Über Liste verschiendene JComponents mit eigenem implementierten Interface ansprechen Allgemeine Java-Themen 7
T Hashmap mit geordneter/ungeordneter liste als Value Allgemeine Java-Themen 5
D Zugriff auf Array-Liste Allgemeine Java-Themen 19
S Threads Liste mit Objekten in Teillisten zerlegen und abarbeiten Allgemeine Java-Themen 3
R ThreadPool - vorhandene thread liste überprüfen bzw. aufräumen Allgemeine Java-Themen 3
pg1337 Liste füllen Allgemeine Java-Themen 2
U Große Liste von Strings mit indiziertem Zugriff Allgemeine Java-Themen 31
B Properties File Liste Allgemeine Java-Themen 3
Gossi Collections Liste zusammenfassen für JSP Allgemeine Java-Themen 4
Gossi Collections (Unbekannte) Liste Sortieren Allgemeine Java-Themen 10
T Collections Liste schnell/nebenläufig durchgehen Allgemeine Java-Themen 2
M Objekt aus Liste in Liste suchen/löschen Allgemeine Java-Themen 6
Q "Doppelte" Einträge einer Liste entfernen Allgemeine Java-Themen 14
C Exponentielle Verteilung in einer Liste Allgemeine Java-Themen 7
Nic.o liste der installierten Zertifikate ?! Allgemeine Java-Themen 3
T Liste mit GregorianCalendar-Objekten in List einlesen, mit Collection sortieren und ausgeben Allgemeine Java-Themen 3
M Verständnisfragen bezüglich Liste Allgemeine Java-Themen 3
S AWT Wie bekomme ich eine Liste aller chars in einem Font? Allgemeine Java-Themen 3
S Aus einer Liste<Oberklasse> alle Elemente die eine bestimmte Unterklasse von Oberklasse haben filter Allgemeine Java-Themen 8
K Liste aller implementierenden Klassen einer Oberklasse anzeigen Allgemeine Java-Themen 4
M Eintrag verschwindet aus Liste Allgemeine Java-Themen 3
E Objekte in einer Liste suchen. Allgemeine Java-Themen 4
I Über eine Liste iterieren und Objekte löschen. Wie löst man das sauber? Allgemeine Java-Themen 5
reibi Kopie einer Liste Allgemeine Java-Themen 4
N Liste mit Map abgleichen extrem langsam Allgemeine Java-Themen 6
C Darstellung der Liste bei vielen Daten extrem langsam Allgemeine Java-Themen 11
T Liste sortieren Allgemeine Java-Themen 6
L Objekte in Liste packen Allgemeine Java-Themen 2
N Liste aendern waehrend des iterierens ueber selbige Allgemeine Java-Themen 11
B Datenstruktur: Liste Allgemeine Java-Themen 5
S Liste mit verschiedenden Objekten Allgemeine Java-Themen 15

Ähnliche Java Themen

Neue Themen


Oben