Commit a10068e2 by Patryk Czarnik

koniec tematu streamów

parent a6e1eb2f
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GrupowanieF1 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
// Dla każdej wartości jobTitle w słowniku zapisana jest lista pracowników, którzy mieli tę wartość.
Map<String, List<Employee>> grupy = emps.stream().collect(Collectors.groupingBy(Employee::getJobTitle));
// System.out.println(grupy);
grupy.forEach((job, lista) -> {
System.out.println("Pracownicy ze stanowiska " + job + " (" + lista.size() + " sztuk):");
lista.forEach(emp -> {
System.out.println(" * " + emp.getFirstName() + " " + emp.getLastName() + " " + emp.getSalary());
});
System.out.println();
});
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class GrupowanieF2 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
// Drugim paramterm kolektora groupingBy może być inny kolektor, który mówi "co zrobić z każdą grupą"
Map<String, Double> srednie = emps.stream().collect(Collectors.groupingBy(
Employee::getJobTitle, Collectors.averagingInt(Employee::getSalary)));
srednie.forEach((job, srednia) -> {
System.out.println(job + " → " + srednia);
});
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class GrupowanieF3 {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
Map<String, IntSummaryStatistics> grupy = emps.stream()
.collect(Collectors.groupingBy(
Employee::getJobTitle,
TreeMap::new,
Collectors.summarizingInt(Employee::getSalary)));
grupy.forEach((job, stats) -> {
// System.out.printf("%-32s → %s%n", job, stats);
System.out.printf("| %-32s | %2d | %5d | %8.2f | %5d |%n",
job, stats.getCount(), stats.getMin(), stats.getAverage(), stats.getMax());
});
}
}
package emps.streamy;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class P8_Partycje {
public static void main(String[] args) throws FileNotFoundException {
List<Employee> emps = ObslugaCSV.readCSV();
// Podział rekordów na dwie części i zapisanie w słowniku,
// w którym kluczem są wartości true/false
Map<Boolean, List<Employee>> grupy = emps.stream()
.collect(Collectors.partitioningBy(emp -> emp.getSalary() >= 10_000));
System.out.println("Bogaci:");
grupy.get(true).forEach(emp -> {
System.out.printf(" * %s %s (%s), pensja: %s\n", emp.getFirstName(), emp.getLastName(), emp.getJobTitle(), emp.getSalary());
});
System.out.println("\nBiedni:");
grupy.get(false).forEach(emp -> {
System.out.printf(" * %s %s (%s), pensja: %s\n", emp.getFirstName(), emp.getLastName(), emp.getJobTitle(), emp.getSalary());
});
}
}
package p18_streamy;
import java.time.LocalTime;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
public class C01_Generowanie {
static int licznikStatyczny = 0;
public static void main(String[] args) {
Stream<String> str0 = Stream.empty();
str0.forEach(s -> System.out.print(s + ", "));
System.out.println();
Stream<String> str1 = Stream.of("Ala", "Ola", "Ela");
str1.forEach(s -> System.out.print(s + ", "));
System.out.println();
String[] tablica = {"Ala", "Ola", "Ula"};
Stream<String> str2 = Stream.of(tablica);
str2.forEach(s -> System.out.print(s + "; "));
System.out.println();
Stream.Builder<String> builder = Stream.builder();
Stream<String> str3 = builder.add("Ula").add("Ala").add("Ola").build();
str3.forEach(s -> System.out.print(s + ", "));
System.out.println();
System.out.println();
// Kolejny element strumienia generowany "bezkontekstowo" (bez żanego parametru)
Stream<LocalTime> czasy = Stream.generate(() -> LocalTime.now());
// to się zapętla:
// czasy.forEach(lt -> System.out.println(lt));
czasy.limit(20).forEach(lt -> System.out.println(lt));
//EXN przy probie kolejnego uzycia
// czasy.limit(30).forEach(lt -> System.out.println(lt));
System.out.println();
int licznikLokalny = 0;
// w wyrażeniu lambda nie wolno modyfikować zmiennych lokalnych ani używać zmieniających się zmiennych lokalnych
// int suma0 = IntStream.generate(() -> ++licznikLokalny).limit(10).sum();
int suma = IntStream.generate(() -> ++licznikStatyczny)
.filter(x -> x%2 == 1)
.limit(8)
.sum();
System.out.println(suma);
// Kolejny element generowany na podstawie poprzedniego
Stream<String> str4 = Stream.iterate("$", s -> s + "*");
// też nieskończony
str4.limit(10).forEach(System.out::println);
System.out.println();
// Przykład sensownych operacji na strumieniach nieskończonych:
IntStream parzyste = IntStream.iterate(0, x -> x+2);
IntStream nieparzyste = parzyste.map(x -> x+1);
int suma2 = nieparzyste.limit(9).sum();
System.out.println(suma2);
System.out.println();
IntStream.iterate(1, x -> x+2).limit(10).forEach(System.out::println);
System.out.println();
LongStream.iterate(1, x -> 2*x).limit(65).forEach(System.out::println);
System.out.println();
Stream<String> str11 = Stream.of("Ala", "Ola", "Ela");
Stream<String> str12 = Stream.of("Adam", "Ludwik", "Ksawery");
Stream<String> razem = Stream.concat(str11, str12);
razem.forEach(s -> System.out.print(s + ", "));
System.out.println();
}
}
package p18_streamy;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.Collator;
import java.util.Arrays;
import java.util.Random;
import java.util.stream.Stream;
public class C02_ZRoznychKlas {
public static void main(String[] args) {
Random random = new Random();
// nieskończony strumień losowych intów
random.ints();
random.ints().limit(100).forEach(System.out::println);
// przykład: utwórz tablicę 100 losowych int-ów:
int[] liczbyLosowe = random.ints().limit(100).toArray();
System.out.println(Arrays.toString(liczbyLosowe));
System.out.println();
//random.doubles();
int suma = random.ints(100, 0, 1000).sum();
System.out.println(suma);
System.out.println();
try {
// operacja "imperatywna":
// List<String> wczytaneLinie = Files.readAllLines(path);
// dostęp strumieniowy
// strumienie też można zamykać; ten należy zamykać
try(Stream<String> lines = Files.lines(Paths.get("pan-tadeusz.txt"))) {
lines.filter(s -> s.contains("Tadeusz"))
.sorted(Collator.getInstance())
.forEachOrdered(System.out::println);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println();
Path dir = Paths.get("src");
try {
Files.list(dir)
.forEach(f -> System.out.println(f + " " + Files.isRegularFile(f)));
} catch (IOException e) {
e.printStackTrace();
}
}
}
package p18_streamy;
import java.util.stream.Stream;
public class C11_FilterMap {
public static void main(String[] args) {
String[] imiona = {"Ala", "Ola", "Basia", "Kasia", "Ela", "Ula", "Agnieszka", "Magdalena", "Anna", "Hanna", "Joanna", "Ala", "Agata", "Genowefa", "Grażyna", "Karolina", "Julia", "Zuzanna"};
Stream.of(imiona)
.filter(s -> s.length() >= 5)
.forEach(System.out::println);
System.out.println();
Stream.of(imiona)
.map(String::toUpperCase)
.forEach(System.out::println);
System.out.println();
Stream.of(imiona)
.filter(s -> s.startsWith("A"))
.map(String::length) // Stream<String> -> Stream<Integer>
.forEach(System.out::println);
Stream.of(imiona)
.filter(s -> s.startsWith("A"))
.mapToInt(String::length) // Stream<String> -> IntStream
.forEach(System.out::println);
}
}
package p18_streamy;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class C12_FlatMap {
static List<Integer> generuj(int ilosc) {
List<Integer> lista = new ArrayList<>();
for(int i = 1; i <= ilosc; i++) {
lista.add(i);
}
return lista;
}
static Stream<Integer> generujStrumien(int ilosc) {
List<Integer> lista = new ArrayList<>();
for(int i = 1; i <= ilosc; i++) {
lista.add(i);
}
return lista.stream();
}
static IntStream generujStrumienIntow(int ilosc) {
List<Integer> lista = new ArrayList<>();
for(int i = 1; i <= ilosc; i++) {
lista.add(i);
}
return lista.stream().mapToInt(Integer::intValue);
}
public static void main(String[] args) {
System.out.println(generuj(1));
System.out.println(generuj(3));
System.out.println(generuj(5));
System.out.println();
System.out.println("Elementy strumienia wejściowego:");
Stream.of(1, 3, 5)
.forEach(x -> System.out.print(x + " | "));
System.out.println();
System.out.println();
System.out.println("Zwykłe mapowanie:");
Stream.of(1, 3, 5)
.map(C12_FlatMap::generuj)
.forEach(x -> System.out.print(x + " | "));
System.out.println();
Stream.of(1, 3, 5)
.map(x -> C12_FlatMap.generuj(x).stream())
.forEach(x -> System.out.print(x + " | "));
System.out.println();
System.out.println();
System.out.println("Płaskie mapowanie:");
Stream.of(1, 3, 5)
.flatMap(x -> C12_FlatMap.generuj(x).stream())
.forEach(x -> System.out.print(x + " | "));
System.out.println();
System.out.println();
Stream.of(1, 3, 5)
.flatMap(C12_FlatMap::generujStrumien)
.forEach(x -> System.out.print(x + " | "));
System.out.println();
System.out.println();
int suma = Stream.of(1, 3, 5)
.flatMapToInt(C12_FlatMap::generujStrumienIntow)
.sum();
System.out.println(suma);
}
}
package p18_streamy;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class C13_RozneOperacje {
public static void main(String[] args) {
String[] imiona = {"Ala", "Ola", "Basia", "Kasia", "Ela", "Ula", "Agnieszka", "Magdalena", "Anna", "Hanna", "Joanna", "Ala", "Agata", "Genowefa", "Grażyna", "Karolina", "Julia", "Zuzanna"};
// ** operacje terminujące ** //
// forEach - dla każdego elementu wykonaj akcję
Stream.of(imiona).forEach(s -> System.out.println(s));
// forEachOrdered - dla każdego elementu wykonaj akcję zachowując kolejność (istotne dla parallelStream)
Stream.of(imiona).forEachOrdered(s -> System.out.println(s));
System.out.println("\n--------------------------------\n");
// count() - liczba elementów strumienia (też wymaga pobrania elementów !)
long n = Stream.of(imiona).count();
System.out.println("count: " + n);
// toArray - tworzy nową tablicę i wstawia tam elementy
Object[] array1 = Stream.of(imiona)
.map(String::toLowerCase)
.toArray();
System.out.println(array1 + " , length="+array1.length);
System.out.println(Arrays.toString(array1));
System.out.println();
// inna wersja: podajemy funkcję tworzącą tablice; korzyść: dostajemy String[] a nie Object[]
String[] array2 = Stream.of(imiona)
.sorted()
.toArray(String[]::new);
System.out.println(array2 + " , length="+array2.length);
System.out.println(Arrays.toString(array2));
System.out.println("\n--------------------------------\n");
// reduce - redukcja w sposób właściwy dla klas niemutowalnych
Optional<String> wynik01 = Stream.of(imiona)
.reduce(String::concat);
System.out.println("wynik01: " + wynik01);
String wynik02 = Stream.of(imiona)
.reduce("", String::concat);
System.out.println("wynik02: " + wynik02);
String wynik03 = Stream.of(imiona)
.reduce("|", String::concat);
System.out.println("wynik03: " + wynik03);
String wynik04 = Stream.of(imiona)
.parallel()
.reduce("|", String::concat);
System.out.println("wynik04: " + wynik04);
// Takie użycie concat jest niewydaje i tego nie naśladujcie
// wersja, w której typ wyniku może być inny niż typ elementów
// tu przykład sumowania długości napisów
Integer wynik05 = Stream.of(imiona)
.reduce(0, (x, s) -> x+s.length(), (x,y)->x+y);
System.out.println("wynik05: " + wynik05);
System.out.println();
// collect - redukcja w sposób właściwy dla klas mutowalnych
StringBuilder wynik06 = Stream.of(imiona).collect(
StringBuilder::new, // supplier - tworzy początkową "pusta" wartość
StringBuilder::append, // accumulator - aktualizuje wartość na podstawie elementu strumienia
StringBuilder::append); // combiner - łączy częściowe wyniki (które mogą się pojawić gdy mamy parallelStream)
System.out.println("wynik06: " + wynik06);
List<String> lista = Stream.of(imiona)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(lista);
System.out.println("\n--------------------------------\n");
// findFirst i findAny - wybór jednego elementu
// findAny zwraca "jakikolwiek" - ale to nie znaczy "losowy"
// po prostu implementacja zwróci ten, do którego ma najszybszy dostęp
Optional<String> wynik07 = Stream.of(imiona).findFirst();
Optional<String> wynik08 = Stream.of(imiona).findAny();
Optional<String> wynik09 = Stream.of(imiona).parallel().findAny(); // niedeterministyczne, czasami była Ala a czasami Ula
// jest szansa na zobaczenie innego imienia niż Ala :)
System.out.println("findFirst : " + wynik07);
System.out.println("findAny : " + wynik08);
System.out.println("findAny par: " + wynik09);
System.out.println();
// kwantyfikatory logiczne - zwracają true albo false
// działają w sposób leniwy - przestają pobierać kolejne elementy strumienia jeśli wynik jest rozstrzygnięty
boolean bool1 = Stream.of(imiona).allMatch(s -> s.endsWith("a"));
System.out.println("bool1 = " + bool1);
boolean bool2 = Stream.of(imiona).allMatch(s -> s.startsWith("K"));
System.out.println("bool2 = " + bool2);
boolean bool3 = Stream.of(imiona).anyMatch(s -> s.startsWith("K"));
System.out.println("bool3 = " + bool3);
boolean bool4 = Stream.of(imiona).noneMatch(s -> s.startsWith("K"));
System.out.println("bool4 = " + bool4);
}
}
package p18_streamy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class C21_DistinctSorted {
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa", "Ola",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
// distinct i sorted to są opearacje "stateful intermediate"
// one są wykonywane dopiero gdy na strumieniu jest odpalona operacja terminalna
// ale mogą wymagać zebrania większej ilości danych (nawet wszystkich) przed przepuszczeniem elementów do dalszych etapów przetwarzania
// Wynika z tego, że nie powinny być stosowane do strumieni nieskończonych.
String napis = lista.stream()
.distinct()
.map(String::toUpperCase)
.sorted()
.collect(Collectors.joining(", "));
System.out.println(napis);
}
}
package p18_streamy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class C22_DistinctSorted {
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Ala", "Magdalena", "Ola", "Joanna", "Anna", "Teresa", "Ola",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
// distinct i sorted to są opearacje "stateful intermediate"
// one są wykonywane dopiero gdy na strumieniu jest odpalona operacja terminalna
// ale mogą wymagać zebrania większej ilości danych (nawet wszystkich) przed przepuszczeniem elementów do dalszych etapów przetwarzania
// Wynika z tego, że nie powinny być stosowane do strumieni nieskończonych.
String napis = lista.stream()
.map(String::toUpperCase)
.peek(s -> System.out.println("start " + s))
.distinct()
.peek(s -> System.out.println("za distinct " + s))
.sorted()
.peek(s -> System.out.println("za sorted " + s))
.collect(Collectors.joining(", "));
System.out.println();
System.out.println(napis);
}
}
package p18_streamy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class C23_DistinctSorted {
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Ala", "Magdalena", "Ola", "Joanna", "Anna", "Teresa", "Ola",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
// distinct i sorted to są opearacje "stateful intermediate"
// one są wykonywane dopiero gdy na strumieniu jest odpalona operacja terminalna
// ale mogą wymagać zebrania większej ilości danych (nawet wszystkich) przed przepuszczeniem elementów do dalszych etapów przetwarzania
// Wynika z tego, że nie powinny być stosowane do strumieni nieskończonych.
String napis = lista.parallelStream()
.map(String::toUpperCase)
.peek(s -> System.out.println("start " + s))
.distinct()
.peek(s -> System.out.println("za distinct " + s))
.sorted()
.peek(s -> System.out.println("za sorted " + s))
.collect(Collectors.joining(", "));
System.out.println();
System.out.println(napis);
}
}
package p18_streamy;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
public class C31_TypyProste {
public static void main(String[] args) {
DoubleStream losowe = DoubleStream.generate(Math::random);
losowe.limit(100).forEach(x -> System.out.print(x + ", "));
System.out.println();
Random random = new Random();
double sumaLosowych1 = random.doubles().limit(10).sum();
System.out.println(sumaLosowych1);
random.ints(10, 100, 200).forEach(x -> System.out.print(x + ", "));
System.out.println();
LongStream potegi = LongStream.iterate(1, x -> x*2);
potegi.limit(65).forEach(x -> System.out.println(x));
System.out.println();
IntStream.range(0, 10).forEach(x -> System.out.print(x + ", "));
System.out.println();
IntStream.rangeClosed(0, 10).forEach(x -> System.out.print(x + ", "));
IntStream str_int = IntStream.rangeClosed(0, 10);
// tłumaczenie między strumieniem intów a strumieniem Integerów:
Stream<Integer> str_Integer = str_int.boxed();
IntStream str_int2 = str_Integer.mapToInt(Integer::intValue);
// IntStream str_int3 = str_Integer.mapToInt(x -> x);
List<Integer> liczby = IntStream.range(0, 100)
.map(i -> i*i)
.boxed() // zmienia IntStream na Stream<Integer>
.collect(Collectors.toList());
System.out.println(liczby);
}
}
package p18_streamy;
import java.util.stream.Stream;
/* collect i reduce to dwa schematy służące do agregacji danych strumienia,
* czyli "zbierania danych" tak, aby na podstawie całego zestawu danych uzyskać pojedynczy wynik.
*
* collect i Collectory - schemat agregacji wykorzystujący klasy mutowalne,
* jako krok operacji podaje się metodę typu void
*
* reduce - schemat agregacji wykorzystujący klasy niemutowalne lub wartości liczbowe
* jako krok operacji podaje się metodę zwracającą wynik
*/
public class Collect_i_Reduce {
public static void main(String[] args) {
String[] imiona = {"Ala", "Ola", "Ela"};
{
StringBuilder wynik = Stream.of(imiona).collect(
StringBuilder::new, // supplier - tworzy początkową "pustą" wartość
StringBuilder::append, // accumulator - aktualizuje wartość na podstawie elementu strumienia
StringBuilder::append); // combiner - łączy częściowe wyniki (które mogą się pojawić gdy mamy parallelStream)
System.out.println("1: " +wynik);
}
// w przypadku strumienia sekwencyjnego można to przetłumaczyć na taką pętlę:
{
StringBuilder wynik = new StringBuilder();
for (String s : imiona) {
wynik.append(s); // tylko wywołanie, wynik tej metody nie jest brany pod uwagę, może być void
}
System.out.println("2: " + wynik);
}
// #################
// Klasa, o którą się opieramy, musi być mutowalna, a operacja (w tym przypadku append)
// musi zmieniać obiekt, na którym jest wołana
// To nie zadziała:
{
String wynik = Stream.of(imiona).collect(
String::new,
String::concat, // concat nie zmienia Strina, na którym jest wołany - więc nie będzie efektu
String::concat);
System.out.println("3: " + wynik);
}
// Dla klas niemutowalnych (i typów prostych) właściwym schematem jest reduce:
{
String wynik = Stream.of(imiona).reduce(
"",
String::concat);
System.out.println("4: " + wynik);
}
// to tłumaczy się na taką pętlę:
{
String wynik = "";
for (String s : imiona) {
wynik = wynik.concat(s); // przypisanie / podmiana wyniku !!!
}
System.out.println("5: " + wynik);
}
// Gdyby "combiner" częściowych wyników różnił się od "accumulatora" pojedynczych wartości,
// podajemy go jako trzeci parametr
{
String wynik = Stream.of(imiona).reduce(
"",
String::concat,
String::concat);
System.out.println("6: " + wynik);
}
// Tu jest taka sytuacja, bo na wejściu mamy strumień Stringów,
// a wynikiem jest int
// pierwsza funkcja jest typu (int, String) -> int
// a druga jest typu (int, int) -> int
{
int wynik = Stream.of(imiona).reduce(
0,
(suma, str) -> suma + str.length(),
Math::addExact);
System.out.println("7: " + wynik);
}
// te ostatnie funkcje ("combiner") są używane tylko gdy parallelStream
}
}
package p18_streamy;
import java.util.Collections;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
/* Przykład własnej definicji Collectora.
* Tylko, aby pokazać, jak one działają.
* Collector o funkcjonalności łączenia napisów istnieje: Collectors.joining();
*/
public class CollectorLaczacyNapisy implements Collector<String, StringBuilder, String> {
@Override
public Supplier<StringBuilder> supplier() {
// nie tak: return new StringBullder();
return StringBuilder::new;
}
@Override
public BiConsumer<StringBuilder, String> accumulator() {
return StringBuilder::append; // append(String)
}
@Override
public BinaryOperator<StringBuilder> combiner() {
return StringBuilder::append; // append(StringBuilder)
}
@Override
public Function<StringBuilder, String> finisher() {
return StringBuilder::toString;
}
@Override
public Set<Characteristics> characteristics() {
return Collections.emptySet();
}
}
package p18_streamy;
import java.util.stream.Collector;
import java.util.stream.Stream;
public class Collector_Test {
public static void main(String[] args) {
String[] imiona = {"Ala", "Ola", "Ela"};
CollectorLaczacyNapisy collector1 = new CollectorLaczacyNapisy();
String wynik1 = Stream.of(imiona).collect(collector1);
System.out.println(wynik1);
// Ale to samo można zrobić bezpośrednio w kodzie:
// Najpierw wersja, że akumulator staje się wynikiem - nie ma funkcji finisher
Collector<String, StringBuilder, StringBuilder> collector2 =
Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append);
StringBuilder wynik2 = Stream.of(imiona).collect(collector2);
System.out.println(wynik2);
// Dodaję finisher równy StringBuilder.toString - ostateczny wynik typu String
Collector<String, StringBuilder, String> collector3 =
Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString);
String wynik3 = Stream.of(imiona).collect(collector3);
System.out.println(wynik3);
}
}
package p18_streamy;
import java.math.BigInteger;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class Silnia_Reduce {
static long silniaFun(int n) {
return LongStream.rangeClosed(2, n)
.reduce(1L, (a, i) -> a * i);
}
static long silniaKlasyczna(int n) {
// działa jak taka pętla:
long a = 1L;
for(int i = 2; i <= n; i++) {
a = a * i;
}
return a;
}
static long silniaFun2(int n) {
return LongStream.rangeClosed(2, n)
.reduce(1, Math::multiplyExact);
}
static BigInteger silniaFunBig(int n) {
return IntStream.rangeClosed(2, n)
.mapToObj(BigInteger::valueOf)
.reduce(BigInteger.ONE, BigInteger::multiply);
}
public static void main(String[] args) {
System.out.println(silniaFun(5));
System.out.println(silniaFun2(5));
try {
System.out.println(silniaFun2(21));
} catch (Exception e) {
System.out.println("overflow");
}
System.out.println(silniaFunBig(5));
System.out.println(silniaFunBig(100));
}
}
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