Objekt-Suche mit mehreren optionalen Parametern

dflasjjs

Bekanntes Mitglied
Hi,

ich habe ein Object (Customer) mit den Attributen: name, email, city und status.
Mehrere dieser Objekte befinden sich in einem Vector<Customer>.

Jetzt habe ich eine Suchfunktion bauen, welche mir nach Eingabe eines ODER mehrer Parameter eine Ergebnisliste auswirft.

Aktuell steh ich vor dem Problem, dass ich einen If-Verteiler einbaue, den ich exponentiell erweitern muss, wenn man ein vierter Parameter hinkommt:

Code:
public Vector<Customer> getCustomerBySearch(String emailName, String city, CustomerStatus status) {

   Vector<Customer> res = new Vector<Customer>();

   Vector<Customer> resultNameEmail = getCustomerBySearchNameEmail(emailName);
   Vector<Customer> resultCity = getCustomerBySearchCity(city);
   Vector<Customer> resultStatus = getCustomerBySearchStatus(status);

   if (!emailName.equals("") && !city.equals("") && status != null) {
      resultNameEmail.retainAll(resultCity);
      resultNameEmail.retainAll(resultStatus);
      res = resultNameEmail;
   } 

   return res;
}

Ich müsste jetzt ja für jede Kombination aus den Parametern so einen If-Kasten bauen, jetzt nur 8 bzw. 7, mit einem vierten Parameter schon 16 usw. wie kann ich das eleganter lösen?
 

Thallius

Top Contributor
Indem du statt für jeden Parameter eine fertige search Methode aufrufst, du einfach selber über den Vector iterierst und innerhalb der Schleife eben alles gesetzten Parameter testest....
 

dflasjjs

Bekanntes Mitglied
Zusätzlich zu dem, was @Thallius geschrieben hat, könntest Du die Tests innerhalb der Iteration verallgemeinern: https://en.wikipedia.org/wiki/Specification_pattern. Ab Java 8 s. java.util.function.Predicate.

Das ist ja wirklich geiler Scheiß, hilft mir auf jeden Fall schon mal weiter.
Ich habe jetzt folgendes:

Code:
public Vector<Customer> getCustomerBySearch(Predicate<Customer> p) {

   Vector<Customer> res = new Vector<Customer>();
   for (Customer c : getCustomers()) {
        if (p.test(c)) {
          res.add(c);
       }
    }
   Collections.sort(res, Customer.getFullNameReverseComparator());

   return res;
}

Funktioniert auch super, allerdings ist der Aufruf jetzt ja das entscheidende.

Im Prinzip stehe ich hier jetzt vor dem selben Problem, ich müsste einen Verteiler machen oder bekomme ich das eleganter hin?
Code:
getCustomerBySearch(p -> p.equalsName(searchTerm))
Was ich will ist ja sowas:
Code:
getCustomerBySearch( if(name) {p -> p.equalsName(name)} && if(searchTerm) {p -> p.equalsCity(city)} && if(searchTerm) {p -> p.equalsStatus(status)})
Geht das irgendwie elegant mit Predicate?


OK, habs jetzt anders gelöst.

Code:
getCustomerBySearch(p -> p.equalsName(searchTerm) && p.equalsEmail(searchTerm) && p.equalsCity(city) && p.equalsStatus(status)))

Und in den Vergleichmethoden gebe ich einfach true zurück, wenn der String leer ist. So habe ich das selbe Ergebnis.

Vielen Dank euch beiden! :)
 
Zuletzt bearbeitet:

mihe7

Top Contributor
p.equalsName(searchTerm) && p.equalsEmail(searchTerm)
Name und Email sollen gleich sein?

Geht das irgendwie elegant mit Predicate?

Du kannst z. B. folgendes machen (skizziert):
Java:
public class Customer {
...
    public static Predicate<Customer> byMail(String term) {
        return p -> mail.equals(term);
    }
...
}
// und dann etwas wie
getCustomersBySearch(Customer.byName(searchTerm)
    .and(Customer.byMail(searchTerm))
    .and(...));

