Commit a6e1eb2f by Patryk Czarnik

emps stream - ciąg dalszy

parent c656097a
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.List;
public class CzegoSieNieDaWLambdach {
static int sumaStatyczna = 0;
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
// czy damy radę obliczyć sumę pensji za pomocą tego nowego forEach?
int sumaLokalna = 0;
int[] tablica = {0};
emps.forEach(emp -> {
// wewnątrz wyrażeń lambda nie wolno modyfikować zmiennych lokalnych
// zdefiniowanych przed tym wyrażeniem
// ograniczenie "effectively final"
// sumaLokalna += emp.getSalary();
// bardzo brzydkie, ale działa:
sumaStatyczna += emp.getSalary();
tablica[0] += emp.getSalary();
});
System.out.println(sumaLokalna);
System.out.println(sumaStatyczna);
System.out.println(tablica[0]);
System.out.println();
// właściwe podejście:
int suma = emps.stream().mapToInt(Employee::getSalary).sum();
System.out.println(suma);
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.Scanner;
public class DaneOpcjonalne {
public static void main(String[] args) throws FileNotFoundException {
// Użytkownik podaje nazwę miasta, a program filtruje dane wczytane z pliku
// i oblicza średnią pensję oraz znajduje najbogatszego i najbiedniejszego pracownika.
// Przykład ma pokazać, jak można wykorzystać wyniki typu Optional.
Scanner scanner = new Scanner(System.in);
System.out.print("Podaj nazwę miasta: ");
String miasto = scanner.nextLine();
List<Employee> emps = ObslugaCSV.readCSV();
OptionalDouble srednia = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.mapToInt(Employee::getSalary)
.average();
Optional<Employee> min = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.min(Comparator.comparingInt(Employee::getSalary));
Optional<Employee> max = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.max(Comparator.comparingInt(Employee::getSalary));
System.out.println("średnia" + srednia);
System.out.println("min: " + min);
System.out.println("max: " + max);
System.out.println();
// Za pomocą isPresent / isEmpty można sprawdzać, czy obiekt zawiera wartość
if(srednia.isPresent()) {
// aby wydobyć liczbę z obiektu, piszemy getAsDouble (w przypadku pustego Optionala kończy się to błędem)
System.out.println("Średnia pensja = " + srednia.getAsDouble());
} else {
System.out.println("Brak danych");
}
System.out.println();
if(min.isPresent()) {
// aby dostać się do obiektu wewnątrz Optionala, piszemy get(); w razie braku danych powoduje to błąd
Employee emp = min.get();
System.out.println("Najbiedniejszy: " + emp.getFirstName() + " " + emp.getLastName() + " z pensją " + emp.getSalary());
} else {
System.out.println("Brak danych");
}
if(max.isEmpty()) {
System.out.println("Brak danych");
} else {
Employee emp = max.get();
System.out.println("Najbogatszy: " + emp.getFirstName() + " " + emp.getLastName() + " z pensją " + emp.getSalary());
}
System.out.println();
// Operacja orElse zwraca wartość z wnętrza Optionala, a w razie braku danych zwraca wartość alternatywną podaną w nawiasach
System.out.println("srednia.orElse(0) = " + srednia.orElse(0));
System.out.println("srednia.orElse(NaN) = " + srednia.orElse(Double.NaN));
// W przypadku obiektów użycie orElse wymagałoby posiadania "domyślnego pracownika", ew. można wstawić nulla
Employee fejkowy = new Employee(0, "Fejkowy", "Pracownik", "nikt", -1, null, "", "", "", "", "nieznany kraj");
System.out.println("najbiedniejszy lub zmyślony:");
System.out.println(min.orElse(fejkowy));
System.out.println("najbogatszy lub null:");
System.out.println(max.orElse(null));
System.out.println();
// Domyślnym wyjątkiem wyrzucanym w razie braku danych gdy robimy get jest NoSuchElementException
// System.out.println("Najbogatsza osoba to " + max.get().getLastName());
// ale możemy wyrzuć własny dedykowany wyjątek
// Podajemy to w formie lambdy, aby kod tworzący wyjątek został wykonany tylko wtedy, gdy jest naprawdę potrzebny
// String nazwisko = max.orElseThrow(() -> new RuntimeException("wielka bieda")).getLastName();
// System.out.println("Najbogatsza osoba to " + nazwisko);
// Na obiektach Optional (i w mniejszym stoniu na ich wersjach liczbowych) można wykonywać operacje
// przypominające operacje na strumieniach.
// Operacja map z Optionala jednego typu jest w stanie utworzyc Optional innego typu
// Na podstawie Optional<Employee> utworzymy Optional<String> zawierający dane pracownika
Optional<String> minTXT = min.map(emp -> "Najbiednieszy jest " + emp.getFirstName() + " " + emp.getLastName());
// Jeśli min był pusty, to minTXT też będzie pusty
// Jeśli min zawierał dane pracownika, to minTXT będzie zawierał tekst z imieniem i nazwiskiem pracownika
System.out.println("Optional<String>: " + minTXT);
// Można to wykorzystać w zapisie typu pipeline w taki sposób:
String maxTXT = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.max(Comparator.comparingInt(Employee::getSalary))
.map(emp -> "Najbogatszy jest " + emp.getFirstName() + " " + emp.getLastName())
.orElse("Brak danych najbogatszego");
System.out.println("maxTXT: " + maxTXT);
// czasami może się zdarzyć, że wartość alternatywna jest obliczana w trakcie działania programu
// aby uniknąć niepotrzebnego obliczania (aby robić to tylko w przypadku braku danych), można podać wyrażenie lambda tworzące ten wynik
String maxTXT2 = emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.max(Comparator.comparingInt(Employee::getSalary))
.map(emp -> "Najbogatszy jest " + emp.getFirstName() + " " + emp.getLastName())
.orElseGet(() -> "Brak najbogatszego w mieście " + miasto);
System.out.println("maxTXT2: " + maxTXT2);
// Można też podać akcję, która zostanie wykonana tylko, gdy optional nie jest pusty
min.ifPresent(emp -> System.out.println("Znaleziony najbiedniejszy pracownik! - " + emp.getFirstName() + " " + emp.getLastName()));
// wersja z else (co zrobić w razie braku danych)
max.ifPresentOrElse(
emp -> System.out.println("Znaleziony najbogatszy pracownik! - " + emp.getFirstName() + " " + emp.getLastName()),
() -> System.out.println("Nie znaleziomo najbogatszego!"));
// oczywiście można to zastosować na końcu pipeline
emps.stream()
.filter(emp -> emp.getCity().equals(miasto))
.mapToInt(Employee::getSalary)
.average()
.ifPresentOrElse(
avg -> System.out.println("Jest średnia " + avg),
() -> System.out.println("Nie ma średniej"));
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.stream.Collectors;
public class P3_SredniaWszystkich {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
/*
// W Javie wewnątrz wyrażeń lambda nie wolno modyfikować zmiennych lokalnych zadeklarowanych w bloku zewnętrznym.
// Nie wolno odwoływać się do zmiennych, które się w ogóle zmieniają (czyli nie mogą być oznaczone final).
double suma = 0;
emps.stream().forEach(emp -> {
suma += emp.getSalary();
});
*/
double srednia1 = emps.stream()
.mapToInt(Employee::getSalary)
.average()
.orElse(0);
System.out.println(srednia1);
Double srednia2 = emps.stream().collect(Collectors.averagingInt(Employee::getSalary));
System.out.println(srednia2);
// zadanie: P4_SredniaJedenJob za pomocą strumieni
// dla chętnych: również P5 MinMax - P6_Sortowanie P7_UnikalneJoby (albo zrobić miasta..)
// grupowanie za pomocą streamów i odpowiedniego Collectora
}
}
package emps.streamy;
import javax.swing.*;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.stream.Collectors;
public class P4_SredniaJedenJob_v1 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
String szukanyJob = JOptionPane.showInputDialog("Podaj nazwę stanowiska");
double srednia = emps.stream()
.filter(emp -> emp.getJobTitle().equalsIgnoreCase(szukanyJob))
.mapToInt(Employee::getSalary)
.average()
.orElse(0);
JOptionPane.showMessageDialog(null, srednia);
}
}
package emps.streamy;
import javax.swing.*;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.OptionalDouble;
public class P4_SredniaJedenJob_v2 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
String szukanyJob = JOptionPane.showInputDialog("Podaj nazwę stanowiska");
OptionalDouble srednia = emps.stream()
.filter(emp -> emp.getJobTitle().equalsIgnoreCase(szukanyJob))
.mapToInt(Employee::getSalary)
.average();
if(srednia.isPresent()) {
JOptionPane.showMessageDialog(null, String.format(
"Pracownicy typu %s mają średnią pensję %.2f", szukanyJob, srednia.getAsDouble()));
} else {
JOptionPane.showMessageDialog(null, String.format("Nikt nie pracuje na stanowisku %s", szukanyJob));
}
}
}
package emps.streamy;
import javax.swing.*;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.OptionalDouble;
public class P4_SredniaJedenJob_v3 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
String szukanyJob = JOptionPane.showInputDialog("Podaj nazwę stanowiska");
// optSrednia.ifPresent(avg -> System.out.println("Średnia = " + avg));
emps.stream()
.filter(emp -> emp.getJobTitle().equalsIgnoreCase(szukanyJob))
.mapToInt(Employee::getSalary)
.average()
.ifPresentOrElse(
avg -> JOptionPane.showMessageDialog(null, String.format(
"Pracownicy typu %s mają średnią pensję %.2f", szukanyJob, avg)),
() -> JOptionPane.showMessageDialog(null, String.format("Nikt nie pracuje na stanowisku %s", szukanyJob)));
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.Comparator;
import java.util.List;
public class P5_MinMax_v1 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
// Gdyby strumień był pusty i min / max zwracały Optional.empty(), to opracja get skończy się wyjątkiem.
Employee min = emps.stream().min(Comparator.comparingInt(Employee::getSalary)).get();
Employee max = emps.stream().max(Comparator.comparingInt(Employee::getSalary)).get();
System.out.println("min: " + min.getFirstName() + " " + min.getLastName() + " " + min.getSalary());
System.out.println("max: " + max.getFirstName() + " " + max.getLastName() + " " + max.getSalary());
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.Comparator;
import java.util.List;
public class P5_MinMax_v2 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
Comparator<Employee> comparator = Comparator.comparingInt(Employee::getSalary);
emps.stream()
.min(comparator)
.map(emp -> "min: " + emp.getFirstName() + " " + emp.getLastName() + " " + emp.getSalary())
.ifPresent(System.out::println);
emps.stream()
.max(comparator)
.map(emp -> "max: " + emp.getFirstName() + " " + emp.getLastName() + " " + emp.getSalary())
.ifPresent(System.out::println);
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.Comparator;
import java.util.List;
public class P6_Sortowanie {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
emps.stream()
.sorted(Comparator.comparingInt(Employee::getSalary).reversed())
.map(emp -> emp.getFirstName() + " " + emp.getLastName() + " " + emp.getSalary())
.forEach(System.out::println);
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class P7_MiastaBezPowtorzen {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
// sposób 1: utworzyć zbiór Stringów
// ma to sens, gdy potrzebujemy wykorzystać te dane w dalszej części programu
Set<String> miasta = emps.stream()
.map(Employee::getCity)
.collect(Collectors.toSet());
System.out.println(miasta);
System.out.println("--------");
// sposób 2: w łańcuchu poleceń (pipeline) umieścić operację distinct
// ma to sens, gdy wykonujemy tylko jedną operację, np, chcemy tylko wypisać te miasta
emps.stream()
.map(Employee::getCity)
.filter(s -> !s.isEmpty())
.distinct()
.sorted()
.forEach(System.out::println);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment