java - Liste der Mitarbeiter mit dem niedrigsten Gehalt über Stream abrufen




lambda java-8 (4)

Erstellen Sie zunächst eine TreeMap , deren Schlüssel das Gehalt ist. TreeMap sortiert seine Einträge nach seinem Schlüssel. Nehmen Sie dann den ersten Eintrag, den Eintrag mit dem niedrigsten Gehalt, und erfassen Sie die damit verbundenen Werte. Diese Lösung durchläuft die Liste nur einmal. So sieht es aus.

List<Employee> empsWithLowestSalary = employees.stream()
    .collect(Collectors.groupingBy(Employee::getSalary, TreeMap::new, Collectors.toList()))
    .firstEntry()
    .getValue();

TreeMap speichert Kartenelemente in einem rot-schwarzen Baum. Die Einfügungskosten für ein Element im Rot-Schwarz-Baum O(Log (n)) . Da wir n Elemente einfügen, ist die Gesamtzeitkomplexität dieser Lösung O(n Log (n)) . Für firstEntry() wird eine konstante Zeit O(1) , da ein Zeiger auf den am weitesten links und am weitesten rechts gelegenen Blattknoten in der firstEntry() beibehalten wird. Der Knoten ganz links repräsentiert den kleinsten Wert in der Baumstruktur, während der Knoten ganz rechts den höchsten Wert repräsentiert.

Gerade als ich dieser großartigen Antwort gefolgt bin, habe ich darüber nachgedacht, einen benutzerdefinierten Sammler zu schreiben, der unseren Zweck erfüllt. Dieser Kollektor durchläuft die Liste nur einmal und seine Laufzeitkomplexität liegt bei O (n), was den obigen Ansatz deutlich übertrifft. Darüber hinaus können Sie Ihren Client-Code in einer einzigen Anweisung schreiben. So sieht es aus.

static <T> Collector<T, ?, List<T>> minList(Comparator<? super T> comp) {
    return Collector.of(ArrayList::new, (list, t) -> {
        int c;
        if (list.isEmpty() || (c = comp.compare(t, list.get(0))) == 0)
            list.add(t);
        else if (c < 0) {
            /*
             * We have found a smaller element than what we already have. Clear the list and
             * add this smallest element to it.
             */
            list.clear();
            list.add(t);
        }
    }, (list1, list2) -> {
        if (comp.compare(list1.get(0), list2.get(0)) < 0)
            return list1;
        else if (comp.compare(list1.get(0), list2.get(0)) > 0)
            return list2;
        else {
            list1.addAll(list2);
            return list1;
        }
    });
}

Und hier ist Ihr Kundencode.

Collection<Employee> empsWithLowestSalary = employees.stream()
                .collect(minList(Comparator.comparing(Employee::getSalary)));

Ich versuche, eine Liste der Mitarbeiter mit dem niedrigsten Gehalt abzurufen. Bisher habe ich es geschafft, den Mitarbeiter mit dem niedrigsten Gehalt zu finden, aber ich möchte mehrere abrufen, wenn mehrere Mitarbeiter das gleiche Gehalt haben.

Ich denke, die Lösung sollte in einer Zeile stehen. Ich kann also keine Variable mit dem niedrigsten Gehalt erstellen und einfach jedes auf 'Gehalt kleiner oder gleich Low_Salary' prüfen. Ich habe es versucht und es hat funktioniert.

Daher glaube ich, dass mein Problem darin besteht, dass ".min (Komparator)" nur eines der niedrigsten abruft.

Comparator<Employee> comparator = Comparator.comparing( Employee :: getSalary);
List<Employee> lowSalary = employees.stream()
               .min(comparator)
               .stream()
               .collect(Collectors.toList());
lowSalary.forEach(System.out::println);

Sie können das Mindestgehalt zuerst berechnen und dann in Ihrer Stream#filter verwenden:

int salary = 
   employees.stream()
            .min(Comparator.comparing(Employee::getSalary))
            .map(e -> e.getSalary())
            .orElse(-1);

List<Employee> emps = 
  employees.stream()
           .filter(emp -> emp.getSalary() == salary)
           .collect(Collectors.toList());

Sie können zuerst den Mindestgehalt Mitarbeiter erhalten und dann danach filtern,

  Comparator<Employee> comparator = Comparator.comparing( Employee :: getSalary);
        Optional<Employee> min = employees.stream()
                .min(comparator);
        List<Employee> lowSalary = employees.stream()
                .filter(ele->ele.salary==min.get().salary)
                .collect(Collectors.toList());

Integer lowestSalary = employees.stream()
.min(Comparator.comparing(Employee::getSalary))
.map(Employee::getSalary).get();

List<Employee> employeesWithLowestSalary = employees.stream()
.filter(e -> e.getSalary() == lowestSalary)
.collect(Collectors.toList());

Suchen Sie zunächst nach dem niedrigsten Gehalt und filtern Sie dann die Liste der Mitarbeiter, sodass Sie nur Mitarbeiter haben, deren Gehalt übereinstimmt.







java-stream