Das ist ja wirklich geiler Scheiß
LOL. Noch "geiler wird der Scheiß", wenn Du Streams verwendest (java.util.stream.Stream), dann kannst Du Dir das Programmieren der Schleife sparen:
Java:
Vector<Customer> customers = ...;
List<Customer> filtered = customers.stream()
    .filter(Customer.byName(searchTerm)
        .and(Customer.byMail(searchTerm))
        .and(...))
    .collect(Collectors.toList());

Falls Du mit den Customers "irgendwas" vorhast, könntest Du auch
Java:
public void forMatching(Predicate<Customer> p, Consumer<Consumer> c) {
     customers.stream().filter(p).forEach(c);
}
implementieren und dann
Java:
customers.forMatching(Customer.byName(searchTerm), c -> doSomething(c));
verwenden. Der Phantasie sind kaum Grenzen gesetzt.
 

Thallius

Top Contributor
Das Ganze funktioniert aber alles nur, wenn immer alles Suchparameter gesetzt sind, was ich für nicht realitätsnah halte. Normalerweise würde ich sagen, dass beliebige PArameter gesetzt sein können und die anderen NULL. Das man dann eben auch nur nach Stadt suchen kann oder nur nach Name und Alter oder was auch immer es noch für Parameter geben wird.

Ausserdem wird es nicht gerade schneller, wenn man für jeden Parameter einmal komplett über das Array iterieren muss anstatt innerhalb einer Schleife alles abzufragen.

Gruß

Claus
 

MoxxiManagarm

Top Contributor
Ehrlich gesagt würde ich diese Suche nie wieder anfassen wollen, wenn ich sie einmal programmiert habe. Wenn sich das Objekt ändert (also Attribute hinzukommen), dann ändert sich im besten Fall nur das Objekt (also Customer) und nicht die Suche, also bestenfalls werden weniger Klassen verändert. Das könnte in Projekten u.a. Einfluss auf den Testscope haben. Aus diesem Grund hier ein Vorschlag von mir:

Java:
package javaforum.org.dflasjjs;

import java.lang.reflect.Field;
import java.util.Vector;
import java.util.stream.Collectors;

public class Customer {
    private String name;
    private String email;
    private String city;

    public Customer(String name, String email, String city) {
        this.name = name;
        this.email = email;
        this.city = city;
    }
 
    public boolean isMaskedBy(Customer customer) {
        for(Field field : Customer.class.getDeclaredFields()) {
            try {
                Object object1 = field.get(this);
                Object object2 = field.get(customer);
           
                if(object2 != null && ! object2.equals(object1)) {
                    return false;
                }
            } catch (IllegalArgumentException | IllegalAccessException ex) {
                // handle it
            }
        }
   
        return true;
    }
 
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
   
        for(Field field : Customer.class.getDeclaredFields()) {
            try {
                sb.append(field.get(this));
            } catch (IllegalArgumentException | IllegalAccessException ex) {
                // handle it
            }
        }
   
        return sb.toString();
    }
 
    public static void main(String[] args) {
        Vector<Customer> customers = new Vector<>();

        customers.add(new Customer("Max Mustermann", "max.mustermann@gmx.de", "Berlin"));
        customers.add(new Customer("Martina Musterfrau", "matina.musterfrau@web.de", "München"));
        customers.add(new Customer("Marc Musterbub", "marc.musterbub@gmail.com", "Köln"));

        Customer mask = new Customer(null, null, "München");

        // Diese Suche bleibt unverändert, falls sich Customer ändert
        System.out.println(customers.stream()
                 .filter(customer -> customer.isMaskedBy(mask))
                 .collect(Collectors.toList())
        );
    }
}

PS.: Muss es wirklich Vector sein? Vector ist deprecated
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Lwjgl 3d Objekt wird schmaler, wenn es sich dreht Allgemeine Java-Themen 0
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
T Objekt Array Aufgabe mit Busdatenbank Allgemeine Java-Themen 2
Maxi-JOO Klassen Dummy Objekt in anderen Constructor übergeben Allgemeine Java-Themen 5
el_niiinho13 Objekt auf der Konsole ausgeben lassen Allgemeine Java-Themen 8
d.lumpi Aus Einer Klasse auf ein Objekt einer anderen Klasse Zugreifen Allgemeine Java-Themen 1
A Objekt aus anderen Objekten machen Allgemeine Java-Themen 8
SaftigMelo In einem Winkel Objekt bewegen Allgemeine Java-Themen 2
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
H Objekt speichern und laden Allgemeine Java-Themen 1
H Objekt speichern und laden Allgemeine Java-Themen 1
J Objekt in Bytestream umwandeln Allgemeine Java-Themen 12
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
J Information von getSource() Objekt auslesen Allgemeine Java-Themen 1
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
S Variable als Objekt Name Allgemeine Java-Themen 3
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
T Objekt in Array packen Allgemeine Java-Themen 6
K Methodenaufruf mit String / String zu Objekt konvertieren Allgemeine Java-Themen 8
S Neues Objekt darstellen Allgemeine Java-Themen 4
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
M Klassen Objekt weiter geben Allgemeine Java-Themen 1
B Klassen Objekt erzeugen und Konstruktor aufrufen - Welche Lösung ist besser? Allgemeine Java-Themen 2
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
D Konstruktor - jedes Objekt einzeln erzeugen - alternative? Allgemeine Java-Themen 8
S Applet Überprüfen ob ein Objekt angeklickt wurde Allgemeine Java-Themen 2
RalleYTN 3D Objekt Translation basierend auf Rotation (Probleme mit Z Rotation) Allgemeine Java-Themen 0
B Von String zu <Objekt> ||Speichern/Laden Allgemeine Java-Themen 17
G Neues Objekt aus List<JsonObject> mit Stream Allgemeine Java-Themen 4
P Threads Objekt im Konstruktor anders wie im Run()-Block Allgemeine Java-Themen 10
R Objekt funktioniert nicht auf iOS Allgemeine Java-Themen 15
K Textdatei als Objekt Allgemeine Java-Themen 4
Viktim Classenname zu Objekt Allgemeine Java-Themen 4
P Entity Objekt Methoden vs Service methoden Allgemeine Java-Themen 2
D Datentypen Klassenattribut aus Objekt in generischer Liste Allgemeine Java-Themen 15
O Klassen Bruch im gleichen Objekt Speichern Allgemeine Java-Themen 1
P Liste zu Objekt umwandeln Allgemeine Java-Themen 4
C Liste checken auf MINDESTENS ein Objekt | Bukkit Allgemeine Java-Themen 3
K Best Practice JFrame Objekt allgemein zugänglich machen Allgemeine Java-Themen 8
B ArrayList in ein Objekt legen Allgemeine Java-Themen 1
D Objekt entlang eines Funktionsgraphens bewegen Allgemeine Java-Themen 6
M Objekt serialisieren/deserialisieren und in einer SQLite-Datenbank speichern Allgemeine Java-Themen 3
D Java Objekt als Service in Runtime registrieren Allgemeine Java-Themen 1
S Interaktion mit einer website (website als Objekt?) Allgemeine Java-Themen 3
J OOP Überwachen, ob ein Objekt erzeugt wird Allgemeine Java-Themen 9
S Byte Array welches in Laufzeit aufgelöst wird // Objekt Array Allgemeine Java-Themen 3
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
Developer_X Input/Output Serialisiertes Objekt speichern und laden Allgemeine Java-Themen 1
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
L Klassen Konstruktor soll Objekt anderer Klasse erzeugen Allgemeine Java-Themen 2
F Neues Objekt aus .CSV definition Allgemeine Java-Themen 3
K Methoden Objekt wird nicht erkannt Allgemeine Java-Themen 11
P Objekt mit verschiedenen Datentypen Allgemeine Java-Themen 5
T Objekt kontaktiert seinen "erzeuger" Allgemeine Java-Themen 5
S Objekt orientierte Programmierung Allgemeine Java-Themen 7
C Objekt Datenverlust nach Methodenaufruf Allgemeine Java-Themen 9
H JavaFX Von einer Methode auf stage-Objekt zugreifen Allgemeine Java-Themen 3
T WeakReference/PhantomReference: Mitbekommen WELCHES Objekt nun GC'ed wird Allgemeine Java-Themen 2
T Class-Objekt mit URLClassloader Allgemeine Java-Themen 7
P Konsoleneingabe übernehmen und Objekt instanzieren. Allgemeine Java-Themen 5
E Auf Java-Objekt aus anderer Instanz zugreifen Allgemeine Java-Themen 26
L Klassen Polymorphie:2 Attribute gleichen Namens in einem Objekt Allgemeine Java-Themen 6
P Objekt Array in Datei Speichern Allgemeine Java-Themen 3
F Dynamisch ein Objekt einer bestimmten Subklasse erstellen Allgemeine Java-Themen 7
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
V Objekt löschen Allgemeine Java-Themen 7
A OOP Wie auf Objekt der Superklasse zugreifen? Allgemeine Java-Themen 6
S Datei in File-Objekt mit UTF-8 einlesen Allgemeine Java-Themen 2
M neues Objekt speichern, nicht Referenz Allgemeine Java-Themen 10
B synchronisierter zugriff auf Objekt Allgemeine Java-Themen 6
F Objekt einer Datei verschieben, aber Verzeichnispfad fehlt Allgemeine Java-Themen 6
C Objekt Typ herausfinden Allgemeine Java-Themen 5
E Objekt beim Erzeugen in ArrayList Allgemeine Java-Themen 9
M Objekt prüfen auf null ->Invocation Target Exception??? Allgemeine Java-Themen 2
M Objekt aus Liste in Liste suchen/löschen Allgemeine Java-Themen 6
D Eigenen Objekt Pool Allgemeine Java-Themen 15
C blueJ: Objekt wird nicht in Objektleiste angezeigt Allgemeine Java-Themen 8
T Objekt 2x deserialisieren, aber nur 1x im Heap haben? Allgemeine Java-Themen 4
sambalmueslie Benachrichtigung bei neuer Objekt-Instanz Allgemeine Java-Themen 5
U Konstante in Objekt definieren Allgemeine Java-Themen 6
D this mit Objekt überschreiben Allgemeine Java-Themen 17
R Synchronized - auf welchem Objekt Allgemeine Java-Themen 16
E Objekt erstellen Allgemeine Java-Themen 7
M Timer von nicht existiertem Objekt stopen Allgemeine Java-Themen 5
M Swing-Frontend abhängig von ausgewähltem Objekt Allgemeine Java-Themen 4
J Lebt das Objekt noch?? Allgemeine Java-Themen 12
K Objekt einer konkreten Implementierung eines Interfaces durch übergebenen String Allgemeine Java-Themen 2
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
S Performance Frage: Objekt oder static? Allgemeine Java-Themen 33
B Speicherverbrauch Objekt-Referenz Allgemeine Java-Themen 11
D Browser-Objekt erzeugen Allgemeine Java-Themen 8
B FileWriter / FileReader testen / Mock-Objekt für Unit Tests? Allgemeine Java-Themen 6
A Iterationen einer XML-Datei in einem Objekt sichern Allgemeine Java-Themen 5
R Objekt zur Laufzeit zerstören? Allgemeine Java-Themen 12
hdi Frage zur Objekt Initialisierung Allgemeine Java-Themen 4
X Prozess-Objekt nach Ausführung der destroy-Methode null oder nicht null ? Allgemeine Java-Themen 10
T Serialisiertes Objekt über Socket nachladen Allgemeine Java-Themen 8
G Entity Objekt Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben