Commit 6dd95496 by Patryk Czarnik

Gotowe przykłady

parent 442b2d06
package emps;
import java.util.List;
public class F9_Kwantyfikatory {
public static void main(String[] args) {
List<Employee> emps = ObslugaCSV.wczytaj("emps.csv");
// czy istnieje pracownik zarabiający 10 tys?
if(emps.stream().anyMatch(emp -> emp.getSalary() == 10_000)) {
System.out.println("A istnieje");
} else {
System.out.println("A nie istnieje");
}
// czy wszyscy pracownicy zarabiają co najmniej 3 tys?
if(emps.stream().allMatch(emp -> emp.getSalary() >= 3000)) {
System.out.println("B prawda");
} else {
System.out.println("B nieprawda");
}
// czy wszyscy programiści zarabiają co namjniej 3 tys?
boolean b3 = emps.stream()
.filter(emp -> "Programmer".equals(emp.getJobTitle()))
.allMatch(emp -> emp.getSalary() >= 3000);
if(b3) {
System.out.println("C prawda");
} else {
System.out.println("C nieprawda");
}
}
}
package p10_metody_klasy_object.finalizacja;
public class Konto {
final int numer;
int saldo;
Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ", " + saldo + ", wł." + wlasciciel;
}
void wplata(int kwota) {
saldo += kwota;
}
void wyplata(int kwota) {
saldo -= kwota;
}
static void przelew(Konto nadawca, Konto odbiorca, int kwota) {
nadawca.saldo -= kwota;
odbiorca.saldo += kwota;
}
void przelew(Konto odbiorca, int kwota) {
this.saldo -= kwota;
odbiorca.saldo += kwota;
}
@Override
protected void finalize() {
// to co tu wpiszemy, zostanie uruchomione tuż przed usunięciem obiektu przez GC
System.out.println("finalize Konto nr " + numer);
}
}
package p10_metody_klasy_object.finalizacja;
import java.time.LocalDate;
import java.time.Period;
public class Osoba {
// zmienne przechowywane w obiektach: pola (field), atrybuty (attribute), zmienne instancyjne (instance variable)
String imie, nazwisko;
LocalDate dataUrodzenia;
Osoba() {
}
Osoba(String imie, String nazwisko, LocalDate data) {
this.imie = imie;
this.nazwisko = nazwisko;
dataUrodzenia = data;
}
Osoba(String imie, String nazwisko, String data) {
this(imie, nazwisko, LocalDate.parse(data));
}
// metody - operacje, które "potrafi" wykonać obiekt
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + getWiek() + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " ur." + dataUrodzenia;
}
public int getWiek() {
if(dataUrodzenia == null) {
return -1;
}
Period czasZycia = Period.between(dataUrodzenia, LocalDate.now());
return czasZycia.getYears();
}
@Override
protected void finalize() {
System.out.println("finalize Osoba " + imie);
}
}
package p10_metody_klasy_object.finalizacja;
public class Usuwanie1 {
public static void main(String[] args) {
System.out.println("Tworzymy dużo obiektów");
Osoba osoba = new Osoba("Ala", "Kowalska", "1993-04-05");
for(int i = 0; i < 100; i++) {
Konto k = new Konto(i, 1000+i, osoba);
// od tego miejsca już z tego Konta nie korzystam
}
osoba = null;
System.out.println("Gotowe...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
// nie zobaczymy finalize
System.out.println("Koniec programu");
}
}
package p10_metody_klasy_object.finalizacja;
public class Usuwanie2_OutOfMemory {
public static void main(String[] args) {
System.out.println("Tworzymy dużo obiektów");
Osoba osoba = new Osoba("Ala", "Kowalska", "1993-04-05");
for(int i = 0; i < 100; i++) {
Konto k = new Konto(i, 1000+i, osoba);
// od tego miejsca już z tego Konta nie korzystam
}
osoba = null;
System.out.println("Gotowe...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("Alokuję dużą tablicę");
try {
long[] t = new long[1000_000_000]; // 8G pamięci
System.out.println("mam tablicę");
} catch (OutOfMemoryError e) {
System.err.println("brak pamięci");
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("Koniec programu");
}
}
package p10_metody_klasy_object.finalizacja;
public class Usuwanie3_gc {
public static void main(String[] args) {
System.out.println("Tworzymy dużo obiektów");
for(int i = 0; i < 100; i++) {
Konto k = new Konto(i, 1000+i, null);
// od tego miejsca już z tego Konta nie korzystam
}
System.out.println("Gotowe...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("Wywołuję System.gc()");
System.gc();
System.out.println("wywołałem");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("Koniec programu");
}
}
package p10_metody_klasy_object.finalizacja;
import java.util.LinkedList;
import java.util.List;
public class Usuwanie4_Lista {
public static void main(String[] args) {
Osoba osoba = new Osoba("Ala", "Kowalska", "1993-04-05");
List<Konto> lista = new LinkedList<>();
for(int i = 1; i <= 100; i++) {
Konto k = new Konto(i, 100*i, osoba);
lista.add(k);
}
System.out.println("Konta utworzone");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
osoba = null;
System.out.println("Odpalam GC");
System.gc();
System.out.println("GC odpalone");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println(lista.get(50));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("Zapominam o liście i ponownie robię GC");
lista = null;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.gc();
System.out.println("GC odpalone");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("koniec");
}
}
package p10_metody_klasy_object.finalizacja;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
public class Usuwanie5_Weak {
public static void main(String[] args) {
Osoba osoba = new Osoba("Ala", "Kowalska", "1993-04-05");
List<WeakReference<Konto>> lista = new LinkedList<>();
for(int i = 1; i <= 100; i++) {
Konto k = new Konto(i, 100*i, osoba);
lista.add(new WeakReference<Konto>(k));
}
System.out.println("Konta utworzone");
System.out.println("przykładowe konto: " + lista.get(50).get());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
osoba = null;
System.out.println("Odpalam GC");
System.gc();
System.out.println("GC odpalone\n");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("teraz odczyt konta: " + lista.get(50).get());
System.out.println("koniec");
}
}
package p10_metody_klasy_object.klonowanie1;
public class Konto implements Cloneable {
final int numer;
int saldo;
Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ", " + saldo + ", wł." + wlasciciel;
}
void wplata(int kwota) {
saldo += kwota;
}
void wyplata(int kwota) {
saldo -= kwota;
}
static void przelew(Konto nadawca, Konto odbiorca, int kwota) {
nadawca.saldo -= kwota;
odbiorca.saldo += kwota;
}
void przelew(Konto odbiorca, int kwota) {
this.saldo -= kwota;
odbiorca.saldo += kwota;
}
/* W tej wersji korzystam z domyślnej implementacji clone(), tylko ją upubliczniam.
*/
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package p10_metody_klasy_object.klonowanie1;
import java.time.LocalDate;
import java.time.Period;
public class Osoba implements Cloneable {
// zmienne przechowywane w obiektach: pola (field), atrybuty (attribute), zmienne instancyjne (instance variable)
String imie, nazwisko;
LocalDate dataUrodzenia;
Osoba() {
}
Osoba(String imie, String nazwisko, LocalDate data) {
this.imie = imie;
this.nazwisko = nazwisko;
dataUrodzenia = data;
}
Osoba(String imie, String nazwisko, String data) {
this(imie, nazwisko, LocalDate.parse(data));
}
// metody - operacje, które "potrafi" wykonać obiekt
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + getWiek() + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " ur." + dataUrodzenia;
}
public int getWiek() {
if(dataUrodzenia == null) {
return -1;
}
Period czasZycia = Period.between(dataUrodzenia, LocalDate.now());
return czasZycia.getYears();
}
@Override
public Osoba clone() {
try {
return (Osoba) super.clone();
} catch (CloneNotSupportedException e) {
// should never happen
throw new RuntimeException(e);
}
}
}
package p10_metody_klasy_object.klonowanie1;
public class TestKlonowania {
public static void main(String[] args) {
// Użycie domyślnej wersji clone wymaga rzutowania obiektu na właściwy typ i obsłużenia wyjątku CloneNotSupportedException
try {
Osoba ala = new Osoba("Ala", "Kowalska", "2001-02-03");
Konto konto = new Konto(1, 1000, ala);
Konto klon;
klon = (Konto) konto.clone();
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
klon.wplata(300);
klon.wlasciciel.imie = "Alicja";
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
package p10_metody_klasy_object.klonowanie2;
public class Konto implements Cloneable {
final int numer;
int saldo;
Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ", " + saldo + ", wł." + wlasciciel;
}
void wplata(int kwota) {
saldo += kwota;
}
void wyplata(int kwota) {
saldo -= kwota;
}
static void przelew(Konto nadawca, Konto odbiorca, int kwota) {
nadawca.saldo -= kwota;
odbiorca.saldo += kwota;
}
void przelew(Konto odbiorca, int kwota) {
this.saldo -= kwota;
odbiorca.saldo += kwota;
}
/* W tej wersji korzystam z domyślnej implementacji clone()
* upubliczniając ją i dostosowując do łatwiego używania (zmiana typu, bez deklarowanego wyjątku).
* Domyślnie tworzy to płytką kopię.
* Wg mnie wygląda to paskudnie.
*/
@Override
public Konto clone() {
try {
return (Konto)super.clone();
} catch (CloneNotSupportedException e) {
// should never happen
throw new RuntimeException(e);
}
}
}
package p10_metody_klasy_object.klonowanie2;
import java.time.LocalDate;
import java.time.Period;
public class Osoba implements Cloneable {
// zmienne przechowywane w obiektach: pola (field), atrybuty (attribute), zmienne instancyjne (instance variable)
String imie, nazwisko;
LocalDate dataUrodzenia;
Osoba() {
}
Osoba(String imie, String nazwisko, LocalDate data) {
this.imie = imie;
this.nazwisko = nazwisko;
dataUrodzenia = data;
}
Osoba(String imie, String nazwisko, String data) {
this(imie, nazwisko, LocalDate.parse(data));
}
// metody - operacje, które "potrafi" wykonać obiekt
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + getWiek() + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " ur." + dataUrodzenia;
}
public int getWiek() {
if(dataUrodzenia == null) {
return -1;
}
Period czasZycia = Period.between(dataUrodzenia, LocalDate.now());
return czasZycia.getYears();
}
@Override
public Osoba clone() {
try {
return (Osoba) super.clone();
} catch (CloneNotSupportedException e) {
// should never happen
throw new RuntimeException(e);
}
}
}
package p10_metody_klasy_object.klonowanie2;
public class TestKlonowania {
public static void main(String[] args) {
Osoba ala = new Osoba("Ala", "Kowalska", "2001-02-03");
Konto konto = new Konto(1, 1000, ala);
Konto klon = konto.clone();
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
klon.wplata(300);
klon.wlasciciel.imie = "Alicja";
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
}
}
package p10_metody_klasy_object.klonowanie3;
public class Konto implements Cloneable {
final int numer;
int saldo;
Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ", " + saldo + ", wł." + wlasciciel;
}
void wplata(int kwota) {
saldo += kwota;
}
void wyplata(int kwota) {
saldo -= kwota;
}
static void przelew(Konto nadawca, Konto odbiorca, int kwota) {
nadawca.saldo -= kwota;
odbiorca.saldo += kwota;
}
void przelew(Konto odbiorca, int kwota) {
this.saldo -= kwota;
odbiorca.saldo += kwota;
}
/* W tej wersji korzystam z domyślnej implementacji clone()
* upubliczniając ją i dostosowując do łatwiego używania (zmiana typu, bez deklarowanego wyjątku).
* Ponadto staram się, aby clone() tworzył głęboką kopię - zmieniam pole wlasciciel.
* Nie ma natomiast potrzeby klonować pól, które są klas niemutowalnych (String, LocalDate itp.).
*/
@Override
public Konto clone() {
try {
Konto klon = (Konto) super.clone();
klon.wlasciciel = wlasciciel.clone();
return klon;
} catch (CloneNotSupportedException e) {
// should never happen
throw new RuntimeException(e);
}
}
}
package p10_metody_klasy_object.klonowanie3;
import java.time.LocalDate;
import java.time.Period;
public class Osoba implements Cloneable {
// zmienne przechowywane w obiektach: pola (field), atrybuty (attribute), zmienne instancyjne (instance variable)
String imie, nazwisko;
LocalDate dataUrodzenia;
Osoba() {
}
Osoba(String imie, String nazwisko, LocalDate data) {
this.imie = imie;
this.nazwisko = nazwisko;
dataUrodzenia = data;
}
Osoba(String imie, String nazwisko, String data) {
this(imie, nazwisko, LocalDate.parse(data));
}
// metody - operacje, które "potrafi" wykonać obiekt
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + getWiek() + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " ur." + dataUrodzenia;
}
public int getWiek() {
if(dataUrodzenia == null) {
return -1;
}
Period czasZycia = Period.between(dataUrodzenia, LocalDate.now());
return czasZycia.getYears();
}
@Override
public Osoba clone() {
try {
return (Osoba) super.clone();
} catch (CloneNotSupportedException e) {
// should never happen
throw new RuntimeException(e);
}
}
}
package p10_metody_klasy_object.klonowanie3;
public class TestKlonowania {
public static void main(String[] args) {
Osoba ala = new Osoba("Ala", "Kowalska", "2001-02-03");
Konto konto = new Konto(1, 1000, ala);
Konto klon = konto.clone();
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
klon.wplata(300);
klon.wlasciciel.imie = "Alicja";
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
}
}
package p10_metody_klasy_object.klonowanie4;
public class Konto implements Cloneable {
final int numer;
int saldo;
Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ", " + saldo + ", wł." + wlasciciel;
}
void wplata(int kwota) {
saldo += kwota;
}
void wyplata(int kwota) {
saldo -= kwota;
}
static void przelew(Konto nadawca, Konto odbiorca, int kwota) {
nadawca.saldo -= kwota;
odbiorca.saldo += kwota;
}
void przelew(Konto odbiorca, int kwota) {
this.saldo -= kwota;
odbiorca.saldo += kwota;
}
/* W tej wersji tworzę własną implementację clone() za pomocą konstruktora.
* Wg mnie wygląda to znacznie lepiej.
* W tej wersji od razu głęboka kopia.
*/
@Override
public Konto clone() {
return new Konto(this.numer, this.saldo, this.wlasciciel.clone());
}
}
package p10_metody_klasy_object.klonowanie4;
import java.time.LocalDate;
import java.time.Period;
public class Osoba implements Cloneable {
// zmienne przechowywane w obiektach: pola (field), atrybuty (attribute), zmienne instancyjne (instance variable)
String imie, nazwisko;
LocalDate dataUrodzenia;
Osoba() {
}
Osoba(String imie, String nazwisko, LocalDate data) {
this.imie = imie;
this.nazwisko = nazwisko;
dataUrodzenia = data;
}
Osoba(String imie, String nazwisko, String data) {
this(imie, nazwisko, LocalDate.parse(data));
}
// metody - operacje, które "potrafi" wykonać obiekt
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + getWiek() + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " ur." + dataUrodzenia;
}
public int getWiek() {
if(dataUrodzenia == null) {
return -1;
}
Period czasZycia = Period.between(dataUrodzenia, LocalDate.now());
return czasZycia.getYears();
}
@Override
protected Osoba clone() {
return new Osoba(imie, nazwisko, dataUrodzenia);
// String i LocalDate nie trzeba już klonować, ponieważ są to klasy immutable
}
}
package p10_metody_klasy_object.klonowanie4;
public class TestKlonowania {
public static void main(String[] args) {
Osoba ala = new Osoba("Ala", "Kowalska", "2001-02-03");
Konto konto = new Konto(1, 1000, ala);
Konto klon = konto.clone();
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
klon.wplata(300);
klon.wlasciciel.imie = "Alicja";
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
}
}
package p10_metody_klasy_object.porownywanie;
class A {
int x, y;
public A(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "( " + x + "," + y +")";
}
}
public class Porownywanie1 {
public static void main(String[] args) {
A a1 = new A(10, 20);
A a2 = new A(10, 20);
A a3 = new A(10, 30);
System.out.println(a1 == a2);
System.out.println(a1 == a3);
System.out.println();
System.out.println(a1.equals(a2));
System.out.println(a1.equals(a3));
}
}
package p10_metody_klasy_object.porownywanie;
import java.util.HashSet;
// Ta wersja nie nadpisuje equals! Tylko dodaje inną metodę
class B {
int x, y;
public B(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "(" + x + "," + y +")";
}
public boolean equals(B that) {
return this.x == that.x && this.y == that.y;
}
public int hashCode() {
return 0;
}
}
public class Porownywanie2 {
public static void main(String[] args) {
B b1 = new B(10, 20);
B b2 = new B(10, 20);
B b3 = new B(10, 30);
System.out.println(b1.toString());
System.out.println(b2.toString());
System.out.println(b3.toString());
System.out.println(b1 == b2);
System.out.println(b1 == b3);
System.out.println();
// chociaż nieprawidłowo zaimplementowałem equals w klasie B, to ten test działa
System.out.println(b1.equals(b2));
System.out.println(b1.equals(b3));
System.out.println();
Object o1 = b1;
Object o2 = b2;
Object o3 = b3;
System.out.println(o1.equals(o2)); // tu działa wersja z Object
System.out.println(o1.equals(o3));
System.out.println();
HashSet<B> zbior = new HashSet<>();
zbior.add(b1);
zbior.add(b2);
zbior.add(b3);
System.out.println(zbior.size());
System.out.println(zbior);
}
}
package p10_metody_klasy_object.porownywanie;
import java.util.HashSet;
class C {
int x, y;
public C(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "(" + x + "," + y +")";
}
@Override
public boolean equals(Object o) {
if(o instanceof C) {
C that = (C)o;
return this.x == that.x && this.y == that.y;
} else {
return false;
}
}
@Override
public int hashCode() {
// taki hashCode jest poprawny, w tym sensie, że spełnia minimalne wymagania kontraktu
// zazwyczaj taka implementacja jest niewydajna i w praktyce tak się nie robi
return 0;
}
}
public class Porownywanie3 {
public static void main(String[] args) {
C c1 = new C(10, 20);
C c2 = new C(10, 20);
C c3 = new C(10, 30);
System.out.println(c1.toString());
System.out.println(c2.toString());
System.out.println(c3.toString());
System.out.println(c1 == c2);
System.out.println(c1 == c3);
System.out.println();
// chociaż nieprawidłowo zaimplementowałem equals w klasie B, to ten test działa
System.out.println(c1.equals(c2));
System.out.println(c1.equals(c3));
System.out.println();
Object o1 = c1;
Object o2 = c2;
Object o3 = c3;
System.out.println(o1.equals(o2)); // tu działa wersja z Object
System.out.println(o1.equals(o3));
System.out.println();
HashSet<C> zbior = new HashSet<>();
zbior.add(c1);
zbior.add(c2);
zbior.add(c3);
System.out.println(zbior.size());
System.out.println(zbior);
}
}
package p10_metody_klasy_object.porownywanie;
import java.util.HashSet;
class D {
int x, y;
public D(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "(" + x + "," + y +")";
}
@Override
public boolean equals(Object o) {
if(o instanceof D) {
D that = (D)o;
return this.x == that.x && this.y == that.y;
} else {
return false;
}
}
@Override
public int hashCode() {
// poprawnym hashCode będzie każdy, który do uzyskania wyniku używa wyłącznie wartości porównywanych w equals
return x*y;
}
}
public class Porownywanie4 {
public static void main(String[] args) {
D d1 = new D(10, 20);
D d2 = new D(10, 20);
D d3 = new D(10, 30);
System.out.println(d1.toString());
System.out.println(d2.toString());
System.out.println(d3.toString());
System.out.println(d1 == d2);
System.out.println(d1 == d3);
System.out.println();
// chociaż nieprawidłowo zaimplementowałem equals w klasie B, to ten test działa
System.out.println(d1.equals(d2));
System.out.println(d1.equals(d3));
System.out.println();
Object o1 = d1;
Object o2 = d2;
Object o3 = d3;
System.out.println(o1.equals(o2)); // tu działa wersja z Object
System.out.println(o1.equals(o3));
System.out.println();
HashSet<D> zbior = new HashSet<>();
zbior.add(d1);
zbior.add(d2);
zbior.add(d3);
System.out.println(zbior.size());
System.out.println(zbior);
}
}
package p13_lambdy.v1;
public interface FunkcjaLiczbowa {
double oblicz(double arg);
}
package p13_lambdy.v1;
public class Lambdy1 {
public static void main(String[] args) {
FunkcjaLiczbowa f1 = (double arg) -> {
System.out.println("liczę i liczę...");
return arg + 100;
};
System.out.println(f1.oblicz(13));
System.out.println(f1.oblicz(77));
System.out.println();
FunkcjaLiczbowa f2 = x -> x*x;
System.out.println(f2.oblicz(5.0));
System.out.println(f2.oblicz(12.5));
// Oprócz wyrażeń lambda, funkcje można wskazywać także za pomocą "method reference"
FunkcjaLiczbowa f3 = Math::sqrt;
System.out.println(f3.oblicz(36));
FunkcjaLiczbowa f4 = x -> Math.sqrt(x);
System.out.println(f4.oblicz(36));
System.out.println();
}
}
package p13_lambdy.v1;
public class Lambdy2 {
public static void main(String[] args) {
FunkcjaLiczbowa f2 = x -> x*x;
System.out.println(f2.oblicz(5.0));
System.out.println(f2.oblicz(12.5));
// Technicznie: w f1 i f2 są wpisane OBIEKTY
Object o = f2;
System.out.println(o);
// Są to obiekty klas generowanych automatycznie,
// te klasy implementują interfejs FunkcjaLiczbowa.
System.out.println(f2.getClass());
if(f2 instanceof FunkcjaLiczbowa) {
System.out.println("Jest instancją");
} else {
System.out.println("Nie jest instancją");
}
// Podczas kompilacji z kontekstu musi wynikać do jakiego interfejsu ma być dopasowana dana lambda.
// Object o2 = x -> 100*x + 13;
// Object o3 = (double x) -> {return 100*x + 13;};
}
}
package p13_lambdy.v1;
public class TradycyjneUzycieInterfejsu {
public static void main(String[] args) {
ZwyklaImplementacja f1 = new ZwyklaImplementacja();
System.out.println( f1.oblicz(1.0) );
System.out.println( f1.oblicz(1.5) );
// obiekt klasy implementującej interfejs mogę zapisać na zmienną typu interfejs
FunkcjaLiczbowa f2 = new ZwyklaImplementacja();
System.out.println( f2.oblicz(2.0) );
// Przed Javą 8 najbardziej zwięzłym sposobem na utworzenie obiektu zgodnego z interfejsem
// była "klasa anonimowa":
FunkcjaLiczbowa f3 = new FunkcjaLiczbowa() {
public double oblicz(double x) {
return x*x*x;
}
};
System.out.println( f3.oblicz(3.0) );
}
}
package p13_lambdy.v1;
public class ZwyklaImplementacja implements FunkcjaLiczbowa {
@Override
public double oblicz(double arg) {
return arg*arg;
}
}
package p13_lambdy.v2;
@FunctionalInterface
public interface FunkcjaLiczbowa {
double oblicz(double arg);
default String nazwa() {
return "moja funkcja";
}
}
package p13_lambdy.v2;
public class Lambdy1 {
public static void main(String[] args) {
FunkcjaLiczbowa f1 = (double arg) -> {
System.out.println("liczę i liczę...");
return arg + 100;
};
System.out.println(f1.oblicz(13));
System.out.println(f1.oblicz(77));
System.out.println();
FunkcjaLiczbowa f2 = x -> x*x;
System.out.println(f2.oblicz(5.0));
System.out.println(f2.oblicz(12.5));
// Oprócz wyrażeń lambda, funkcje można wskazywać także za pomocą "method reference"
FunkcjaLiczbowa f3 = Math::sqrt;
System.out.println(f3.oblicz(36));
FunkcjaLiczbowa f4 = x -> Math.sqrt(x);
System.out.println(f4.oblicz(36));
System.out.println();
}
}
package p13_lambdy.v2;
public class Lambdy2 {
public static void main(String[] args) {
FunkcjaLiczbowa f2 = x -> x*x;
System.out.println(f2.oblicz(5.0));
System.out.println(f2.oblicz(12.5));
// Technicznie: w f1 i f2 są wpisane OBIEKTY
Object o = f2;
System.out.println(o);
// Są to obiekty klas generowanych automatycznie,
// te klasy implementują interfejs FunkcjaLiczbowa.
System.out.println(f2.getClass());
if(f2 instanceof FunkcjaLiczbowa) {
System.out.println("Jest instancją");
} else {
System.out.println("Nie jest instancją");
}
// Podczas kompilacji z kontekstu musi wynikać do jakiego interfejsu ma być dopasowana dana lambda.
// Object o2 = x -> 100*x + 13;
// Object o3 = (double x) -> {return 100*x + 13;};
}
}
package p13_lambdy.v2;
public class MojFrameworkFunkcyjny {
public static void zamien(double[] tablica, FunkcjaLiczbowa f) {
for (int i = 0; i < tablica.length; i++) {
tablica[i] = f.oblicz(tablica[i]);
}
}
}
package p13_lambdy.v2;
public class TradycyjneUzycieInterfejsu {
public static void main(String[] args) {
ZwyklaImplementacja f1 = new ZwyklaImplementacja();
System.out.println( f1.oblicz(1.0) );
System.out.println( f1.oblicz(1.5) );
// obiekt klasy implementującej interfejs mogę zapisać na zmienną typu interfejs
FunkcjaLiczbowa f2 = new ZwyklaImplementacja();
System.out.println( f2.oblicz(2.0) );
// Przed Javą 8 najbardziej zwięzłym sposobem na utworzenie obiektu zgodnego z interfejsem
// była "klasa anonimowa":
FunkcjaLiczbowa f3 = new FunkcjaLiczbowa() {
public double oblicz(double x) {
return x*x*x;
}
};
System.out.println( f3.oblicz(3.0) );
}
}
package p13_lambdy.v2;
import java.util.Arrays;
public class UzycieFramworku {
public static void main(String[] args) {
double[] a = { 0, 10, 20, 30, 40, 50 };
double[] b = { 100, 16, 25, 2 };
System.out.println("a: " + Arrays.toString(a));
System.out.println("b: " + Arrays.toString(b));
System.out.println();
MojFrameworkFunkcyjny.zamien(a, x -> x*x);
System.out.println("a: " + Arrays.toString(a));
MojFrameworkFunkcyjny.zamien(a, x -> x+5);
System.out.println("a: " + Arrays.toString(a));
MojFrameworkFunkcyjny.zamien(b, Math::sqrt);
System.out.println("b: " + Arrays.toString(b));
}
}
package p13_lambdy.v2;
public class ZwyklaImplementacja implements FunkcjaLiczbowa {
@Override
public double oblicz(double arg) {
return arg*arg;
}
}
package p13_lambdy.v3;
public class DoKwadratu implements FunkcjaLiczbowa {
@Override
public double oblicz(double x) {
return x * x;
}
}
package p13_lambdy.v3;
import java.util.ArrayList;
import java.util.List;
public class EffectivelyFinal {
private static int statyczna = 0;
public static void main(String[] args) {
// W wyrażeniach lambda (podobnie jak w klasach anonimowych) nie można używać zmiennych lokalnych, które są modyfikowane
// Przykład kiedy to przeszkadza w praktyce:
List<String> imiona = new ArrayList<>();
imiona.add("Ala");
imiona.add("Aleksandra");
imiona.add("Ula");
imiona.add("Elżbieta");
double liczba = 0;
liczba = liczba + imiona.size();
int x = 0;
// Głupie rozwiązanie problemu "ile jest jest imion 3-literowych"
imiona.forEach(s -> {
if(s.length() == 3) {
//NK x++; // wewnątrz wyrażeń lambda nie można modyfikować zmiennych lokalnych z otoczenia
// ani nawet używać zmiennych modyfikowanych poza lambdą
//NK System.out.println(liczba);
// mamy dostęp do zmiennych z poziomu klasy (statycznych, isntancyjnych)
statyczna++;
// ale to zły styl
}
});
System.out.println(" x : " + x);
System.out.println("statyczna : " + statyczna);
}
}
package p13_lambdy.v3;
@FunctionalInterface
public interface FunkcjaLiczbowa {
// interfejs funkcyjny może zawierać metody defaultowe i statyczne
// ale ma zawierać dokładnie jedną metodę abstrakcyjną (czyli niezaimplementowaną)
double oblicz(double arg);
// aplikuje bieżącą funkcję podwójnie
default double podwojnie(double arg) {
return oblicz(oblicz(arg));
}
default FunkcjaLiczbowa zloz(FunkcjaLiczbowa nastepnyKrok) {
return x -> {
double wynikPosredni = oblicz(x);
double wynikKoncowy = nastepnyKrok.oblicz(wynikPosredni);
return wynikKoncowy;
};
}
static FunkcjaLiczbowa identycznosc() {
return x -> x;
}
}
package p13_lambdy.v3;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.UnaryOperator;
public class ReferencjeDoMetod {
public static void main(String[] args) {
List<String> lista = new ArrayList<>();
lista.add("Ala");
lista.add("Ola");
lista.add("Ela");
// Jeśli istnieje metoda, której chcemy użyć, to zamiast pisać taką trywialną lambdę
FunkcjaLiczbowa f1 = x -> Klasa.aaa(x);
System.out.println(f1.oblicz(10));
// możemy bezpośrednio wskazać tę metodę
// Opcja 1: wskazujemy metodę statyczną poprzez klasę
FunkcjaLiczbowa f2 = Klasa::aaa;
System.out.println(f2.oblicz(10));
System.out.println();
// Opcja 2: wskazujemy metodę instancyjną poprzez obiekt
Klasa obiekt = new Klasa(50);
FunkcjaLiczbowa f3 = obiekt::bbb;
System.out.println(f3.oblicz(10));
FunkcjaLiczbowa f4 = x -> obiekt.bbb(x);
System.out.println(f4.oblicz(10));
System.out.println();
// Opcja 3: wskazujemy metodę instancyjną poprzez klasę.
// Wówczas this jest traktowany jak pierwszy argument funkcji.
UnaryOperator<String> naDuzeLitery = String::toUpperCase;
System.out.println(naDuzeLitery.apply("Ala ma kota"));
System.out.println();
lista.stream()
.map(naDuzeLitery)
.forEach(System.out::print);
System.out.println();
lista.stream()
.map(String::toUpperCase)
.forEach(System.out::print);
System.out.println();
lista.stream()
.map(x -> x.toUpperCase())
.forEach(System.out::print);
System.out.println();
System.out.println();
Comparator<String> komp1 = (s1, s2) -> s1.compareTo(s2);
Comparator<String> komp2 = String::compareTo;
// jakby (this, argument) -> this.compareTo(argument);
lista.stream().sorted(String::compareTo).forEachOrdered(System.out::println);
}
static class Klasa {
private int wartosc;
public Klasa(int x) {
this.wartosc = x;
}
static double aaa(double x) {
return x+1;
}
double bbb(double x) {
return x+wartosc;
}
}
}
package p13_lambdy.v3;
import java.time.LocalTime;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntUnaryOperator;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public class SkladniaLambd {
static int globalna = 0;
public static void main(String[] args) {
FunkcjaLiczbowa f1 = (double arg) -> {
System.out.println("obliczam...");
double z = arg * arg;
globalna++;
return z + 5;
};
System.out.println("a kuku");
double wynik = f1.oblicz(7);
System.out.println(wynik);
// pomijam typ argumentu
FunkcjaLiczbowa f2 = (arg) -> {return arg + 5;};
//FunkcjaLiczbowa f2 = (arg) -> return arg + 5;
// jeśli prawa strona sprowadza się do jednego return, można od razu pisać wynim bez klamerek i bez return:
FunkcjaLiczbowa f3 = (arg) -> arg + 5;
// tutaj średnik należy do instrukcji przypisania, a nie jest częścią lambdy
FunkcjaLiczbowa f3a = ( (arg) -> arg + 5 ) ;
// jeśli po lewej stronie jest jeden argument bez typu, to można pominąć nawiasy
FunkcjaLiczbowa f4 = arg -> arg + 5;
// Consumer jest typu T -> void czyli nie zwraca wyniku
Consumer<String> cs1 = s -> {System.out.println(s);};
// nawet jeśli metoda nie zwraca wyniku, ale jest zbudowana z jednego polecenia, można pominąć nawiasy klamrowe
Consumer<String> cs2 = s -> System.out.println(s) ;
Function<String, Integer> ff = s -> s.length();
UnaryOperator<String> un = s -> s.toUpperCase();
IntUnaryOperator iun = i -> 10*i;
int x = 15;
int y = -x; // minus jest "operatorem unarnym", stąd się wzięła nazwa dla funkcji przyjmujących jeden argument
// Jeśli parametrów jest więcej niż 1, to musimy wziąć je w nawiasy
// Albo podajemy typy wszystkich parametrów, albo żadnego
// Comparator<String> komp = x, y -> x.compareToIgnoreCase(y);
Comparator<String> komp1 = (String s1, String s2) -> s1.compareToIgnoreCase(s2);
Comparator<String> komp2 = (s1, s2) -> s1.compareToIgnoreCase(s2);
//NK Comparator<String> komp3 = (String s1, s2) -> s1.compareToIgnoreCase(s2);
// Jeśli metoda nie przyjmuje parametrów, to po lewej stronie strzałki piszemy puste nawiasy
Runnable r1 = () -> {};
Runnable r2 = () -> {System.out.println("Hello world");};
//NK Runnable r2a = (void) -> {System.out.println("Hello world");};
// nawet jeśli funkcja jest typu void (nie zwraca wyniku), a treść ogranicza się do jednej instrukcji,
// to tę instrukcję możemy napisać bez klamerek
Runnable r3 = () -> System.out.println("Hello world");
Runnable r4 = () -> globalna = 103;
System.out.println("gloalna przed: " + globalna);
r4.run();
System.out.println("gloalna przed: " + globalna);
Consumer<String> cs4 = napis -> System.out.println(napis.length());
Supplier<String> dajDate = () -> LocalTime.now().toString();
// nazwami parametrów w lambdach nie mogą być zajęte nazwy zmiennych lokalnych
// Comparator<String> komp2 = (x, y) -> x.compareToIgnoreCase(y);
System.out.println();
for(int i = 0; i < 10; i++)
System.out.println(dajDate.get());
}
}
package p13_lambdy.v3;
public class Test1 {
public static void main(String[] args) {
FunkcjaLiczbowa f1 = new DoKwadratu();
System.out.println(f1.oblicz(5.0));
FunkcjaLiczbowa f2 = new FunkcjaLiczbowa() {
public double oblicz(double x) {
return x*x;
}
};
System.out.println(f2.oblicz(5.0));
FunkcjaLiczbowa f3 = y -> y*y;
System.out.println(f3.oblicz(5.0));
FunkcjaLiczbowa f4 = Math::sqrt;
System.out.println(f4.oblicz(25.0));
}
}
package p13_lambdy.v3;
import java.util.function.DoubleUnaryOperator;
public class Test2 {
public static void main(String[] args) {
FunkcjaLiczbowa razy2 = x -> x*2;
FunkcjaLiczbowa razy10 = x -> x*10;
FunkcjaLiczbowa plus3 = x -> x+3;
FunkcjaLiczbowa kwadrat = x -> x*x;
FunkcjaLiczbowa pierwiastek = Math::sqrt;
System.out.println(razy2.oblicz(10));
FunkcjaLiczbowa zlozenie1 = razy10.zloz(plus3);
System.out.println(zlozenie1.oblicz(10));
FunkcjaLiczbowa zlozenie2 = kwadrat.zloz(pierwiastek);
System.out.println(zlozenie2.oblicz(10));
System.out.println(zlozenie2.oblicz(50));
System.out.println(zlozenie2.oblicz(5.5));
FunkcjaLiczbowa zlozenie3 = pierwiastek.zloz(kwadrat);
System.out.println(zlozenie3.oblicz(2));
FunkcjaLiczbowa zlozenie4 = pierwiastek.zloz(pierwiastek);
System.out.println(zlozenie4.oblicz(10000));
System.out.println(zlozenie4.oblicz(625));
FunkcjaLiczbowa ident = FunkcjaLiczbowa.identycznosc();
System.out.println(ident.oblicz(113)); // 113
System.out.println(kwadrat.podwojnie(3)); // 81
// Takie rzeczy naprawdę istnieją:
DoubleUnaryOperator f1 = Math::sqrt;
DoubleUnaryOperator f2 = y -> y*y;
DoubleUnaryOperator f3 = f1.andThen(f2);
System.out.println(f3.applyAsDouble(2));
System.out.println(f1.andThen(f1).applyAsDouble(625));
}
}
package p13_lambdy.v3;
import static p13_lambdy.v3.ZastosowaniaFunkcjiLiczbowej.*;
import java.util.Arrays;
// To już już jest kod pisany na co dzień przez zwykłych programistów,
// który używają gotowych schematów.
public class UzycieLambd2 {
public static void main(String[] args) {
double[] a = {0, 10, 20, 30, 40, 50};
double[] b = {100, 16, 25, 2};
System.out.println("a: " + Arrays.toString(a));
System.out.println("b: " + Arrays.toString(b));
System.out.println();
// tutaj mogę w wygodny sposób podawać funkcje
zastosujdoTablicy(a, x -> x*x);
zastosujdoTablicy(b, Math::sqrt);
System.out.println("a: " + Arrays.toString(a));
System.out.println("b: " + Arrays.toString(b));
System.out.println();
}
}
package p13_lambdy.v3;
// Tego typu kod piszą twórcy "frameworków", gotowych rozwiązań
// Tutaj uzywamy nazw takich jak FunkcjaLiczbowa, oblicz
// - normalne programowanie w Javie.
// Ale robimy to, aby zwykli programiści mieli łatwiej w takich miejscahc jak Uzycie2
public class ZastosowaniaFunkcjiLiczbowej {
// Ta operacja bardzo przypomina map na streamach
// Tutaj zmienia wartość wewnątrz tablicy
public static void zastosujdoTablicy(double[] tab, FunkcjaLiczbowa f) {
for (int i = 0; i < tab.length; i++) {
tab[i] = f.oblicz(tab[i]);
}
}
}
package p14_streamy.a_poczatek;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class A_TypowyPrzyklad {
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println(lista);
System.out.println();
lista.stream()
.filter(s -> s.contains("a"))
.map(s -> s.toUpperCase())
.forEach(s -> System.out.println(s));
// To odpowiada takiej pętli:
for(String s1 : lista) {
if(s1.contains("a")) {
String s2 = s1.toUpperCase();
System.out.println(s2);
}
}
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class Strumienie1 {
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
Stream<String> str1 = lista.stream();
System.out.println(str1);
// Strumień nie jest kolekcją, nie zawiera danych. Jest on tylko sposobem dostępu do danych.
str1.forEach(s -> System.out.print(s + ", "));
System.out.println();
System.out.println();
// Jednego strumienia nie można używać wielokrotnie
// forEach jest "operacją terminującą" i zamyka strumień
//EXN str1.forEach(s -> System.out.print(s + "; "));
// Jest też forEach bezpośrednio na liście (na każdym Iterable)
lista.forEach(s -> System.out.print(s + "; "));
System.out.println();
// Zobaczmy po kolei jakiego typu wyniki wychodzą:
Stream<String> str2a = Arrays.stream(tablica);
Stream<String> str2b = str2a.filter(s -> s.length() > 3);
Stream<String> str2c = str2b.map(s -> s.toUpperCase());
// Stream<Integer> str2d = str2c.map(s -> s.length());
// albo - w praktyce lepiej:
IntStream str2e = str2c.mapToInt(s -> s.length());
// Strumienie liczb oferują dodatkowe operacje.
int suma = str2e.sum();
System.out.println(suma);
System.out.println();
// Zazwyczaj nie tworzy się zmiennych pośrednich, tylko zapisuje jednym ciągiem ("pipeline"):
suma = Arrays.stream(tablica)
.filter(s -> s.length() > 3)
.map(s -> s.toUpperCase())
.mapToInt(s -> s.length())
.sum();
System.out.println(suma);
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
// Operacje wypisują co robią na ekran, abyśmy mogli sprawdzić kolejność ich wykonania.
public class Strumienie2_JakToDziala {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
// Chociaż wskazuję operacje sprawdź i mapuj w momencie definiowania strumienia
// to one jeszcze się nie wykonują.
Stream<String> strumien = lista.stream()
.filter(s -> sprawdz(s))
.map(s -> mapuj(s));
System.out.println("Strumień utworzony: " + strumien);
lista.add("Dodatkowy");
System.out.println();
System.out.println("Operacja terminująca:");
strumien.forEach(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie2a {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.stream()
.filter(s -> sprawdz(s))
.map(s -> mapuj(s))
.limit(5);
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
strumien.forEach(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie2b {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.stream()
.limit(5)
.filter(s -> sprawdz(s))
.map(s -> mapuj(s));
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
strumien.forEach(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie2c {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.parallelStream()
.filter(s -> sprawdz(s))
.map(s -> mapuj(s));
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
strumien.forEach(s -> System.out.println(" * " + s));
// forEach nie ma obowiązku zachowania kolejności i w przypadku parallelStream nie zachowuje
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie2d {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.parallelStream()
.filter(s -> sprawdz(s))
.map(s -> mapuj(s));
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
// forEachOrdered gwarantuje wykonanie operacji (tylko tej ostatniej) w takiej kolejności, w jakiej elementy są umieszczone w strumieniu
strumien.forEachOrdered(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie2e {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.parallelStream()
.filter(s -> sprawdz(s))
.map(s -> mapuj(s))
.limit(5);
// tutaj wciąż te same 5 elementów jest wyświetlanych na końcu
// tak dzieje się dlatego, że strumień jest uporządkowany (ORDERED), bo pochodzi z listy
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
strumien.forEach(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie2f {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.parallelStream()
.filter(s -> sprawdz(s))
.map(s -> mapuj(s))
.limit(5);
// tutaj wciąż te same 5 elementów jest wyświetlanych na końcu - a ich kolejność będzie zachowana
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
strumien.forEachOrdered(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie2g {
static boolean sprawdz(String s) {
System.out.println("sprawdzam " + s);
return s.length() > 3;
}
static String mapuj(String s) {
System.out.println("mapuję " + s);
return s.toUpperCase();
}
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.parallelStream()
.unordered()
.filter(s -> sprawdz(s))
.map(s -> mapuj(s))
.limit(5);
// unordered - zapomnij o kolejności; to może zwiekszyć wydajność, ale wyniki tego przykładu
// (gdzie mamy limit) są niedetrministyczne
// teraz zmienia się zestaw elementów wyświetlanym na końcu forEachem
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
// strumien.forEach(s -> System.out.println(" * " + s));
strumien.forEachOrdered(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
}
}
package p14_streamy.b_dzialanie;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Strumienie3_Peek {
public static void main(String[] args) {
String[] tablica = { "Ala", "Ola", "Iwona", "Magdalena", "Joanna", "Anna", "Teresa",
"Żaneta", "Ęcki", "Ącki", "Agnieszka", "ala", "Łucja", "Julia", "Julitta", "Zuzanna" };
List<String> lista = new ArrayList<>(Arrays.asList(tablica));
System.out.println("Przed tworzeniem strumienia");
Stream<String> strumien = lista.stream()
.peek(s -> System.out.println("\n F : " + s))
.filter(s -> s.length() > 3)
.peek(s -> System.out.println(" M : " + s))
.map(String::toUpperCase)
.peek(s -> System.out.println(" # : " + s));
System.out.println("Strumień utworzony: " + strumien);
System.out.println();
System.out.println("Operacja terminująca:");
strumien.forEach(s -> System.out.println(" * " + s));
System.out.println("KONIEC");
System.out.println();
Stream<String> str2a = lista.stream();
Stream<String> str2b = str2a.peek(s -> System.out.println(" % " + s));
// peek nie wpływa na zawartość ani "widzianą z zewnątrz logikę" strumienia,
// ale powoduje, że w momencie ewaluacji strumienia na każdym elemencie będzie wykonan podana operacja
str2b.limit(5).forEach(s -> {});
}
}
package p14_streamy.c_przeglad_operacji;
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 p14_streamy.c_przeglad_operacji;
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 p14_streamy.c_przeglad_operacji;
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 p14_streamy.c_przeglad_operacji;
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 p14_streamy.c_przeglad_operacji;
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 p14_streamy.c_przeglad_operacji;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import emps.Employee;
import emps.ObslugaCSV;
public class C14_MinMax {
public static void main(String[] args) {
List<Employee> lista = ObslugaCSV.wczytaj("emps.csv");
Optional<Employee> min = lista.stream().min(Comparator.comparing(Employee::getSalary));
Optional<Employee> max = lista.stream().max(Comparator.comparing(Employee::getSalary));
System.out.println("min: " + min);
System.out.println("max: " + max);
System.out.println();
if(min.isPresent()) {
System.out.println("Znaleziono minimum:");
Employee emp = min.get();
System.out.println(emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary());
} else {
System.out.println("nie ma minimum");
}
if(max.isPresent()) {
System.out.println("Znaleziono maximum:");
Employee emp = max.get();
System.out.println(emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary());
} else {
System.out.println("nie ma maximum");
}
System.out.println();
String [] stanowiska = {"Programmer", "Shipping Clerk", "Brygadier"};
for (String stanowisko : stanowiska) {
String tekst = lista.stream()
.filter(emp -> Objects.equals(emp.getJobTitle(), stanowisko))
.max(Comparator.comparing(Employee::getSalary))
.map(emp -> emp.getFirstName() + " " + emp.getLastName() + " zarabia " + emp.getSalary())
.orElse("nie ma takiego gościa");
// powyższe map dotyczy Optional, a nie Stream
System.out.println("Najbogatszy " + stanowisko + ": " + tekst);
}
}
}
package p14_streamy.c_przeglad_operacji;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
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 p14_streamy.c_przeglad_operacji;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
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 p14_streamy.c_przeglad_operacji;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
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 p14_streamy.c_przeglad_operacji;
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 p14_streamy.d_redukcje_i_grupowanie;
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 p14_streamy.d_redukcje_i_grupowanie;
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 p14_streamy.d_redukcje_i_grupowanie;
import java.util.stream.Collector;
import java.util.stream.Collector.Characteristics;
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 p14_streamy.d_redukcje_i_grupowanie;
import java.util.Collection;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import emps.Employee;
import emps.ObslugaCSV;
public class Kolektory1 {
public static void main(String[] args) {
//List<Employee> emps = Collections.emptyList();
List<Employee> emps = ObslugaCSV.wczytaj("emps.csv");
// collectory obliczające standardowe funkcje agregujące
Long ilu = emps.stream().collect(Collectors.counting());
Integer suma = emps.stream().collect(Collectors.summingInt(Employee::getSalary));
Double avg = emps.stream().collect(Collectors.averagingInt(Employee::getSalary));
// dla pustego zbioru danych wychodzi 0.0
System.out.println(ilu + ", " + suma + ", " + avg);
// Porównuje pracowników wg pensji
Comparator<Employee> komp = Comparator.comparingInt(Employee::getSalary);
Optional<Employee> min = emps.stream().collect(Collectors.minBy(komp));
Optional<Employee> max = emps.stream().collect(Collectors.maxBy(komp));
System.out.println(min);
System.out.println(max);
// przykład wyciągaia wartości z Optionala
String str1 = min
.map(emp -> emp.getFirstName()
+ " " + emp.getLastName()
+ " / " + emp.getSalary())
.orElse("nie ma takiego gościa");
System.out.println(str1);
System.out.println();
// Oblicza wszystkie 5 standardowe funkcje agregujące
IntSummaryStatistics statystyki = emps.stream().collect(Collectors.summarizingInt(Employee::getSalary));
System.out.println(statystyki);
System.out.println(statystyki.getAverage());
System.out.println();
// Zestaw kolektorów zbierających dane do kolekcji:
List<String> list1 = emps.stream()
.map(Employee::getFirstName)
.sorted()
.distinct()
.collect(Collectors.toList());
System.out.println(list1);
Set<String> set1 = emps.stream()
.map(Employee::getCity)
.collect(Collectors.toSet());
System.out.println(set1);
Collection<String> kolekcja = emps.stream()
.map(Employee::getCity)
.collect(Collectors.toCollection(TreeSet::new));
System.out.println(kolekcja);
System.out.println();
// Tworząc słownik podajemy skąd się biorą klucze, skąd się biorą wartości
// i ewentualnie jak aktualizować już wpisane wartości
Map<String, Integer> grupy = emps.stream()
.collect(Collectors.toMap(Employee::getCity,
Employee::getSalary,
Math::addExact));
grupy.forEach((k,v) -> System.out.printf("%20s -> %10s\n", k, v));
System.out.println();
String txt1 = emps.stream()
.map(Employee::getDepartmentName)
.distinct()
.collect(Collectors.joining());
System.out.println(txt1);
String txt2 = emps.stream()
.map(Employee::getDepartmentName)
.distinct()
.collect(Collectors.joining(", "));
System.out.println(txt2);
String txt3 = emps.stream()
.map(Employee::getDepartmentName)
.distinct()
.collect(Collectors.joining(", ", "<", ">"));
System.out.println(txt3);
}
}
package p14_streamy.d_redukcje_i_grupowanie;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
import emps.Employee;
import emps.ObslugaCSV;
public class Kolektory2 {
public static void main(String[] args) {
//List<Employee> emps = Collections.emptyList();
List<Employee> emps = ObslugaCSV.wczytaj("emps.csv");
// grouping by - zbiera elementy w grupy
Map<String, List<Employee>> grupy1 = emps.stream()
.collect(Collectors.groupingBy(Employee::getJobTitle));
grupy1.forEach((k,v) -> {
System.out.println(k);
v.forEach(emp -> {
System.out.printf(" %-12s %-12s %10s\n", emp.getFirstName(), emp.getLastName(), emp.getSalary());
});
});
System.out.println();
// Podajemy dodatkowy kolektor mówiący co robić z każdą grupą
Map<String, Integer> grupy2 = emps.stream()
.collect(Collectors.groupingBy(
Employee::getJobTitle,
Collectors.summingInt(Employee::getSalary)));
grupy2.forEach((k,v) -> {
System.out.printf("%-32s %12s\n", k, v);
});
System.out.println();
// Możemy też podać fabrykę map jako środkowy parametr
Map<String, Integer> grupy3 = emps.stream()
.collect(Collectors.groupingBy(
Employee::getJobTitle,
TreeMap::new,
Collectors.summingInt(Employee::getSalary)));
grupy3.forEach((k,v) -> {
System.out.printf("%-32s %12s\n", k, v);
});
System.out.println();
System.out.println("================");
Map<Boolean, List<Employee>> partycje1 = emps.stream()
.collect(Collectors.partitioningBy(emp -> emp.getSalary() >= 10000));
System.out.println("Bogaci:");
partycje1.get(true)
.forEach(emp -> System.out.println(" " + emp.getLastName()));
System.out.println("\nBiedni:");
partycje1.get(false)
.forEach(emp -> System.out.println(" "+ emp.getLastName()));
System.out.println();
Map<Boolean, Long> partycje2 = emps.stream()
.collect(Collectors.partitioningBy(
emp -> emp.getSalary() >= 10000,
Collectors.counting()));
System.out.println("Bogatych " + partycje2.get(true));
System.out.println("Biednych " + partycje2.get(false));
}
}
package p14_streamy.d_redukcje_i_grupowanie;
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));
}
}
package p15_parallel_stream.a;
import java.util.Arrays;
import java.util.function.IntUnaryOperator;
import java.util.stream.IntStream;
public class SprawdzanieIleWatkow1 {
public static void main(String[] args) {
IntUnaryOperator operacja = x -> {
System.out.println(Thread.currentThread().getId());
return 2*x;
};
int[] tab = new int[100];
Arrays.fill(tab, 33);
System.out.println("Sekwencyjnie:");
int suma1 = IntStream.of(tab).map(operacja).sum();
System.out.println("suma1 = " + suma1);
System.out.println();
System.out.println("Parallel:");
int suma2 = IntStream.of(tab).parallel().map(operacja).sum();
System.out.println("suma2 = " + suma2);
}
}
package p15_parallel_stream.a;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.function.IntUnaryOperator;
import java.util.stream.IntStream;
public class SprawdzanieIleWatkow2 {
public static void main(String[] args) {
AtomicIntegerArray array = new AtomicIntegerArray(50);
IntUnaryOperator operacja = x -> {
int id = (int)Thread.currentThread().getId();
array.incrementAndGet(id);
return 2*x;
};
int[] tab = new int[1_000_000];
Arrays.fill(tab, 33);
System.out.println("Tablica wątków na początku:");
System.out.println(array);
int suma2 = IntStream.of(tab).parallel().map(operacja).sum();
System.out.println("suma2 = " + suma2);
System.out.println();
System.out.println("Tablica wątków na końcu:");
System.out.println(array);
int ileWatkow = 0;
for (int i = 0; i < array.length(); i++) {
if(array.get(i) > 0) {
ileWatkow++;
System.out.printf("wątek nr %3d - %8d razy\n", i, array.get(i));
}
}
System.out.println();
System.out.println("W sumie pracowało " + ileWatkow + " wątków.");
System.out.println("Ilość procesorów: " +
Runtime.getRuntime().availableProcessors());
}
}
package p15_parallel_stream.a;
import java.util.Random;
import java.util.function.LongSupplier;
import java.util.stream.LongStream;
public class SumArray {
static final int N = 120_000_000;
static final int MAX = 1000;
static final int POWTORZENIA = 40;
static long[] tab;
public static void main(String[] args) {
System.out.println("Generuje dane");
tab = new long[N];
wylosuj();
System.out.println("pętla");
testuj(SumArray::petla);
System.out.println("stream");
testuj(SumArray::sekw);
System.out.println("parallel stream");
testuj(SumArray::parallel);
System.out.println();
System.out.println("pętla");
testuj(POWTORZENIA, SumArray::petla);
System.out.println("stream");
testuj(POWTORZENIA, SumArray::sekw);
System.out.println("parallel stream");
testuj(POWTORZENIA, SumArray::parallel);
}
private static void testuj(LongSupplier metoda) {
long start = System.currentTimeMillis();
long wynik = metoda.getAsLong();
long end = System.currentTimeMillis();
System.out.printf("czas: %6d, wynik: %15d\n", end - start, wynik);
}
private static void testuj(int n, LongSupplier metoda) {
long start = System.currentTimeMillis();
long wynik = 0L;
for(int i = 1; i <= n; i++) {
wynik += metoda.getAsLong();
}
long end = System.currentTimeMillis();
System.out.printf("czas: %6d, wynik: %15d\n", end - start, wynik);
}
private static void wylosuj() {
Random r = new Random();
for (int i = 0; i < tab.length; i++) {
tab[i] = r.nextInt(MAX);
}
}
private static long petla() {
long suma = 0L;
for (int i = 0; i < tab.length; i++) {
suma += tab[i];
}
return suma;
}
private static long sekw() {
return LongStream.of(tab).sum();
}
private static long parallel() {
return LongStream.of(tab).parallel().sum();
}
}
package p15_parallel_stream.b_spliterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
public class ArrayListSplit {
public static void main(String[] args) {
List<String> lista = new ArrayList<>();
lista.add("aaa");
lista.add("bbb");
lista.add("ccc");
lista.add("ddd");
lista.add("eee");
lista.add("fff");
lista.add("ggg");
lista.add("hhh");
lista.add("iii");
lista.add("jjj");
System.out.println(lista);
Consumer<String> akcja = s -> System.out.println("* " + s);
System.out.println("Pętla tryAdvance:");
Spliterator<String> spliterator1 = lista.spliterator();
while(spliterator1.tryAdvance(akcja));
System.out.println();
System.out.println("forEachRemaining:");
Spliterator<String> spliterator2 = lista.spliterator();
spliterator2.forEachRemaining(akcja);
System.out.println();
System.out.println("trySplit 2 poziomy:");
Spliterator<String> spliterator3 = lista.spliterator();
System.out.println("estimate size: " + spliterator3.estimateSize());
Spliterator<String> spliterator3a = spliterator3.trySplit();
System.out.println("Oryginalny:");
spliterator3.forEachRemaining(akcja);
System.out.println("wynik pierwszego split:");
spliterator3a.forEachRemaining(akcja);
System.out.println();
System.out.println("trySplit 3 poziomy:");
Spliterator<String> spliterator4 = lista.spliterator();
System.out.println("estimate size: " + spliterator4.estimateSize());
Spliterator<String> spliterator4a = spliterator4.trySplit();
Spliterator<String> spliterator4b = spliterator4.trySplit();
System.out.println("Oryginalny:");
spliterator4.forEachRemaining(akcja);
System.out.println("wynik pierwszego split:");
spliterator4a.forEachRemaining(akcja);
System.out.println("wynik drugiego split:");
spliterator4b.forEachRemaining(akcja);
System.out.println();
}
}
package p15_parallel_stream.b_spliterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
// Morał: LinkedList nie dzieli się na fragmenty, więc operacje nie będą zrównoleglane
public class LinkedListSplit {
public static void main(String[] args) {
List<String> lista = new LinkedList<>();
lista.add("aaa");
lista.add("bbb");
lista.add("ccc");
lista.add("ddd");
lista.add("eee");
lista.add("fff");
lista.add("ggg");
lista.add("hhh");
lista.add("iii");
lista.add("jjj");
System.out.println(lista);
Consumer<String> akcja = s -> System.out.println("* " + s);
System.out.println("Pętla tryAdvance:");
Spliterator<String> spliterator1 = lista.spliterator();
while(spliterator1.tryAdvance(akcja));
System.out.println();
System.out.println("forEachRemaining:");
Spliterator<String> spliterator2 = lista.spliterator();
spliterator2.forEachRemaining(akcja);
System.out.println();
System.out.println("trySplit 2 poziomy:");
Spliterator<String> spliterator3 = lista.spliterator();
System.out.println("estimate size: " + spliterator3.estimateSize());
Spliterator<String> spliterator3a = spliterator3.trySplit();
System.out.println("Oryginalny:");
spliterator3.forEachRemaining(akcja);
System.out.println("wynik pierwszego split:");
spliterator3a.forEachRemaining(akcja);
System.out.println();
System.out.println("trySplit 3 poziomy:");
Spliterator<String> spliterator4 = lista.spliterator();
System.out.println("estimate size: " + spliterator4.estimateSize());
Spliterator<String> spliterator4a = spliterator4.trySplit();
Spliterator<String> spliterator4b = spliterator4.trySplit();
System.out.println("4a " + spliterator4a);
System.out.println("4b " + spliterator4b); // null
System.out.println("Oryginalny:");
spliterator4.forEachRemaining(akcja);
System.out.println("wynik pierwszego split:");
spliterator4a.forEachRemaining(akcja);
// NPE
// System.out.println("wynik drugiego split:");
// spliterator4b.forEachRemaining(akcja);
System.out.println();
}
}
package p15_parallel_stream.b_spliterator;
import java.util.function.LongSupplier;
public class MierzenieCzasu {
public static void uruchom(LongSupplier metoda) {
long start = System.nanoTime();
long wynik = metoda.getAsLong();
long end = System.nanoTime();
System.out.printf("czas: %12d , wynik = %d\n", (end - start) / 1000, wynik);
}
public static void uruchom(int n, LongSupplier metoda) {
long start = System.currentTimeMillis();
long wynik = 0L;
for(int i = 1; i <= n; i++) {
wynik += metoda.getAsLong();
}
long end = System.currentTimeMillis();
System.out.printf("czas: %6d, wynik: %15d\n", end - start, wynik);
}
}
package p15_parallel_stream.b_spliterator;
import java.util.Spliterator;
import java.util.function.Consumer;
public class SpliteratorLiczbyNieparzyste implements Spliterator<Integer> {
private int max;
private int min;
// domyślnie 100 liczb
public SpliteratorLiczbyNieparzyste() {
this(100);
}
public SpliteratorLiczbyNieparzyste(int ile) {
this(0, ile);
}
private SpliteratorLiczbyNieparzyste(int min, int max) {
this.min = min;
this.max = max;
}
private int next() {
return 1 + 2 * min++;
}
private boolean hasNext() {
return min < max;
}
@Override
public boolean tryAdvance(Consumer<? super Integer> action) {
if(hasNext()) {
action.accept(this.next());
return true;
} else {
return false;
}
}
@Override
public SpliteratorLiczbyNieparzyste trySplit() {
int middle = (max + min) / 2;
SpliteratorLiczbyNieparzyste nowy = new SpliteratorLiczbyNieparzyste(min, middle);
min = middle;
return nowy;
}
@Override
public long estimateSize() {
return max - min;
}
@Override
public int characteristics() {
return ORDERED | DISTINCT | SIZED | SUBSIZED | NONNULL;
}
}
package p15_parallel_stream.b_spliterator;
import java.util.Spliterator;
import java.util.function.Consumer;
public class SpliteratorPowolny implements Spliterator<Integer> {
private int max;
private int min;
private int niepotrzebne;
private final int SPOWOLNIENIE = 10000;
// domyślnie 100 liczb
public SpliteratorPowolny() {
this(100);
}
public SpliteratorPowolny(int ile) {
this(0, ile);
}
private SpliteratorPowolny(int min, int max) {
this.min = min;
this.max = max;
}
private int next() {
for(int i=0; i<SPOWOLNIENIE; i++) {
niepotrzebne++;
}
return 1 + 2 * min++;
}
private boolean hasNext() {
return min < max;
}
@Override
public boolean tryAdvance(Consumer<? super Integer> action) {
action.accept(this.next());
return hasNext();
}
@Override
public SpliteratorPowolny trySplit() {
int middle = (max + min) / 2;
SpliteratorPowolny nowy = new SpliteratorPowolny(min, middle);
min = middle;
return nowy;
}
@Override
public long estimateSize() {
return max - min;
}
@Override
public int characteristics() {
return ORDERED | DISTINCT | SIZED | SUBSIZED | NONNULL;
}
}
package p15_parallel_stream.b_spliterator;
import java.util.Spliterator;
import java.util.function.IntConsumer;
public class SpliteratorPrimitive implements Spliterator.OfInt {
private int max;
private int min;
// domyślnie 100 liczb
public SpliteratorPrimitive() {
this(100);
}
public SpliteratorPrimitive(int ile) {
this(0, ile);
}
private SpliteratorPrimitive(int min, int max) {
this.min = min;
this.max = max;
}
private int next() {
return 1 + 2 * min++;
}
private boolean hasNext() {
return min < max;
}
@Override
public boolean tryAdvance(IntConsumer action) {
action.accept(this.next());
return hasNext();
}
@Override
public SpliteratorPrimitive trySplit() {
int middle = (max + min) / 2;
SpliteratorPrimitive nowy = new SpliteratorPrimitive(min, middle);
min = middle;
return nowy;
}
@Override
public long estimateSize() {
return max - min;
}
@Override
public int characteristics() {
return ORDERED | DISTINCT | SIZED | SUBSIZED | NONNULL;
}
}
package p15_parallel_stream.b_spliterator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Test1 {
// Stream<Integer> bez spowalniania. Niepotrzebny narzut na boxing
public static void main(String[] args) {
SpliteratorLiczbyNieparzyste spl1 = new SpliteratorLiczbyNieparzyste(10000000);
Stream<Integer> str1 = StreamSupport.stream(spl1, false);
MierzenieCzasu.uruchom(() -> str1.mapToInt(x->x).sum());
SpliteratorLiczbyNieparzyste spl2 = new SpliteratorLiczbyNieparzyste(10000000);
Stream<Integer> str2 = StreamSupport.stream(spl2, true);
MierzenieCzasu.uruchom(() -> str2.mapToInt(x->x).sum());
System.out.println();
}
}
package p15_parallel_stream.b_spliterator;
import java.util.Spliterator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Test2 {
// Spliterator sztucznie spowolniony, Stream<Integer>, widać zysk z parallel
public static void main(String[] args) {
Spliterator<Integer> spl1 = new SpliteratorPowolny(10000000);
Stream<Integer> str1 = StreamSupport.stream(spl1, false);
MierzenieCzasu.uruchom(() -> str1.mapToLong(x->x).sum());
Spliterator<Integer> spl2 = new SpliteratorPowolny(10000000);
Stream<Integer> str2 = StreamSupport.stream(spl2, true);
MierzenieCzasu.uruchom(() -> str2.mapToLong(x->x).sum());
}
}
package p15_parallel_stream.b_spliterator;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
public class Test3 {
public static void main(String[] args) {
// IntStream bez żadnego boxingnu - działa najszybciej
SpliteratorPrimitive spl1 = new SpliteratorPrimitive(10000000);
IntStream str1 = StreamSupport.intStream(spl1, false);
MierzenieCzasu.uruchom(() -> str1.sum());
SpliteratorPrimitive spl2 = new SpliteratorPrimitive(10000000);
IntStream str2 = StreamSupport.intStream(spl2, true);
MierzenieCzasu.uruchom(() -> str2.sum());
}
}
package p15_parallel_stream.b_spliterator;
import java.util.Spliterator;
import java.util.function.Consumer;
public class TestNieparzyste {
public static void main(String[] args) {
Consumer<Integer> akcja = i -> System.out.print(i + ", ");
SpliteratorLiczbyNieparzyste spl1 = new SpliteratorLiczbyNieparzyste(100);
spl1.forEachRemaining(akcja);
System.out.println();
System.out.println();
Spliterator<Integer> spl2 = new SpliteratorLiczbyNieparzyste(100);
Spliterator<Integer> a = spl2.trySplit();
Spliterator<Integer> b = a.trySplit();
System.out.println("Fragmenty:");
b.forEachRemaining(akcja);
System.out.println();
a.forEachRemaining(akcja);
System.out.println();
spl2.forEachRemaining(akcja);
System.out.println();
System.out.println();
}
}
package p15_parallel_stream.b_spliterator;
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class TestStrumienNieparzystych {
public static void main(String[] args) {
Consumer<Integer> akcja = i -> System.out.print(i + ", ");
SpliteratorLiczbyNieparzyste spl1 = new SpliteratorLiczbyNieparzyste(100);
Stream<Integer> str1 = StreamSupport.stream(spl1, false);
str1.forEach(akcja);
System.out.println();
System.out.println();
SpliteratorLiczbyNieparzyste spl2 = new SpliteratorLiczbyNieparzyste(100);
Stream<Integer> str2 = StreamSupport.stream(spl2, true);
str2.forEach(akcja);
System.out.println();
System.out.println();
SpliteratorLiczbyNieparzyste spl3 = new SpliteratorLiczbyNieparzyste(50);
Stream<Integer> str3 = StreamSupport.stream(spl3, false);
int suma3 = str3.mapToInt(x -> x).sum();
System.out.println(suma3);
SpliteratorLiczbyNieparzyste spl4 = new SpliteratorLiczbyNieparzyste(50);
Stream<Integer> str4 = StreamSupport.stream(spl4, true);
int suma4 = str4.mapToInt(x -> x).sum();
System.out.println(suma4);
}
}
package p15_parallel_stream.b_spliterator;
import java.util.function.IntConsumer;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
public class TestStrumienPrimite {
public static void main(String[] args) {
IntConsumer akcja = i -> System.out.print(i + ", ");
SpliteratorPrimitive spl1 = new SpliteratorPrimitive(100);
IntStream str1 = StreamSupport.intStream(spl1, false);
str1.forEach(akcja);
System.out.println();
}
}
package p16_porownywanie.v1_brak_equals;
public class HaszKody {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// Jeśli w klasie nie nadpiszemy metody hashCode, to działa domyślna implementacja
// wyliczająca hashcode na podstawie adresu.
// Daje to efekt, że haszkody różnych obiektów są różne.
// Dopóki nie tworzymy miliardów obiektów, to hashcody będą unikalne.
System.out.println("hasz a " + a.hashCode());
System.out.println("hasz r " + r.hashCode());
System.out.println("hasz b " + b.hashCode());
System.out.println("hasz c " + c.hashCode());
}
}
package p16_porownywanie.v1_brak_equals;
public class Osoba {
String imie, nazwisko;
int wiek;
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
@Override
public String toString() {
return "Osoba [imie=" + imie + ", nazwisko=" + nazwisko + ", wiek=" + wiek + "]";
}
}
package p16_porownywanie.v1_brak_equals;
import java.util.Objects;
public class Porownywanie {
// Jeśli w klasie nie zdefiniujemy metody equals, to używana jest domyślna implementacja pochodząca z klasy Object,
// która porównuje adresy (działa jak ==).
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// == sprawdza cz yto jest ten sam adres
System.out.println("a == a " + (a == a));
System.out.println("a == r " + (a == r));
System.out.println("a == b " + (a == b));
System.out.println("a == c " + (a == c));
System.out.println();
System.out.println("a.equals(a) " + (a.equals(a)));
System.out.println("a.equals(r) " + (a.equals(r)));
System.out.println("a.equals(b) " + (a.equals(b)));
System.out.println("a.equals(c) " + (a.equals(c)));
System.out.println();
System.out.println("Obj a a " + Objects.equals(a, a));
System.out.println("Obj a r " + Objects.equals(a, r));
System.out.println("Obj a b " + Objects.equals(a, b));
System.out.println("Obj a c " + Objects.equals(a, c));
System.out.println();
}
}
package p16_porownywanie.v1_brak_equals;
import java.util.Set;
import java.util.TreeSet;
public class ZbiorDrzewowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// TreeSet oraz TreeMap w działaniu korzystają z metody compareTo (ewentualnie z komparatora).
// Ten program kończy sie błedem, bo Osoba nie jest Comparable
boolean wynik;
Set<Osoba> zbior = new TreeSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v1_brak_equals;
import java.util.HashSet;
import java.util.Set;
public class ZbiorHaszowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// HashSet oraz HashMap w działaniu korzystają z metod hashCode i equals.
// 1) patrzy jaki jest hashcode i jeśli różny, to traktuje jak różne obiekty
// 2) jeśli hc jest równy, to wtedy porówuje za pomocą equals
boolean wynik; // wynik operacji add: jeśli element został dodany to true, a jeśli nie to false
Set<Osoba> zbior = new HashSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilość elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v2_bledny_equals;
public class HaszKody {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// Jeśli w klasie nie nadpiszemy metody hashCode, to działa domyślna implementacja
// wyliczająca hashcode na podstawie adresu.
// Daje to efekt, że haszkody różnych obiektów są różne.
// Dopóki nie tworzymy miliardów obiektów, to hashcody będą unikalne.
System.out.println("hasz a " + a.hashCode());
System.out.println("hasz r " + r.hashCode());
System.out.println("hasz b " + b.hashCode());
System.out.println("hasz c " + c.hashCode());
}
}
package p16_porownywanie.v2_bledny_equals;
import java.util.Objects;
public class Osoba {
String imie, nazwisko;
int wiek;
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
@Override
public String toString() {
return "Osoba [imie=" + imie + ", nazwisko=" + nazwisko + ", wiek=" + wiek + "]";
}
// To nie jest "overriding" tylko "overloading".
// Nie nadpisuję "prawdziwej" metody equals pochodzącej z Object, tylko towrzę nową dodatkową metodę odstepną tylko w klasie Osoba.
// Ten equals zadziała tylko jeśli bezpośrednio go wywołamy na obiekcie Osoba,
// ale to nie jest "ten prawdziwy" equals, i Java (np. HashSet) nie będzie brać tej definicji pod uwagę.
public boolean equals(Osoba inna) {
return inna != null
&& Objects.equals(this.imie, inna.imie)
&& Objects.equals(this.nazwisko, inna.nazwisko)
&& this.wiek == inna.wiek;
}
public int hashCode() {
// to jest niewydajne, ale poprawne i muszę to dopisać, aby "oszukać" hashset
return 0;
}
}
package p16_porownywanie.v2_bledny_equals;
import java.util.Objects;
public class Porownywanie {
// Jeśli w klasie nie zdefiniujemy metody equals, to używana jest domyślna implementacja pochodząca z klasy Object,
// która porównuje adresy (działa jak ==).
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// == sprawdza cz yto jest ten sam adres
System.out.println("a == a " + (a == a));
System.out.println("a == r " + (a == r));
System.out.println("a == b " + (a == b));
System.out.println("a == c " + (a == c));
System.out.println();
System.out.println("a.equals(a) " + (a.equals(a)));
System.out.println("a.equals(r) " + (a.equals(r)));
System.out.println("a.equals(b) " + (a.equals(b)));
System.out.println("a.equals(c) " + (a.equals(c)));
System.out.println();
System.out.println("Obj a a " + Objects.equals(a, a));
System.out.println("Obj a r " + Objects.equals(a, r));
System.out.println("Obj a b " + Objects.equals(a, b));
System.out.println("Obj a c " + Objects.equals(a, c));
System.out.println();
}
}
package p16_porownywanie.v2_bledny_equals;
import java.util.Set;
import java.util.TreeSet;
public class ZbiorDrzewowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// TreeSet oraz TreeMap w działaniu korzystają z metody compareTo (ewentualnie z komparatora).
// Ten program kończy sie błedem, bo Osoba nie jest Comparable
boolean wynik;
Set<Osoba> zbior = new TreeSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v2_bledny_equals;
import java.util.HashSet;
import java.util.Set;
public class ZbiorHaszowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// HashSet oraz HashMap w działaniu korzystają z metod hashCode i equals.
boolean wynik; // wynik operacji add: jeśli element został dodany to true, a jeśli nie to false
Set<Osoba> zbior = new HashSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v3_equals;
public class HaszKody {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// Jeśli w klasie nie nadpiszemy metody hashCode, to działa domyślna implementacja
// wyliczająca hashcode na podstawie adresu.
// Daje to efekt, że haszkody różnych obiektów są różne.
// Dopóki nie tworzymy miliardów obiektów, to hashcody będą unikalne.
System.out.println("hasz a " + a.hashCode());
System.out.println("hasz r " + r.hashCode());
System.out.println("hasz b " + b.hashCode());
System.out.println("hasz c " + c.hashCode());
}
}
package p16_porownywanie.v3_equals;
import java.util.Objects;
public class Osoba {
String imie, nazwisko;
int wiek;
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
public String toString() {
return "Osoba [imie=" + imie + ", nazwisko=" + nazwisko + ", wiek=" + wiek + "]";
}
public boolean equals(Object obj) {
if(obj == null || ! (obj instanceof Osoba)) {
return false;
}
Osoba inna = (Osoba)obj;
return Objects.equals(this.imie, inna.imie)
&& Objects.equals(this.nazwisko, inna.nazwisko)
&& this.wiek == inna.wiek;
}
// Formalnym wymaganiem wobec hashCode jest:
// jeśli dwa obiekty są równe (equals), to hashcode'y muszą być równe
// Natomiast dla zwiększenia wydajności jeśli obiekty są różne,
// to z dużym pradopodobieństwem hashcody powinny być różne.
public int hashCode() {
return 0;
}
}
package p16_porownywanie.v3_equals;
import java.util.Objects;
public class Porownywanie {
// Jeśli w klasie nie zdefiniujemy metody equals, to używana jest domyślna implementacja pochodząca z klasy Object,
// która porównuje adresy (działa jak ==).
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// == sprawdza cz yto jest ten sam adres
System.out.println("a == a " + (a == a));
System.out.println("a == r " + (a == r));
System.out.println("a == b " + (a == b));
System.out.println("a == c " + (a == c));
System.out.println();
System.out.println("a.equals(a) " + (a.equals(a)));
System.out.println("a.equals(r) " + (a.equals(r)));
System.out.println("a.equals(b) " + (a.equals(b)));
System.out.println("a.equals(c) " + (a.equals(c)));
System.out.println();
System.out.println("Obj a a " + Objects.equals(a, a));
System.out.println("Obj a r " + Objects.equals(a, r));
System.out.println("Obj a b " + Objects.equals(a, b));
System.out.println("Obj a c " + Objects.equals(a, c));
System.out.println();
}
}
package p16_porownywanie.v3_equals;
import java.util.Set;
import java.util.TreeSet;
public class ZbiorDrzewowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// TreeSet oraz TreeMap w działaniu korzystają z metody compareTo (ewentualnie z komparatora).
// Ten program kończy sie błędem, bo Osoba nie jest Comparable.
boolean wynik;
Set<Osoba> zbior = new TreeSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v3_equals;
import java.util.HashSet;
import java.util.Set;
public class ZbiorHaszowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// HashSet oraz HashMap w działaniu korzystają z metod hashCode i equals.
boolean wynik; // wynik operacji add: jeśli element został dodany to true, a jeśli nie to false
Set<Osoba> zbior = new HashSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v4_equals_generowany;
public class HaszKody {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// Jeśli w klasie nie nadpiszemy metody hashCode, to działa domyślna implementacja
// wyliczająca hashcode na podstawie adresu.
// Daje to efekt, że haszkody różnych obiektów są różne.
// Dopóki nie tworzymy miliardów obiektów, to hashcody będą unikalne.
System.out.println("hasz a " + a.hashCode());
System.out.println("hasz r " + r.hashCode());
System.out.println("hasz b " + b.hashCode());
System.out.println("hasz c " + c.hashCode());
}
}
package p16_porownywanie.v4_equals_generowany;
public class Osoba {
String imie, nazwisko;
int wiek;
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
@Override
public String toString() {
return "Osoba [imie=" + imie + ", nazwisko=" + nazwisko + ", wiek=" + wiek + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((imie == null) ? 0 : imie.hashCode());
result = prime * result + ((nazwisko == null) ? 0 : nazwisko.hashCode());
result = prime * result + wiek;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
// lepiej tak sprawdzać klasę niż za pomocą instanceof
if (getClass() != obj.getClass())
return false;
Osoba other = (Osoba) obj;
if (imie == null) {
if (other.imie != null)
return false;
} else if (!imie.equals(other.imie))
return false;
if (nazwisko == null) {
if (other.nazwisko != null)
return false;
} else if (!nazwisko.equals(other.nazwisko))
return false;
if (wiek != other.wiek)
return false;
return true;
}
}
package p16_porownywanie.v4_equals_generowany;
import java.util.Objects;
public class Porownywanie {
// Jeśli w klasie nie zdefiniujemy metody equals, to używana jest domyślna implementacja pochodząca z klasy Object,
// która porównuje adresy (działa jak ==).
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// == sprawdza cz yto jest ten sam adres
System.out.println("a == a " + (a == a));
System.out.println("a == r " + (a == r));
System.out.println("a == b " + (a == b));
System.out.println("a == c " + (a == c));
System.out.println();
System.out.println("a.equals(a) " + (a.equals(a)));
System.out.println("a.equals(r) " + (a.equals(r)));
System.out.println("a.equals(b) " + (a.equals(b)));
System.out.println("a.equals(c) " + (a.equals(c)));
System.out.println();
System.out.println("Obj a a " + Objects.equals(a, a));
System.out.println("Obj a r " + Objects.equals(a, r));
System.out.println("Obj a b " + Objects.equals(a, b));
System.out.println("Obj a c " + Objects.equals(a, c));
System.out.println();
}
}
package p16_porownywanie.v4_equals_generowany;
import java.util.Set;
import java.util.TreeSet;
public class ZbiorDrzewowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// TreeSet oraz TreeMap w działaniu korzystają z metody compareTo (ewentualnie z komparatora).
// Ten program kończy sie błedem, bo Osoba nie jest Comparable
boolean wynik;
Set<Osoba> zbior = new TreeSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v4_equals_generowany;
import java.util.HashSet;
import java.util.Set;
public class ZbiorHaszowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// HashSet oraz HashMap w działaniu korzystają z metod hashCode i equals.
boolean wynik; // wynik operacji add: jeśli element został dodany to true, a jeśli nie to false
Set<Osoba> zbior = new HashSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v5_equals_oraz_comparable;
public class HaszKody {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// Jeśli w klasie nie nadpiszemy metody hashCode, to działa domyślna implementacja
// wyliczająca hashcode na podstawie adresu.
// Daje to efekt, że haszkody różnych obiektów są różne.
// Dopóki nie tworzymy miliardów obiektów, to hashcody będą unikalne.
System.out.println("hasz a " + a.hashCode());
System.out.println("hasz r " + r.hashCode());
System.out.println("hasz b " + b.hashCode());
System.out.println("hasz c " + c.hashCode());
}
}
package p16_porownywanie.v5_equals_oraz_comparable;
import java.util.Comparator;
import java.util.Objects;
public class Osoba implements Comparable<Osoba> {
String imie, nazwisko;
int wiek;
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public int getWiek() {
return wiek;
}
@Override
public String toString() {
return "Osoba [imie=" + imie + ", nazwisko=" + nazwisko + ", wiek=" + wiek + "]";
}
@Override
public int hashCode() {
return Objects.hash(imie, nazwisko, wiek);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Osoba other = (Osoba) obj;
return Objects.equals(imie, other.imie) && Objects.equals(nazwisko, other.nazwisko) && wiek == other.wiek;
}
@Override
public int compareTo(Osoba inna) {
return komparator.compare(this, inna);
}
private final static Comparator<Osoba> komparator =
Comparator.comparing(Osoba::getNazwisko)
.thenComparing(Osoba::getImie)
.thenComparing(Osoba::getWiek);
}
package p16_porownywanie.v5_equals_oraz_comparable;
import java.util.Objects;
public class Porownywanie {
// Jeśli w klasie nie zdefiniujemy metody equals, to używana jest domyślna implementacja pochodząca z klasy Object,
// która porównuje adresy (działa jak ==).
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// == sprawdza cz yto jest ten sam adres
System.out.println("a == a " + (a == a));
System.out.println("a == r " + (a == r));
System.out.println("a == b " + (a == b));
System.out.println("a == c " + (a == c));
System.out.println();
System.out.println("a.equals(a) " + (a.equals(a)));
System.out.println("a.equals(r) " + (a.equals(r)));
System.out.println("a.equals(b) " + (a.equals(b)));
System.out.println("a.equals(c) " + (a.equals(c)));
System.out.println();
System.out.println("Obj a a " + Objects.equals(a, a));
System.out.println("Obj a r " + Objects.equals(a, r));
System.out.println("Obj a b " + Objects.equals(a, b));
System.out.println("Obj a c " + Objects.equals(a, c));
System.out.println();
}
}
package p16_porownywanie.v5_equals_oraz_comparable;
import java.util.Set;
import java.util.TreeSet;
public class ZbiorDrzewowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// TreeSet oraz TreeMap w działaniu korzystają z metody compareTo (ewentualnie z komparatora).
// Ten program kończy sie błedem, bo Osoba nie jest Comparable
boolean wynik;
Set<Osoba> zbior = new TreeSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p16_porownywanie.v5_equals_oraz_comparable;
import java.util.HashSet;
import java.util.Set;
public class ZbiorHaszowy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 20);
Osoba r = a;
Osoba b = new Osoba("Ala", "Kowalska", 20);
Osoba c = new Osoba("Ola", "Kowalska", 30);
// HashSet oraz HashMap w działaniu korzystają z metod hashCode i equals.
boolean wynik; // wynik operacji add: jeśli element został dodany to true, a jeśli nie to false
Set<Osoba> zbior = new HashSet<>();
wynik = zbior.add(a);
System.out.println("a " + wynik);
wynik = zbior.add(r);
System.out.println("r " + wynik);
wynik = zbior.add(b);
System.out.println("b " + wynik);
wynik = zbior.add(c);
System.out.println("c " + wynik);
System.out.println();
System.out.println("Ilośc elementów: " + zbior.size());
for (Osoba osoba : zbior) {
System.out.println(osoba);
}
}
}
package p17_generyki.kolekcje;
import java.util.ArrayList;
import java.util.List;
public class DeklaracjeGeneryczne {
public static void main(String[] args) {
List l1 = new ArrayList();
ArrayList l2 = new ArrayList();
List<String> l3 = new ArrayList<String>();
List<String> l4 = new ArrayList<>(); // diamond operator od Javy 7
List<String> l5 = new ArrayList();
List l6 = new ArrayList<>(); // lista Object-ów
List l6a = new ArrayList<String>();
//NK List<> l7 = new ArrayList<String>();
List<List<Integer>> l8 = new ArrayList<>();
//NK List<List<Integer>> l9 = new ArrayList<<>>();
//NK List<List<Integer>> l10 = new ArrayList<List<>>();
List<List<Integer>> l11 = new ArrayList<List<Integer>>();
//NK List<Object> l12 = new ArrayList<String>();
//NK List<String> l13 = new ArrayList<Object>();
List<? extends Object> l14 = new ArrayList<String>();
List<?> l15 = new ArrayList<String>(); // sam ? jest równoważny ? extends Object
//NK List<?> foo1 = new ArrayList<? extends Number>();
//NK List<?> foo2 = new ArrayList<? super Number>();
//NK List<?> foo3 = new ArrayList<?>();
}
}
package p17_generyki.kolekcje;
import java.util.ArrayList;
import java.util.List;
public class OszukiwanieGenerykow {
public static void main(String[] args) {
List<String> lista = new ArrayList<String>();
Integer i = 99;
lista.add("Ala");
//NK lista.add(7);
//NK lista.add(i);
List oszust = lista;
oszust.add("Ola");
oszust.add(i); // tu nie jeszcze błędu
oszust.add(8);
System.out.println(lista.size());
System.out.println(lista);
for(Object o : lista) {
System.out.println(o + " obiekt klasy " + o.getClass().getSimpleName());
}
System.out.println();
for(String s : lista) { // dopiero tu jest błąd CCE gdy dojdziemy do Integera
System.out.println(s);
}
}
}
package p17_generyki.kolekcje;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class OszukiwanieGenerykow2 {
static void metodaOszukujaca(List<String> lista) {
List oszust = lista;
oszust.add(new Integer(113));
}
public static void main(String[] args) {
List<String> lista1 = new ArrayList<String>();
lista1.add("Ala");
lista1.add("Ola");
System.out.println(lista1);
metodaOszukujaca(lista1);
System.out.println(lista1);
System.out.println();
List<String> lista2 = new ArrayList<String>();
List<String> listaZabezpieczona = Collections.checkedList(lista2, String.class);
// checkedList daje zachowanie typu "fail-fast" - od razu w momencie wykonanie niepoprawnej operacji następuje wyjątek
lista2.add("Ela");
listaZabezpieczona.add("Ula");
// listaZabezpieczona jest "widokiem" listy oryginalnej
// zmiany dokonywane poprzez jedną zmienną są widziane przez drugą
System.out.println(lista2);
System.out.println(listaZabezpieczona);
metodaOszukujaca(listaZabezpieczona); // teraz będzie wyjątek już przy próbie dodania niezgodnego elementu
System.out.println(lista2);
}
}
package p17_generyki.kolekcje;
import java.util.ArrayList;
import java.util.List;
public class Polimorfizm1 {
static double testPojedynczego(Number arg) {
return arg.doubleValue();
}
static double suma1(List<Number> lista) {
double wynik = 0.0;
for (Number number : lista) {
wynik += number.doubleValue();
}
return wynik;
}
static void modyfikuj1(List<Number> lista) {
lista.add(Long.valueOf(10_000_000_000L));
}
static double suma2(List<? extends Number> lista) {
//NK lista.add(Long.valueOf(10_000_000_000L));
double wynik = 0.0;
for (Number number : lista) {
wynik += number.doubleValue();
}
return wynik;
}
static void modyfikuj2(List<? super Long> lista) {
lista.add(Long.valueOf(10_000_000_000L));
}
/** Zamienia pierwszy element z ostatnim i zwraca ich średnią */
static <T extends Number> double sredniaZZamiana(List<T> lista) {
T pierwszy = lista.get(0);
T ostatni = lista.get(lista.size()-1);
lista.set(0, ostatni);
lista.set(lista.size()-1, pierwszy);
return (pierwszy.doubleValue() + ostatni.doubleValue()) / 2.0;
}
/* to się nie kompilowało, bo wewnątrz funkcji o elementach listy było wiadomo tlyko,
* że są to jakieś Numbery - a to za mało aby wpisać do listy niewiadomoczego
* Lista mogłaby być listą Integerów, a zmienne pierwszy i ostatni sa typu Number. */
/*
static double sredniaZZamiana2(List<? extends Number> lista) {
Number pierwszy = lista.get(0);
Number ostatni = lista.get(lista.size()-1);
lista.set(0, ostatni);
lista.set(lista.size()-1, pierwszy);
return (pierwszy.doubleValue() + ostatni.doubleValue()) / 2.0;
}
*/
/*
static double sredniaZZamiana3(List<? super Number> lista) {
Number pierwszy = lista.get(0);
Number ostatni = lista.get(lista.size()-1);
lista.set(0, ostatni);
lista.set(lista.size()-1, pierwszy);
return (pierwszy.doubleValue() + ostatni.doubleValue()) / 2.0;
}
*/
/* //Takiej składni nie ma:
static <T super Number> void metoda3(List<T> lista) {
}
*/
// Sam znak zapytania jest równoważny <? extends Object> - co nie wnosi żadnej wiedzy
// "lista czegokolwiek"
// To nie jest to samo co List<Object> !!!
// bo wtedy nie dałoby się przekazać np. List<Integer>
// To też nie jest to samo co po prostu List.
static int metoda4a(List<Object> lista) {
return lista == null ? 0 : lista.size();
}
static int metoda4(List<?> lista) {
return lista == null ? 0 : lista.size();
}
static void metoda5(List<?> lista) {
// z takiej listy można odczytywać elementy - są dla nas Objectami
Object o = lista.get(0);
// do takiej listy nie możemy wstawić niczego innego niż null
// być może jest to lista Integerów? albo Stringów? nie wiadomo - na wszelki wypadek kompilator zabrania wstawiać czegokolwiek-
//NK lista.add(new Object());
// null pasuje do każdego typu
lista.add(null);
}
public static void main(String[] args) {
double wynik;
Number nn = new Long(123L);
Integer ii = new Integer(321);
wynik = testPojedynczego(nn);
System.out.println(wynik);
wynik = testPojedynczego(ii);
System.out.println(wynik);
System.out.println();
List<Number> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
System.out.println(numbers);
List<Integer> ints = new ArrayList<>();
ints.add(11);
ints.add(21);
ints.add(31);
ints.add(41);
System.out.println(ints);
wynik = suma1(numbers);
System.out.println(wynik);
System.out.println();
// Gdy metoda oczekuje listy Numberów, nie można przekazać listy Integerów
// wynik = suma1(ints);
// System.out.println(wynik);
// System.out.println();
// Do listy Numberów można dodać Longa - OK
modyfikuj1(numbers);
System.out.println(numbers);
// Gdyby można było przekazywać, to to wywołanie zepsułoby listę Integerów
// - na takiej liście znalazłby się Long
// modyfikuj1(ints);
// System.out.println(ints);
System.out.println();
// Nie wolno też przypisać List<Integer> na zmienną List<Number>
//NK List<Integer> ints2 = numbers;
wynik = suma2(numbers);
System.out.println(wynik);
System.out.println();
wynik = suma2(ints);
System.out.println(wynik);
System.out.println();
modyfikuj2(numbers);
System.out.println(numbers);
// modyfikuj2(ints);
// System.out.println(ints);
//NK metoda4a(ints); // List<Object>
metoda4(ints); // List<?>
}
}
package p17_generyki.kolekcje;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Polimorfizm2 {
// Przykład funkcji, która zadziała dla dowolnej listy - typ elementu w ogóle nieistotny
static void usunOstatni(List<?> lista) {
int size = lista.size();
if(size > 0) {
lista.remove(size-1);
}
}
// Do tak zadeklarowanej funkcji będzie można przekazać tylko listę Objectów
// (konkretnie List<Object>, nic innego)
static void usunOstatniZle(List<Object> lista) {
int size = lista.size();
if(size > 0) {
lista.remove(size-1);
}
}
public static void main(String[] args) {
List<String> listaStringow = new ArrayList<>();
List<Integer> listaIntow = new ArrayList<>();
List<LocalDate> listaDat = new ArrayList<>();
List<?> lista1 = new ArrayList<>();
// do tak zadeklarowanej listy nie można dodać niczego
// lista1.add("ala");
// OK, można dodać nulla
lista1.add(null);
// Dlaczego?
// List<?> jest równoważna takiej:
List<? extends Object> lista2 = new ArrayList<>();
// lista2.add("ala");
lista2.add(null);
// To znaczy, że na taką zmienną można wpisać dowolną listę:
lista2 = listaDat;
// czy można wpisać Stringa na taką listę?
// kompilator zabrania wstawiać czegokolwiek - chodzi o tym zmiennej, a nie listy w pamięci
// lista2.add("ala");
lista2 = listaIntow;
lista1 = listaDat;
lista1 = listaIntow;
for (Object object : lista1) {
// podczas czytania elementy widzimy jako Objecty
}
Class<Polimorfizm2> klasa1 = Polimorfizm2.class;
//NK Class<Polimorfizm2> klasa2 = String.class;
Class<?> klasa3 = Polimorfizm2.class;
Class<?> klasa4 = String.class;
Class<? extends Number> klasa5;
klasa5 = Integer.class;
klasa5 = Long.class;
klasa5 = Number.class;
//NK klasa5 = String.class;
}
}
package p17_generyki.kolekcje;
import java.util.Arrays;
public class Polimorfizm3_Tablice {
static double suma(Number[] t) {
double suma = 0.0;
for (Number number : t) {
suma += number.doubleValue();
}
return suma;
}
static void modyfikuj(Number[] t) {
t[0] = new Long(10_000_000_000L);
}
public static void main(String[] args) {
Number[] numbers = new Number[] {10, 20, 30, 40, 50};
Integer[] ints = new Integer[] {11, 21, 31, 41};
Number[] numbers2 = ints;
//NK Integer[] ints2 = numbers2;
double wynik;
wynik = suma(numbers);
System.out.println(wynik);
// jesli chodzi o tablicę, to tablica podklas jest traktowana jak podklasa tablicy nadklas
wynik = suma(ints);
System.out.println(wynik);
System.out.println();
modyfikuj(numbers);
System.out.println(Arrays.toString(numbers));
modyfikuj(ints);
System.out.println(Arrays.toString(ints));
}
}
package p17_generyki.techniczne;
public class GdzieMoznaUzywacGenerykow {
private static class Box<T> {
// Parametru generycznego można używać:
// typ zmiennej instanyjnej
T x, y;
// typ paraterów i wyniku metod instancyjnych:
T metoda(T parametr, String innyParametr) {
// typ zmiennej lokalnej wewnątrz metody instancyjnej:
T zmienna = parametr;
if(zmienna == null) {
zmienna = x;
}
return zmienna;
}
// Parametru generycznego nie można używać:
// w kontekście statycznym
// static T statyczna;
// static T metodaStatyczna(T arg) {
// return arg;
// }
static void normalnaMetodaStatyczna() {
// T zmienna = null;
}
void test(T arg1, Object arg2) {
// Parametru generycznego nie można używać również w poleceniach,
// które wymagałyby znajomości tego typu w runtajmie:
// System.out.println(T.class);
System.out.println(x.getClass());
// if(arg1 instanceof T) {
//
// }
//
// if(arg2 instanceof T) {
//
// }
// rzutowanie można zapisać, ale nie ma jak sprawdzić w instaceof czy to bezpieczne
T t = (T)arg2;
System.out.println(t);
}
}
}
package p17_generyki.techniczne;
import java.time.LocalDate;
public class MetodyInstancyjne<A> {
// Metody mogą być parametryzowane typami generycznymi - każda niezależnie.
// Te parametry nie mają nic wspólnego z parametreami na poziomie klasy, w której jesteśmy (gdyby takie były).
A aaa(A a) {
System.out.println("a = " + a);
return a;
}
// A jest parametrem ustalonym na poziomie klasy, a B na poziomie metody
<B> B bbb(A a, B b) {
System.out.println("a = " + a + " , b = " + b);
return b;
}
// Parametr podany na poziomie metody może przesłonić parametr podany na poziomie klasy
<A> A ccc(A a) {
System.out.println("a = " + a);
return a;
}
public static void main(String[] args) {
MetodyInstancyjne<String> instancjaString = new MetodyInstancyjne<>();
MetodyInstancyjne<Integer> instancjaInteger = new MetodyInstancyjne<>();
String s1 = instancjaString.aaa("Ala");
System.out.println(s1);
// LocalDate s2 = instancjaString.aaa(LocalDate.now());
// Na pierwszym parametrze musi być String,
// na drugim może być cokolwiek. Typ metody mówi, że wynik jest tego samego typu, co drugi argument.
String s3 = instancjaString.bbb("Ala", "Ola");
System.out.println(s3);
LocalDate s4 = instancjaString.bbb("Ala", LocalDate.now());
System.out.println(s4);
LocalDate s5 = instancjaInteger.bbb(123, LocalDate.now());
System.out.println(s5);
LocalDate s6 = instancjaString.ccc(LocalDate.now());
System.out.println(s6);
}
}
package p17_generyki.techniczne;
import java.util.Optional;
import p17_generyki.v2_generics.Para;
public class MetodyStatyczne {
// Metody mogą być parametryzowane typami generycznymi - każda niezależnie.
// Te parametry nie mają nic wspólnego z parametreami na poziomie klasy, w której jesteśmy (gdyby takie były).
// Można to robić zarówno dla metod statycznych (w praktyce znacznie częściej),
// jak i dla instancyjnych.
static <T> T ident(T arg) {
return arg;
}
static <T> Optional<T> opakuj(T arg) {
if (arg == null) {
return Optional.empty();
} else {
return Optional.of(arg);
}
}
static <T> T dajNulla() {
return null;
}
static <L, R> void wypisz(Para<L,R> para) {
System.out.println(para);
}
static <L, R> Para<R,L> zamien(Para<L,R> para) {
return new Para<>(para.getPrawy(), para.getLewy());
}
public static void main(String[] args) {
String s, z;
s = "Ala";
z = ident(s);
System.out.println(z);
System.out.println(opakuj(s));
System.out.println(opakuj(null));
}
}
package p17_generyki.v1_object;
import java.util.ArrayList;
public class KolekcjeBezGenerykow {
public static void main(String[] args) {
ArrayList lista = new ArrayList();
lista.add("Ala");
lista.add("Ola");
lista.add(new Integer(50));
System.out.println(lista);
// W momencie wyjęcia obiektu z kolekcji, trzeba było dokonać rzutowania.
String imie = (String)lista.get(1);
System.out.println(imie);
//EXN CCE imie = (String) lista.get(2);
// System.out.println(imie);
}
}
package p17_generyki.v1_object;
import java.util.Objects;
/* Wersja bez typów generycznych - programowanie jak w Javie <= 1.4 */
public class Para {
private Object lewy;
private Object prawy;
public Para() {
}
public Para(Object lewy, Object prawy) {
this.lewy = lewy;
this.prawy = prawy;
}
public Object getLewy() {
return lewy;
}
public void setLewy(Object lewy) {
this.lewy = lewy;
}
public Object getPrawy() {
return prawy;
}
public void setPrawy(Object prawy) {
this.prawy = prawy;
}
@Override
public String toString() {
return "<" + lewy + ", " + prawy + ">";
}
@Override
public int hashCode() {
return Objects.hash(lewy, prawy);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Para other = (Para) obj;
return Objects.equals(lewy, other.lewy) && Objects.equals(prawy, other.prawy);
}
}
package p17_generyki.v1_object;
import java.util.Objects;
/* Wersja bez typów generycznych - programowanie jak w Javie <= 1.4.
*
* Istnieje możliwość tworzenia osobnych klas w zlaeżnośc iod tego, co będą miały w środku.
* Ale to pracochłonne i redundantne.
*/
public class ParaIntegerow {
private Integer lewy;
private Integer prawy;
public ParaIntegerow() {
}
public ParaIntegerow(Integer lewy, Integer prawy) {
this.lewy = lewy;
this.prawy = prawy;
}
public Integer getLewy() {
return lewy;
}
public void setLewy(Integer lewy) {
this.lewy = lewy;
}
public Integer getPrawy() {
return prawy;
}
public void setPrawy(Integer prawy) {
this.prawy = prawy;
}
@Override
public String toString() {
return "<" + lewy + ", " + prawy + ">";
}
@Override
public int hashCode() {
return Objects.hash(lewy, prawy);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ParaIntegerow other = (ParaIntegerow) obj;
return Objects.equals(lewy, other.lewy) && Objects.equals(prawy, other.prawy);
}
}
package p17_generyki.v1_object;
import java.time.LocalDate;
public class Test1 {
public static void main(String[] args) {
Para para1 = new Para("Ala", 33);
System.out.println(para1);
// problem1: odczytując dostaję ogólny typ Object i muszę dokonać rzutowania:
String imie = (String) para1.getLewy();
int wiek = (Integer) para1.getPrawy();
System.out.println(imie + " : " + wiek);
// problem2: brak kontroli typów podczas zapisywania (przekazywania parametrów):
para1.setPrawy(LocalDate.now());
// łatwo się pomylić co do typu obiektu
wiek = (Integer) para1.getPrawy(); // EXN
System.out.println(wiek);
}
}
package p17_generyki.v2_generics;
import java.util.Objects;
/*
* Zazwyczaj nazwy parametrów typowych są jednoliterowe (T, R, ...),
* ale z punktu widzenia składni Javy są to po prostu identyfikatory.
*/
public class Para<Lewy, Prawy> {
private Lewy lewy;
private Prawy prawy;
public Para() {
}
public Para(Lewy lewy, Prawy prawy) {
this.lewy = lewy;
this.prawy = prawy;
}
public Lewy getLewy() {
return lewy;
}
public void setLewy(Lewy lewy) {
this.lewy = lewy;
}
public Prawy getPrawy() {
return prawy;
}
public void setPrawy(Prawy prawy) {
this.prawy = prawy;
}
@Override
public String toString() {
return "<" + lewy + ", " + prawy + ">";
}
@Override
public int hashCode() {
return Objects.hash(lewy, prawy);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Para other = (Para) obj;
return Objects.equals(lewy, other.lewy) && Objects.equals(prawy, other.prawy);
}
}
package p17_generyki.v2_generics;
public class Test1 {
public static void main(String[] args) {
Para<String, Integer> para1 = new Para<String, Integer>("Ala", 33);
System.out.println(para1);
// Podczas odczytywania nie trzeba rzutować.
String imie = para1.getLewy();
Integer wiek = para1.getPrawy();
System.out.println(imie + " : " + wiek);
// Tym razem taka próba się nie skompiluje
// para1.setPrawy(LocalDate.now());
// Poszczególne instancje mogą mieć różnie ustalone parametry generyczne.
Para<Integer, Integer> para2 = new Para<>();
para2.setLewy(13);
para2.setPrawy(13);
System.out.println(para2);
System.out.println();
// Na etapie kompilacji zmienne para1 i para2 są różnego typu
//NK para1 = para2;
// Jednak w runtime klasa tych obiektów jest taka sama.
System.out.println(para1.getClass());
System.out.println(para2.getClass());
System.out.println(para1.getClass() == para2.getClass());
}
}
package p17_generyki.v3_para_liczb_bez_generykow;
import java.util.Objects;
/*
* Zazwyczaj nazwy parametrów typowych są jednoliterowe (T, R, ...),
* ale z punktu widzenia składni Javy są to po prostu identyfikatory.
*/
public class Para<Lewy, Prawy> {
private Lewy lewy;
private Prawy prawy;
public Para() {
}
public Para(Lewy lewy, Prawy prawy) {
this.lewy = lewy;
this.prawy = prawy;
}
public Lewy getLewy() {
return lewy;
}
public void setLewy(Lewy lewy) {
this.lewy = lewy;
}
public Prawy getPrawy() {
return prawy;
}
public void setPrawy(Prawy prawy) {
this.prawy = prawy;
}
@Override
public String toString() {
return "<" + lewy + ", " + prawy + ">";
}
@Override
public int hashCode() {
return Objects.hash(lewy, prawy);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Para other = (Para) obj;
return Objects.equals(lewy, other.lewy) && Objects.equals(prawy, other.prawy);
}
}
package p17_generyki.v3_para_liczb_bez_generykow;
import java.util.Objects;
public class ParaLiczb {
private Number lewy;
private Number prawy;
public ParaLiczb() {
}
public ParaLiczb(Number lewy, Number prawy) {
this.lewy = lewy;
this.prawy = prawy;
}
public Number getLewy() {
return lewy;
}
public void setLewy(Number lewy) {
this.lewy = lewy;
}
public Number getPrawy() {
return prawy;
}
public void setPrawy(Number prawy) {
this.prawy = prawy;
}
@Override
public String toString() {
return "<" + lewy + ", " + prawy + ">";
}
@Override
public int hashCode() {
return Objects.hash(lewy, prawy);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ParaLiczb other = (ParaLiczb) obj;
return Objects.equals(lewy, other.lewy) && Objects.equals(prawy, other.prawy);
}
// Wiedza, że elementy są jakimiś liczbami daje mi możliwości definiowania operacji matematycznych,
// przykładowo średnia.
// Nie byłoby to możliwe w klasie takiej jak Para
public double getSrednia() {
return (lewy.doubleValue() + prawy.doubleValue()) / 2.0;
}
}
package p17_generyki.v3_para_liczb_bez_generykow;
public class Test2 {
public static void main(String[] args) {
ParaLiczb para1 = new ParaLiczb(new Integer(13), new Integer(3000));
// Przy takim podejściu mogę odczytywane wartości potraktować jak Number:
Number lewy = para1.getLewy();
// Ale nie mogę założyć że to będzie np. Integer
// Integer lewyi = para1.getLewy();
Integer lewyi = (Integer) para1.getLewy();
System.out.println(para1.getSrednia());
// Mogę też wstawić dowolny Number, kompilator nie sprawdzi czy to Integer
// A jeśli chciałbym, aby w tej konkretnej parze były Integery?
para1.setLewy(new Double(3.14));
System.out.println(para1.getSrednia());
// Jednocześnie uzywanie ogólnej Pary nie daje mi wiedzy o tym, że tam są na pewno liczby
Para<Integer, Integer> para = new Para<>(3,4);
System.out.println(para);
// System.out.println(para.getSrednia());
}
}
package p17_generyki.v4_para_liczb_extends;
import java.util.Objects;
// Za pomocą ograniczeń "extends" oraz "super" możemy wymusić, że parametr typowy
// spełnia pewne warunki.
// W tym przypadku T extends Number oznacza, że T to może byc Number, Integer, Double itd., ale nie String, Object czy inne typy
public class ParaLiczb<T extends Number> {
private T lewy;
private T prawy;
public ParaLiczb() {
}
public ParaLiczb(T lewy, T prawy) {
this.lewy = lewy;
this.prawy = prawy;
}
public T getLewy() {
return lewy;
}
public void setLewy(T lewy) {
this.lewy = lewy;
}
public T getPrawy() {
return prawy;
}
public void setPrawy(T prawy) {
this.prawy = prawy;
}
@Override
public String toString() {
return "<" + lewy + ", " + prawy + ">";
}
@Override
public int hashCode() {
return Objects.hash(lewy, prawy);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ParaLiczb other = (ParaLiczb) obj;
return Objects.equals(lewy, other.lewy) && Objects.equals(prawy, other.prawy);
}
// Wiedza, że elementy są jakimiś liczbami daje mi możliwości definiowania operacji matematycznych,
// przykładowo średnia.
// Nie byłoby to możliwe w klasie takiej jak Para
public double getSrednia() {
return (lewy.doubleValue() + prawy.doubleValue()) / 2.0;
}
}
package p17_generyki.v4_para_liczb_extends;
import java.math.BigDecimal;
public class Test2 {
public static void main(String[] args) {
ParaLiczb<Integer> para1 = new ParaLiczb<>(new Integer(13), new Integer(3000));
System.out.println(para1);
Number lewy = para1.getLewy();
Integer lewyi = para1.getLewy();
//NK para1.setLewy(new Double(3.14));
para1.setLewy(new Integer(44));
// Wiedząc, że jest to para liczb, mogę korzystać z operacji matematycznych
double avg = para1.getSrednia();
System.out.println(avg);
ParaLiczb<BigDecimal> para2 = new ParaLiczb<>(BigDecimal.ONE, new BigDecimal("3.99"));
System.out.println(para2);
avg = para2.getSrednia();
System.out.println(avg);
// Wymagane jest, aby typ był Number albo jego podklasą
//NK ParaLiczb<String> para3 = new ParaLiczb<>();
}
}
package p18_wrappery;
import java.util.concurrent.atomic.AtomicInteger;
public class Parametry {
static void test(int i, Integer j, AtomicInteger k) {
i += 5;
j += 6; // to nie zmienia wartości wewnątrz obiektu, tylko tworzy nowy obiekt
// tak jakby: j = new Integer(j.intValue() + 6);
k.addAndGet(7);
System.out.println("i: " + i + " , j: " + j + " , k: " + k);
}
public static void main(String[] args) {
int x = 100;
Integer y = 200;
// Integer y = new Integer(200); // zadziała tak samo
AtomicInteger z = new AtomicInteger(300);
System.out.println("x: " + x + " , y: " + y + " , z: " + z);
test(x, y, z);
System.out.println("x: " + x + " , y: " + y + " , z: " + z);
}
}
package p18_wrappery;
public class Wrappery1_Podstawy {
public static void main(String[] args) {
// Dla każdego z 8 typów prostych istnieje odpowiadająca mu klasa ("opakowaniowa"?), tzw. "wrapper".
// Obiekt klasy wrapper zawiera w sobie wartość danego typu.
// Wszystkie klasy wrapperów są NIEMUTOWALNE, tzn. wartość w obiekcie nigdy nie ulega zmianie; /na zmienną typu wrapper można wpisać nowy obiekt, ale to nie to samo./
int i = 103;
// Obiekt klasy opakowaniowej na podstawie wartości można utworzyć:
// - za pomocą konstruktora (obecnie niezalecane)
Integer ii1 = new Integer(i);
// - za pomocą metody valueOf
Integer ii2 = Integer.valueOf(i);
// - za pomocą automatycznej konwersji (autoboxing, od Javy 5); wewnętrznie jest to realizowane za pomocą valueOf
Integer ii3 = i;
byte y = 15;
Byte yy1 = new Byte(y);
Byte yy2 = Byte.valueOf(y);
Byte yy3 = y;
short s = 10_000;
Short ss1 = new Short(s);
Short ss2 = Short.valueOf(s);
Short ss3 = s;
long l = 4_000_000L;
Long ll1 = new Long(l);
Long ll2 = Long.valueOf(l);
Long ll3 = l;
float f = 3.14F;
Float ff1 = new Float(f);
Float ff2 = Float.valueOf(f);
Float ff3 = f;
double d = 1.4142;
Double dd1 = new Double(d);
Double dd2 = Double.valueOf(d);
Double dd3 = d;
char c = 'A';
Character cc1 = new Character(c);
Character cc2 = Character.valueOf(c);
Character cc3 = c;
boolean b = true;
Boolean bb1 = new Boolean(b);
Boolean bb2 = Boolean.valueOf(b);
Boolean bb3 = b;
// Dodatkowo istnieje klasa Void, odpowiadająca typowi void.
// Nie da się utworzyć obiektu tej klasy.
Void v = null;
}
}
package p18_wrappery;
import java.util.ArrayList;
import java.util.List;
public class Wrappery2_Zastosowania {
public static void main(String[] args) {
// Zastosowania wrapperów.
// 1) Stałe i metody statyczne zdefiniowane w klasie
String liczbaTekstowo = "12345";
int liczba = Integer.parseInt(liczbaTekstowo);
Integer obiekt = Integer.valueOf(liczbaTekstowo);
System.out.println(liczba * 2);
System.out.printf("Typ %s ma %d bajty, czyli %d bity, minimalna wartość to %d, a maksymalna %d\n",
Integer.TYPE.getSimpleName(), Integer.BYTES, Integer.SIZE, Integer.MIN_VALUE, Integer.MAX_VALUE);
// 2) Obiekt jako "wartość opcjonalna".
// Zmienna/funkcja typu int MUSI mieć/zwracać jakąś wartość. Każdy ciąg bitów w zmiennej typu prostego oznacza jakąś konkretną wartość.
// Zmienna typu obiektowego może wskazywać na obiekt LUB mieć wartość null. null może być traktowany jako dodatkowa wartość oznaczająca brak danych/brak wyniku
// Współcześnie bardziej zalecane do tego celu jest używanie klas Optional (np. OptionalInt), ale tradycyjnie używało się wrapperów i w wielu miejscach to pozostało.
int[] a = {13, 7, 14, 3, 12};
int[] b = {13, 7, 3, 9, -5};
Integer wynik1 = pierwszaParzysta(a);
if(wynik1 != null) {
System.out.println("pierwszy wynik: " + wynik1);
} else {
System.out.println("brak pierwszego wyniku");
}
Integer wynik2 = pierwszaParzysta(b);
if(wynik2 != null) {
System.out.println("drugi wynik: " + wynik2);
} else {
System.out.println("brak drugiego wyniku");
}
// 3) Kolekcje i bardziej ogólnie deklaracje typów generycznych.
// nie da rady: List<int> listaLiczb1 = new ArrayList<>();
List<Integer> listaLiczb = new ArrayList<>();
for(int x : a) {
listaLiczb.add(x);
}
System.out.println(listaLiczb);
}
public static Integer pierwszaParzysta(int[] tab) {
for(int x : tab) {
if(x % 2 == 0) {
return x;
}
}
return null;
}
}
package p18_wrappery;
// Integer i Long są dużo wolniejsze niż int i long
// z tego powodu używanie List<Integer> jest dużo wolniejsze niż int[]
// Gdy w Javie 8 wymyślano Streamy, stworzono osobne wersje IntStream, DoubleStream, LongStream
// i lepiej ich używać zamiast Stream<Integer> itd.
public class Wrappery3_Wydajnosc {
static Long suma1(int n) {
Long wynik = 0L;
for(Integer i = 1; i <= n; i++) {
wynik += i;
}
return wynik;
}
static long suma2(int n) {
long wynik = 0L;
for(int i = 1; i <= n; i++) {
wynik += i;
}
return wynik;
}
public static void main(String[] args) {
int n = 1_000_000_000;
long p, k;
System.out.println("v1 start");
p = System.currentTimeMillis();
Long wynik1 = suma1(n);
k = System.currentTimeMillis();
System.out.println("v1 wynik: " + wynik1);
System.out.println("czas: " + (k - p));
System.out.println();
System.out.println("v2 start");
p = System.currentTimeMillis();
long wynik2 = suma2(n);
k = System.currentTimeMillis();
System.out.println("v2 wynik: " + wynik2);
System.out.println("czas: " + (k - p));
}
}
package p18_wrappery;
public class Wrappery4_WielkaCiekawostka {
public static void main(String[] args) {
Integer x, y;
x = 100;
y = 100;
System.out.println(x == y);
x = 200;
y = 200;
System.out.println(x == y);
System.out.println();
// wyjasnienie: automatyczny boxing jest robiony za pomocą valueOf:
x = Integer.valueOf(100);
y = Integer.valueOf(100);
System.out.println(x == y);
System.out.println(x.equals(y));
System.out.println();
x = Integer.valueOf(200);
y = Integer.valueOf(200);
System.out.println(x == y);
System.out.println(x.equals(y));
}
}
package p18_wrappery;
import java.util.HashMap;
import java.util.Map;
public class Wrappery5_Null {
static int pomnoz(Integer a) {
return 2*a;
}
static int dodaj(int a) {
return 2*a;
}
public static void main(String[] args) {
Integer x, y;
x = 55;
y = null;
System.out.println(pomnoz(x));
System.out.println(pomnoz(y)); // NPE w środku metody
System.out.println(dodaj(x));
System.out.println(dodaj(y)); // NPE przy przekazywaniu parametru
int z = y; // NPE przy przypisaniu
System.out.println(z);
// bo tak naprawde
int z2 = y.intValue();
// Szczególnie trzeba uważać przy korzystaniu z map:
Map<String, Integer> mapa = new HashMap<>();
mapa.put("Ala", 30);
mapa.put("Ola", 40);
// typy błąd programisty:
// NullPointerException, bo mapa.get zwraca null, a my wpisujemy to na zmienną int
// int wiek = mapa.get("Ula");
// System.out.println(wiek);
Integer wiek2 = mapa.get("Ula");
System.out.println(wiek2);
// teraz operacje liczbowe będą powodowały błedy:
// System.out.println(wiek2 + 1);
}
}
package p18_wrappery;
public class Wrappery6_Number {
public static void main(String[] args) {
Number n = 777;
System.out.println(n.byteValue());
System.out.println(n.shortValue());
System.out.println(n.intValue());
System.out.println(n.longValue());
System.out.println(n.floatValue());
System.out.println(n.doubleValue());
}
}
package p18_wrappery;
public class Wrappery7_Parsowanie {
public static void main(String[] args) {
String tekst = "1234";
// typ wyniku int
int x = Integer.parseInt(tekst);
System.out.println(2*x);
// typ wyniku Integer
Integer y = Integer.valueOf(tekst);
// skompiluje się też, ale mnie wydajne:
int xx = Integer.valueOf(tekst);
Integer yy = Integer.parseInt(tekst);
double d = Double.parseDouble(tekst);
System.out.println(d);
}
}
package p18_wrappery;
import java.util.ArrayList;
import java.util.List;
public class Wrappery8_Lista {
public static void main(String[] args) {
List<String> napisy = new ArrayList<>();
napisy.add("Ala");
napisy.add("Ola");
napisy.add("Ela");
napisy.add("Ula");
System.out.println(napisy);
napisy.remove(2); // usuwa według indeksu, zwraca referencję do usuwanego obiektu
System.out.println(napisy);
napisy.remove("Ala"); // usuwa wg wartości, zwraca boolean mówiący czy element został usunięty
System.out.println(napisy);
System.out.println();
List<Integer> liczby = new ArrayList<>();
liczby.add(4);
liczby.add(8);
liczby.add(1);
liczby.add(5);
liczby.add(13);
liczby.add(12);
liczby.add(5);
liczby.add(1);
System.out.println(liczby);
// liczby.remove(12); // traktowane jako pozycja
Integer co = liczby.remove(0); // traktowane jako pozycja
// System.out.println(liczby);
// traktowane jako obiekt - czyli wartość wpisu
boolean czy = liczby.remove((Object)13);
liczby.remove(new Integer(12));
liczby.remove(Integer.valueOf(5));
System.out.println(liczby);
}
}
package p18_wrappery;
import java.util.ArrayList;
import java.util.Locale;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
public class Wrappery9_WydajnoscList {
// wiekość tablicy
private static final int N = 100_000_000;
// ilość powtórzeń odczytu
private static final int K = 20;
private static void zmierzCzas(String tytul, Runnable procedura) {
System.out.println("\nZaczynam " + tytul);
long start = System.nanoTime();
procedura.run();
long koniec = System.nanoTime();
double czas = (koniec - start) * 1e-9;
System.out.printf(Locale.US, "%s: %10.6f s\n", tytul, czas);
}
private static void wyczysc() {
try {
System.gc();
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
private static void petla() {
long suma = 0L;
for(int k = 0; k < K; k++) {
for(int i = 0; i < N; i++) {
suma += i;
}
}
System.out.println(suma);
}
private static void tablica() {
int[] t = new int[N];
for(int i = 0; i < N; i++) {
t[i] = i;
}
long suma = 0L;
for(int k = 0; k < K; k++) {
for(int x : t) {
suma += x;
}
}
System.out.println(suma);
}
private static void array_list() {
ArrayList<Integer> l = new ArrayList<>();
for(int i = 0; i < N; i++) {
l.add(i);
}
long suma = 0L;
for(int k = 0; k < K; k++) {
for(int x : l) {
suma += x;
}
}
System.out.println(suma);
}
private static void stream_range() {
long suma = 0L;
for(int k = 0; k < K; k++) {
suma += LongStream.range(0, N).sum();
}
System.out.println(suma);
}
private static void stream_tablica() {
int[] t = IntStream.range(0, N).toArray();
long suma = 0L;
for(int k = 0; k < K; k++) {
suma += IntStream.of(t).asLongStream().sum();
}
System.out.println(suma);
}
public static void main(String[] args) {
System.out.println("Startujemy...");
zmierzCzas("Pętla bez kolekcji", Wrappery9_WydajnoscList::petla);
wyczysc();
zmierzCzas("Tablica", Wrappery9_WydajnoscList::tablica);
wyczysc();
zmierzCzas("ArrayList", Wrappery9_WydajnoscList::array_list);
wyczysc();
zmierzCzas("Stream (range)", Wrappery9_WydajnoscList::stream_range);
wyczysc();
zmierzCzas("Stream (tablica)", Wrappery9_WydajnoscList::stream_tablica);
wyczysc();
System.out.println("Koniec");
}
}
package p19_napisy;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class BudowanieNapisow_PomiarCzasu {
static String kolejneLiczby(int n) {
String napis = "";
for(int i = 1; i <= n; i++) {
napis += i + " ";
}
return napis;
}
static String kolejneLiczbyConcat(int n) {
String napis = "";
for(int i = 1; i <= n; i++) {
napis = napis.concat(i + " ");
}
return napis;
}
static String kolejneLiczbyCollector(int n) {
return IntStream.rangeClosed(1, n)
.mapToObj(Integer::toString)
.collect(Collectors.joining(" "));
}
static String kolejneLiczbySB(int n) {
StringBuilder s = new StringBuilder();
for(int i = 1; i <= n; i++) {
s.append(i).append(' ');
}
return s.toString();
}
public static void main(String[] args) {
// sprawdzanie czasu wykonania
int[] dane1 = {25000, 50000, 100_000};
int[] dane2 = {25000, 50000, 100_000, 1_000_000, 10_000_000};
int[] dane3 = {25000, 50000, 100_000, 1_000_000, 10_000_000, 100_000_000};
System.out.println("Wersja String +=");
System.out.println(kolejneLiczby(10));
for(int n : dane1) {
System.out.println("n = " + n + "...");
long start = System.currentTimeMillis();
String wynik = kolejneLiczby(n);
long koniec = System.currentTimeMillis();
System.out.println(" Dla n = " + n + " trwało " + (koniec - start) + "ms");
System.out.println(" Napis ma długość " + wynik.length());
}
System.out.println();
System.out.println("Wersja String concat");
System.out.println(kolejneLiczbyConcat(10));
for(int n : dane1) {
System.out.println("n = " + n + "...");
long start = System.currentTimeMillis();
// start = System.nanoTime();
String wynik = kolejneLiczbyConcat(n);
long koniec = System.currentTimeMillis();
System.out.println(" Dla n = " + n + " trwało " + (koniec - start) + "ms");
System.out.println(" Napis ma długość " + wynik.length());
}
System.out.println();
System.out.println("Wersja Stream / collector");
System.out.println(kolejneLiczbyCollector(10));
for(int n : dane2) {
System.out.println("n = " + n + "...");
long start = System.currentTimeMillis();
String wynik = kolejneLiczbyCollector(n);
long koniec = System.currentTimeMillis();
System.out.println(" Dla n = " + n + " trwało " + (koniec - start) + "ms");
System.out.println(" Napis ma długość " + wynik.length());
}
System.out.println();
System.out.println("Wersja StringBuilder");
System.out.println(kolejneLiczbySB(10));
for(int n : dane3) {
System.out.println("n = " + n + "...");
long start = System.currentTimeMillis();
String wynik = kolejneLiczbySB(n);
long koniec = System.currentTimeMillis();
System.out.println(" Dla n = " + n + " trwało " + (koniec - start) + "ms");
System.out.println(" Napis ma długość " + wynik.length());
}
System.out.println();
}
}
package p19_napisy;
public class InnaKlasa {
public static String dajStringaZKodu() {
return "Ala ma kota";
}
public static String dajStringaNowego() {
return new String("Ala ma kota");
}
}
package p19_napisy;
public class OperacjeNaStringach {
public static void main(String[] args) {
String napis = "Ala ma kota";
System.out.println(napis);
napis.concat(" Filemona");
napis.replace("Ala", "Alicja");
System.out.println(napis); // napis się nie zmienił
System.out.println();
napis = napis.concat(" Bonifacego");
System.out.println(napis); // teraz zmieniony
System.out.println("\nMetody informacyjne");
System.out.println(napis.length());
System.out.println(napis.charAt(2)); // numeracja od 0
//EXN System.out.println(napis.charAt(30));
System.out.println(napis.codePointAt(2)); // kod Unicode
System.out.println("\nSprawdzanie czy zawiera fragment");
// istotna jest też wielkośc liter
System.out.println(napis.contains("kot"));
System.out.println(napis.startsWith("Ala"));
System.out.println(napis.endsWith("kot"));
System.out.println(napis.equals("ala ma kota bonifacego")); // F
// a to nie patrzy na wielkość liter
System.out.println(napis.equalsIgnoreCase("ala ma kota bOnIfAcEgO")); // T
System.out.println("\nWyszukiwanie");
System.out.println(napis.indexOf("ma"));
System.out.println(napis.indexOf("pies")); // -1
System.out.println(napis.indexOf('a')); //2
System.out.println(napis.indexOf('a', 3)); //5 bo szukam litery a od pozycji nr 3
System.out.println(napis.lastIndexOf('a')); // ostatnie a w napisie
System.out.println("\nMetody zwracające zmieniony napis");
System.out.println(napis.concat(" i jeszcze psa Reksia"));
System.out.println("|"+napis.substring(7, 15)+"|"); // od 7 włącznie, do 15 wyłączając; 15-7 = 8, 8 to jest długość wynikowego słowa
System.out.println("|"+napis.substring(7)+"|"); // od 7 do końca
System.out.println(napis.toLowerCase());
System.out.println(napis.toUpperCase());
// replace zamienia wszystkie wystąpienia
System.out.println(napis.replace(' ', '_'));
System.out.println(napis.replace("ma", "posiada"));
// Działa na wyrażeniach regularnych.
// Ten przykład zamienia pierwsze litery słów (po spacjach)
System.out.println(napis.replaceAll(" .", " X"));
}
}
package p19_napisy;
public class ParametryString {
public static void main(String[] args) {
String a = "Ala";
System.out.println("a1 = " + a);
m(a);
System.out.println("a2 = " + a);
// String is immutable
}
static void m(String c) {
System.out.println("c1 = " + c);
c += " ma kota";
System.out.println("c2 = " + c);
// tak naprawdę jest tworzony nowy obiekt String: c = new String("Ala" + " ma kota")
// a oryginalny obiekt, na który wskazuje zmienna a, nie zmienia się
}
}
package p19_napisy;
import java.util.Objects;
public class Porownywanie {
public static void main(String[] args) {
String ala = "Ala";
final String final_ala = "Ala";
String a = "Ala ma kota";
String b = "Ala ma kota";
String c = "Ala" + " ma kota";
String d = final_ala + " ma kota";
String e = InnaKlasa.dajStringaZKodu();
String f = new String(a);
String g = ala + " ma kota";
// tak samo jest dla danych wczytywanych z zewnętrznych źródeł: konsola, plik, baza danych
System.out.println("==");
System.out.println(a == "Ala ma kota");
System.out.println(a == a);
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a == d);
System.out.println(a == e);
System.out.println(a == f);
System.out.println(a == g);
System.out.println();
System.out.println("intern");
// intern zwraca referencję do stringa o takiej samej treści, ale pochodzącego z puli stringów
// jeśli w puli jeszcze go nie było, to dodawany
System.out.println(a.intern() == f.intern());
System.out.println();
System.out.println("equals");
System.out.println(a.equals(a));
System.out.println(a.equals(b));
System.out.println(a.equals(c));
System.out.println(a.equals(d));
System.out.println(a.equals(e));
System.out.println(a.equals(f));
System.out.println(a.equals(g));
System.out.println("Ala ma kota".equals(g));
System.out.println(Objects.equals(a, g));
}
}
package p20_daty;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.temporal.ChronoField;
public class DataICzas {
public static void main(String[] args) {
// Która godzina jest w innej strefie czasowej
LocalDateTime dt2 = LocalDateTime.now(ZoneId.of("UTC-4"));
System.out.println(dt2);
LocalDateTime dt = LocalDateTime.now();
System.out.println(dt);
// Metody "with" modyfikują wybrane pole i zwracają wmieniony obiekt
dt.with(ChronoField.HOUR_OF_DAY, 17);
System.out.println(dt); // nie widać zmiany, bo dato-czasy są immutable
// przypisanie na zmienną dt zapisuje zmieniony obiekt
dt = dt.with(ChronoField.HOUR_OF_DAY, 17);
System.out.println(dt);
dt = dt.withDayOfMonth(13);
System.out.println(dt);
dt = dt.withDayOfYear(200);
System.out.println(dt);
dt = dt.with(ChronoField.SECOND_OF_DAY, 12360);
System.out.println(dt);
try {
dt = dt.with(ChronoField.OFFSET_SECONDS, 7200);
System.out.println(dt);
} catch (Exception e) {
System.out.println("Był wyjątek " + e.getClass() + " " + e.getMessage());
}
dt = LocalDateTime.now();
System.out.println(dt);
OffsetDateTime przesuniety = dt.atOffset(ZoneOffset.ofHours(5));
System.out.println(przesuniety);
dt = LocalDateTime.parse("2019-05-08T14:55:04.360");
System.out.println(dt);
dt = LocalDateTime.parse("2019-05-08T14:55");
System.out.println(dt);
dt = LocalDateTime.parse("2019-05-08T14:55:00");
System.out.println(dt); // sekundy równe zero w ogóle się nie wypisują
}
}
package p20_daty;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class Formatowanie1_Standardy {
public static void main(String[] args) {
LocalDateTime teraz = LocalDateTime.now();
DateTimeFormatter[] formats = {
DateTimeFormatter.BASIC_ISO_DATE,
DateTimeFormatter.ISO_DATE,
DateTimeFormatter.ISO_DATE_TIME,
DateTimeFormatter.ISO_LOCAL_DATE_TIME,
DateTimeFormatter.ISO_ORDINAL_DATE,
DateTimeFormatter.ISO_WEEK_DATE,
};
System.out.println("Format domyslny:");
System.out.println(teraz.toString());
System.out.println(LocalDate.now().toString());
System.out.println(LocalTime.now().toString());
System.out.println();
for (DateTimeFormatter df : formats) {
// formatowanie można wywoływać na dwa sposoby
System.out.println(teraz.format(df));
System.out.println(df.format(teraz));
}
}
}
package p20_daty;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class Formatowanie2_Jezykowo {
public static void main(String[] args) {
ZonedDateTime teraz = ZonedDateTime.now();
DateTimeFormatter df = DateTimeFormatter
.ofLocalizedDateTime(FormatStyle.FULL)
.withLocale(new Locale("ru", "RU"));
System.out.println(teraz.format(df));
}
}
package p20_daty;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class Formatowanie3_Jezykowo_BezStrefy {
public static void main(String[] args) {
LocalDateTime teraz = LocalDateTime.now();
Locale[] locales = {
new Locale("pl", "PL"),
new Locale("pl"),
new Locale("fr", "FR"),
new Locale("de", "DE"),
new Locale("es", "ES"),
new Locale("it", "IT"),
new Locale("ru", "RU"),
new Locale("ja", "JP"),
new Locale("ar", "EY"),
new Locale("en", "GB"),
new Locale("en", "US"),
new Locale("en")
};
FormatStyle[] styles = {
//FormatStyle.FULL,
//FormatStyle.LONG,
FormatStyle.MEDIUM,
FormatStyle.SHORT
};
for(Locale locale : locales) {
System.out.println("\nLOCALE " + locale);
for(FormatStyle style : styles) {
DateTimeFormatter df = DateTimeFormatter.ofLocalizedDateTime(style);
System.out.println(teraz.format(df));
}
}
}
}
package p20_daty;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
public class Formatowanie4_Jezykowo_Strefa {
public static void main(String[] args) {
ZonedDateTime teraz = ZonedDateTime.now();
Locale[] locales = {
new Locale("pl", "PL"),
new Locale("pl"),
new Locale("fr", "FR"),
new Locale("de", "DE"),
new Locale("es", "ES"),
new Locale("it", "IT"),
new Locale("ru", "RU"),
new Locale("ja", "JP"),
new Locale("ar", "EY"),
new Locale("en", "GB"),
new Locale("en", "US"),
new Locale("en")
};
FormatStyle[] styles = {
FormatStyle.FULL,
FormatStyle.LONG,
FormatStyle.MEDIUM,
FormatStyle.SHORT
};
for(Locale locale : locales) {
System.out.println("\nLOCALE " + locale);
for(FormatStyle style : styles) {
DateTimeFormatter df = DateTimeFormatter
.ofLocalizedDateTime(style)
.withLocale(locale);
System.out.println(teraz.format(df));
System.out.println(df.format(teraz));
}
}
}
}
package p20_daty;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Formatowanie5_Pattern {
public static void main(String[] args) {
ZonedDateTime teraz = ZonedDateTime.now();
DateTimeFormatter df = DateTimeFormatter.ofPattern("YYYY-MM-dd");
System.out.println(teraz.format(df));
df = DateTimeFormatter.ofPattern("dd.MM.YY");
System.out.println(teraz.format(df));
df = DateTimeFormatter.ofPattern("dd.MM.YYY");
System.out.println(teraz.format(df));
df = DateTimeFormatter.ofPattern("d M Y");
System.out.println(teraz.format(df));
df = DateTimeFormatter.ofPattern("dd MM YY");
System.out.println(teraz.format(df));
df = DateTimeFormatter.ofPattern("e dd MMM");
System.out.println(teraz.format(df));
df = DateTimeFormatter.ofPattern("EEE, dd MMMM");
System.out.println(teraz.format(df));
df = DateTimeFormatter.ofPattern("EEEE, dd MMMMM");
System.out.println(teraz.format(df));
}
}
package p20_daty;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Formatowanie6_Parse {
public static void main(String[] args) {
LocalDateTime data = LocalDateTime.now();
DateTimeFormatter df = DateTimeFormatter.ofPattern("EEEE,yyyyMMdd HH@mm");
System.out.println(data.format(df));
System.out.println(data);
System.out.println();
data = LocalDateTime.parse("wtorek,19981208 12@13", df);
System.out.println(data);
}
}
package p20_daty;
import java.time.LocalDate;
import java.time.Period;
public class Okresy {
public static void main(String[] args) {
LocalDate d1 = LocalDate.parse("2015-05-13");
LocalDate d2 = LocalDate.parse("2016-09-11");
Period p1 = Period.between(d1, d2);
System.out.println(p1);
Period p2 = Period.of(3, 14, 44);
System.out.println(p2);
LocalDate dzisiaj = LocalDate.now();
LocalDate przyszlosc1 = dzisiaj.plus(p2);
System.out.println(przyszlosc1);
LocalDate przyszlosc2 = (LocalDate) p2.addTo(dzisiaj);
System.out.println(przyszlosc2);
Period p3 = p2.normalized();
System.out.println(p3); // miesiące są normalizowane (miesiące powyżej 12 są zamieniane na lata), ale dni nie, bo się nie da
System.out.println();
Period p4 = Period.parse("P3M2W10D"); // tygodnie od razu przeliczają się na dni, ale miesiące nie przeliczają się na lata
System.out.println(p4);
Period p5 = Period.ofWeeks(3);
System.out.println(p5);
Period p6 = Period.ofDays(50);
System.out.println(p6);
}
}
package p20_daty;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
public class Porownywanie {
public static void main(String[] args) {
LocalDate d1 = LocalDate.now();
LocalDate d2 = LocalDate.of(2016, 12, 7);
LocalDate d3 = LocalDate.parse("2016-04-04");
System.out.println(d1.equals(d2)); // T
System.out.println(d1.equals(d3)); // F
if(d1.compareTo(d3) > 0) {
System.out.println("d1 później niż d3");
} else {
System.out.println("d1 wcześniej niż d3");
}
if(d1.isAfter(d3)) {
System.out.println("d1 później niż d3");
} else {
System.out.println("d1 wcześniej niż d3");
}
ArrayList<LocalDate> daty = new ArrayList<>();
daty.add(LocalDate.of(2015, 12, 24));
daty.add(LocalDate.of(2016, 9, 24));
daty.add(LocalDate.of(2015, 3, 11));
daty.add(LocalDate.of(2016, 8, 8));
System.out.println(daty);
Collections.sort(daty);
System.out.println(daty);
}
}
package p20_daty;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
public class ProsteDaty {
public static void main(String[] args) {
LocalDate data1 = LocalDate.now();
System.out.println(data1);
LocalDate data2 = LocalDate.of(2016, 12, 5);
System.out.println(data2);
LocalDate data3 = LocalDate.of(2016, Month.DECEMBER, 5);
System.out.println(data3);
LocalDate data4 = LocalDate.parse("2016-12-05");
System.out.println(data4);
LocalDate data5 = LocalDate.parse("2016-02-29");
System.out.println(data5);
// LocalDate data6 = LocalDate.parse("2015-02-29");
// System.out.println(data6);
// najpierw starsza potem pozniejsza
Period czasTrwania = Period.between(data4, data1);
System.out.println(czasTrwania);
System.out.println(czasTrwania.getDays());
}
}
package p20_daty;
import java.time.LocalTime;
public class ProstyCzas {
public static void main(String[] args) {
LocalTime czas1 = LocalTime.now(); // ustawia z dokladnoscia do milisekundy
System.out.println(czas1);
// uwaga: można utworzyć czas nie podając sekund
LocalTime czas2 = LocalTime.of(12, 15);
System.out.println(czas2);
LocalTime czas3 = LocalTime.of(12, 15, 33);
System.out.println(czas3);
// uwaga: nanosekumdy podajemy jako liczbę całkowitą (int)
LocalTime czas4 = LocalTime.of(12, 15, 33, 333222111);
System.out.println(czas4);
// to oznacza jedną nanosekundę (miliardową część sekundy),
// a nie jedną dizesiątą sekundy
LocalTime czas5 = LocalTime.of(12, 15, 33, 1);
System.out.println(czas5);
}
}
package p20_daty;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class PrzykladInstant {
public static void main(String[] args) {
Instant czas = Instant.now();
System.out.println(czas);
ZonedDateTime uNas = czas.atZone(ZoneId.systemDefault());
System.out.println(uNas);
ZonedDateTime zoned = ZonedDateTime.now();
System.out.println(zoned);
}
}
package p20_daty;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class StareFormatowanieDat {
public static void display(Date date, Locale locale) {
DateFormat df;
df = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
System.out.println("Date DEFAULT: " + df.format(date));
df = DateFormat.getDateInstance(DateFormat.FULL, locale);
System.out.println("Date FULL: " + df.format(date));
df = DateFormat.getDateInstance(DateFormat.LONG, locale);
System.out.println("Date LONG: " + df.format(date));
df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
System.out.println("Date MEDIUM: " + df.format(date));
df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
System.out.println("Date SHORT: " + df.format(date));
df = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale);
System.out.println("Time DEFAULT: " + df.format(date));
df = DateFormat.getTimeInstance(DateFormat.FULL, locale);
System.out.println("Time FULL: " + df.format(date));
df = DateFormat.getTimeInstance(DateFormat.LONG, locale);
System.out.println("Time LONG: " + df.format(date));
df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);
System.out.println("Time MEDIUM: " + df.format(date));
df = DateFormat.getTimeInstance(DateFormat.SHORT, locale);
System.out.println("Time SHORT: " + df.format(date));
//Tu już tylko przykładowo
df = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale);
System.out.println("DateTime DEFAULT DEFAULT: " + df.format(date));
df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT, locale);
System.out.println("DateTime LONG SHORT: " + df.format(date));
}
public static void main(String[] args) {
Locale[] all = {
new Locale("pl", "PL"),
new Locale("pl"),
new Locale("de", "DE"),
new Locale("fr", "FR"),
new Locale("ru", "RU"),
new Locale("es", "ES"),
new Locale("it", "IT"),
new Locale("ja", "JP"),
new Locale("ar", "EY"),
new Locale("en", "GB"),
new Locale("en", "US"),
new Locale("en") };
Date now = Calendar.getInstance().getTime();
DateFormat df = DateFormat.getInstance();
System.out.println("domyślnie: " + df.format(now));
for (Locale locale : all) {
System.out.println("Dla locali " + locale.toString());
display(now, locale);
System.out.println();
}
}
}
package p20_daty;
import java.text.DateFormat;
import java.util.Locale;
import java.util.Locale.Category;
public class WypiszDostepneLocale {
public static void main(String[] args) {
System.out.println("DEFAULT: "+Locale.getDefault());
System.out.println("DISPLAY: "+Locale.getDefault(Category.DISPLAY));
System.out.println("FORMAT: "+Locale.getDefault(Category.FORMAT));
for (Locale loc : DateFormat.getAvailableLocales()) {
System.out.println(loc.toString() + " " + loc.getDisplayLanguage() + "/" + loc.getDisplayCountry() );
}
}
}
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