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

Author: Sunny, 2015-01-31

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.

 1
Author: sprinter, 2015-01-31 07:31:31