Java - Criteri di ricerca nell'elenco delle classi definite dall'utente
Ho una classe POJO SearchCriteria
public class SearchCriteria{
private int empId;
private String empName;
private String empAddress;
private String empDesignation,
:
:
//getter + setters
}
Ho un metodo returnAllEmployees in un'altra classe
public List<Employees> returnAllEmployees (){
// makes a db call which has lot of joins and returns info for all the employees
}
Ora la mia domanda è che devo filtrare il risultato di returnAllEmployees() in base ai criteri di ricerca passati, ovvero se il campo empName di searchcriteria è popolato come "ABC", l'elenco dei filtri dovrebbe contenere i dettagli di tutti i dipendenti come ABC.
Allo stesso modo, se i criteri di ricerca contengono empName = " ABC " e empDesignation="engineer", dovrebbe filtrare l'elenco contenente tutti i dipendenti aventi nome abc e designazione come ingegnere
So che è possibile usare if-else ma ciò creerebbe molte righe di codici
1 answers
La soluzione migliore è usare i flussi Java 8. Sono perfetti per questo:
List<Employee> listOfEngineersCalledFred = getAllEmployees().stream()
.filter(emp -> emp.getName().equals("Fred"))
.filter(emp -> emp.getDesignation().equals("Engineer"))
.collect(Collectors.toList());
Una tecnica che personalmente trovo utile e ordinata è quella di aggiungere metodi statici che restituiscano predicati invece di usare getter:
class Employee {
public static Predicate<Employee> hasName(String name) {
return emp -> emp.name.equals(name);
}
}
Questi possono quindi essere utilizzati, ad esempio, per trovare tutti i dipendenti non chiamare Fred:
streamAllEmployees()
.filter(Employee.hasName("Fred").negate())
...
Che sembra più ordinato e più deliberato di esporre il campo con un getter.
Potresti anche considerare di convertire il tuo getAllEmployees
in streamAllEmployees
:
public Stream<Employee> streamAllEmployees() {
return employeeList.stream();
}
Quindi stai dicendo all'utente che possono fare cose con gli oggetti employee nell'elenco piuttosto che nell'elenco stesso.
La cosa bella di restituirlo come flusso è che una volta filtrato puoi facilmente contare, raggruppare, ordinare, rimuovere i duplicati, ottenere il primo n ecc. Puoi anche convertirlo banalmente per utilizzare più thread se stai filtrando un gran numero di elementi.
Per esempio:
Map<String, Employee> employeesByDesignation = streamAllEmployees()
.collect(Collectors.groupingBy(emp -> emp.getDesignation()));
Sono molto potenti e vale la pena imparare e servendosi.