Commit 493f3352 by Patryk Czarnik

Dodatkowe przykłady JAVA

parent a5fbb0f7
package gotowe.p20_enum;
public enum DzienTygodnia1 {
PON, WTO, SRO, CZW, PIA(), SOB, NIE
}
// Deklaracja enuma określa wszystkie obiekty,
// poza tym miejscem nie da się utworzyć nowych obiektów klasy enumowej.
package gotowe.p20_enum;
public enum DzienTygodnia2 implements AutoCloseable {
// Wartości mogą być tworzone poprzez wywołanie odpowiedniego konstruktora:
DODATKOWY(13L),
PON("poniedziałek"),
WTO("wtorek"),
SRO("środa"),
CZW("czwartek"),
PIA("piątek"),
SOB("sobota"),
NIE("niedziela");
// Enum, jak zwykła klasa, może zawierać:
// * pola
private String nazwa;
public int dlugoscTekstu;
// * Konstruktory (są prywatne, bo są używane tylko wewnątrz "klasy"!)
// można napisać poziom widoczności private, ale nawet jak nie napiszemy, to i tak będzie private
// nie wolno podać innego poziomu widoczności
DzienTygodnia2(String jakaNazwa) {
nazwa = jakaNazwa;
dlugoscTekstu = jakaNazwa.length();
}
private DzienTygodnia2(Number numer) {
}
//NK public DzienTygodnia2(int numer) { }
// * Metody (i mogą implementować interfejsy)
public void wypiszSie() {
System.out.println("Jestem sobie " + this.nazwa + " i mam kod " + this.name() + " oraz numer " + this.ordinal());
}
public void close() {
System.out.println("się zamykam...");
}
@Override
public String toString() {
return nazwa;
}
// Można też definiować zmienne i metody statyczne
static String napisStatyczny = "Ala ma kota";
static void metodaStatyczna() {
System.out.println(napisStatyczny);
}
}
package gotowe.p20_enum;
public enum DzienTygodnia3 {
// Wartości mogą być tworzone poprzez wywołanie odpowiedniego konstruktora:
PON("poniedziałek"),
WTO("wtorek"),
SRO("środa"),
CZW("czwartek"),
PIA("piątek"),
SOB("sobota"),
// Możliwość nadpisania metody dla wybranych wartości (technicznie: powstaje podklasa)
NIE("niedziela") {
@Override
public boolean handelDozwolony() {
return false;
}
public void nowaMetoda() { }
};
// Enum, jak zwykła klasa, może zawierać:
// * pola
private String nazwa;
// * Konstruktory (mogą być prywatne, bo sa używane tylko wewnątrz "klasy"!)
private DzienTygodnia3(String jakaNazwa) {
nazwa = jakaNazwa;
}
// * Metody
@Override
public String toString() {
return nazwa;
}
public boolean handelDozwolony() {
return true;
}
}
package gotowe.p20_enum;
import java.util.Arrays;
public class Test1 {
static String tekst(DzienTygodnia1 dt) {
// można użyć switch, nie wolno prefiksować wartości nazwą klasy
switch (dt) {
//case DzienTygodnia1.PON: return "poniedziałek";
case PON: return "poniedziałek";
case WTO: return "wtorek";
case SRO: return "środa";
case CZW: return "czwartek";
case PIA: return "piątek";
case SOB: return "sobota";
case NIE: return "niedziela";
// ale mimo wyczerpania wszystkich wartości potrzebny default
default : return "???";
}
}
public static void main(String[] args) {
DzienTygodnia1 dt = DzienTygodnia1.WTO;
String zmienna = "WTO";
DzienTygodnia1 wczytany = DzienTygodnia1.valueOf(zmienna);
//EXN DzienTygodnia1a wczytany = DzienTygodnia1.valueOf("nie ma takiego dnia");
// IllegalArgumentException
if(dt == wczytany) {
System.out.println("równe");
} else {
System.out.println("nierówne");
}
if(dt.equals(wczytany)) {
System.out.println("równe");
} else {
System.out.println("nierówne");
}
// == równoważne equals; dla każdej wartości enuma istnieje dokładnie jeden obiekt
System.out.println();
// Standardowo dostępne informacje dla pojedynczej wartości:
System.out.println(dt);
System.out.println(dt.toString());
System.out.println(dt.name());
System.out.println(dt.ordinal()); // od 0
//NK System.out.println(dt < wczytany);
System.out.println(dt.compareTo(wczytany)); // OK
System.out.println(tekst(dt));
System.out.println();
// Standardowo dostępne rzeczy dla klasy enuma:
DzienTygodnia1 dt4 = DzienTygodnia1.valueOf("PIA");
System.out.println(dt4);
DzienTygodnia1[] values = DzienTygodnia1.values();
System.out.println(Arrays.toString(values));
System.out.println(DzienTygodnia1.class.getSuperclass());
}
}
package gotowe.p20_enum;
import static gotowe.p20_enum.DzienTygodnia1.*;
import java.util.Arrays;
public class Test1_import_static {
static String tekst(DzienTygodnia1 dt) {
// można użyć switch, nie wolno prefiksować wartości nazwą klasy
switch (dt) {
case PON: return "poniedziałek";
case WTO: return "wtorek";
case SRO: return "środa";
case CZW: return "czwartek";
case PIA: return "piątek";
case SOB: return "sobota";
case NIE: return "niedziela";
// ale mimo wyczerpania wszystkich wartości potrzebny default
default : return "???";
}
}
public static void main(String[] args) {
// dzięki static import mogę używać krótkich nazw z enuma także poza switch
DzienTygodnia1 dt = WTO;
DzienTygodnia1 wczytany = DzienTygodnia1.valueOf("WTO");
//EXN DzienTygodnia1a wczytany = DzienTygodnia1.valueOf("nie ma takiego dnia");
// IllegalArgumentException
if(dt == wczytany) {
System.out.println("równe");
} else {
System.out.println("nierówne");
}
if(dt.equals(wczytany)) {
System.out.println("równe");
} else {
System.out.println("nierówne");
}
// == równoważne equals; dla każdej wartości enuma istnieje dokładnie jeden obiekt
System.out.println();
// Standardowo dostępne informacje dla pojedynczej wartości:
System.out.println(dt);
System.out.println(dt.toString());
System.out.println(dt.name());
System.out.println(dt.ordinal()); // od 0
//NK System.out.println(dt < wczytany);
System.out.println(dt.compareTo(wczytany)); // OK
System.out.println(tekst(dt));
System.out.println();
// Standardowo dostępne rzeczy dla klasy enuma:
DzienTygodnia1 dt4 = DzienTygodnia1.valueOf("PIA");
System.out.println(dt4);
DzienTygodnia1[] values = DzienTygodnia1.values();
System.out.println(Arrays.toString(values));
System.out.println(DzienTygodnia1.class.getSuperclass());
}
}
package gotowe.p20_enum;
public class Test2 {
public static void main(String[] args) {
DzienTygodnia2 dt = DzienTygodnia2.WTO;
// mogę odwoływać się do zmiennych nie-prywatnych z obiektu enum, nawet je modyfikować
System.out.println(dt.dlugoscTekstu);
dt.dlugoscTekstu += 100;
System.out.println(dt.dlugoscTekstu);
System.out.println(DzienTygodnia2.WTO.dlugoscTekstu);
dt.wypiszSie();
}
}
package gotowe.p20_enum;
public class Test3 {
public static void main(String[] args) {
DzienTygodnia3 wtorek = DzienTygodnia3.WTO;
System.out.print(wtorek + " ");
System.out.println(wtorek.handelDozwolony());
System.out.println(wtorek.name() + " " + wtorek.ordinal());
System.out.println(wtorek.getClass());
System.out.println(wtorek.getClass().getSuperclass());
System.out.println(wtorek.getClass().getSuperclass().getSuperclass());
System.out.println(wtorek.getClass().getSuperclass().getSuperclass().getSuperclass());
System.out.println();
DzienTygodnia3 niedziela = DzienTygodnia3.NIE;
System.out.print(niedziela + " ");
System.out.println(niedziela.handelDozwolony());
System.out.println(niedziela.name() + " " + niedziela.ordinal());
System.out.println(niedziela.getClass());
System.out.println(niedziela.getClass().getSuperclass());
System.out.println(niedziela.getClass().getSuperclass().getSuperclass());
System.out.println(niedziela.getClass().getSuperclass().getSuperclass().getSuperclass());
}
}
package gotowe.p20_enum;
import gotowe.p20_enum.E4.KlasaIntancyjna;
class Zagniezdzanie1 {
int instancyjna = 10;
static int statyczna = 20;
enum E1 {A, B, C,}
static enum E2 {A, B, C;}
// Nawet jeżeli nie napiszemy static, to enum zagnieżdżony w klasie jest static
enum E3 {A, B, C;
public void metoda() {
System.out.println(statyczna);
// enum jest w kontekście statycznym
//NK System.out.println(instancyjna);
}
}
}
// W enumie mogę też zagnieździć klasę lub enuma
enum E4 {
A, B, C;
static class KlasaStatyczna {
void print() {
System.out.println("aaa");
//NK System.out.println("bbb " + name());
}
}
class KlasaIntancyjna {
void print() {
// name() to będzie nazwa tewartości (jednej z A B C),
// z której został pobrany obiekt tej klasy
System.out.println("bbb " + name());
}
}
interface III {
void test();
}
enum E5 {
}
}
public class Zagniezdzanie {
public static void main(String[] args) {
Zagniezdzanie1.E1 x = Zagniezdzanie1.E1.A;
E4.KlasaStatyczna y = new E4.KlasaStatyczna();
y.print();
KlasaIntancyjna z = E4.C.new KlasaIntancyjna();
z.print();
}
}
package gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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";
// w tej wersji oba konta mają refencję do tego samego obiektu Osoba
// (bo clone zrobił płytką kopię)
System.out.println("oryginał: " + konto);
System.out.println("klon : " + klon);
System.out.println();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
package gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p21_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p26_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_generyki.kolekcje;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class StaraJava {
public static void main(String[] args) {
// Tak się używało list i innych kolekcji w wersjach Javy < 5
List lista = new ArrayList();
lista.add("Ala");
lista.add("Ola");
lista.add("Ela");
// lista.add(new Integer(133));
System.out.println(lista);
Iterator it = lista.iterator();
while(it.hasNext()) {
String elt = (String)it.next();
System.out.println(elt);
}
String imie = (String)lista.get(1);
System.out.println(imie);
}
}
package gotowe.p27_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 gotowe.p27_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 gotowe.p27_generyki.techniczne;
import java.util.Optional;
import gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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 gotowe.p27_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, BigDecimal 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 gotowe.p27_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));
ParaLiczb<Integer> para1a = new ParaLiczb<>(13, 3000);
ParaLiczb<Integer> para1b = new ParaLiczb<>(Integer.valueOf(13), Integer.valueOf(3000));
System.out.println(para1);
Number lewy = para1.getLewy();
Integer lewyi = para1.getLewy();
//NK para1.setLewy(new Double(3.14));
para1.setLewy(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 gotowe.p29_refleksja;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Scanner;
public final class PokazRefleksji {
private final Scanner sc;
private Class<?> c = null;
private Object o = null;
PokazRefleksji() {
sc = new Scanner(System.in);
}
private String menu() {
System.out.println();
System.out.println("Current class: " + c);
System.out.println("Current object: " + o);
System.out.println("\nChoose action:");
System.out.println("q - quit");
if(c == null) {
System.out.println("c - choose class");
} else {
System.out.println("c - change class");
System.out.println("p - print general info about current class");
System.out.println("lf - list fields of current class");
System.out.println("lm - list methods of current class");
System.out.println("lc - list constructors of current class");
System.out.println("o - create object ()");
System.out.println("oc - create object using constructor");
}
return sc.nextLine().trim().toLowerCase();
}
private void changeClass() {
System.out.println("Give the full class name (with package):");
String className = sc.nextLine();
try {
c = Class.forName(className);
System.out.println("Class " + className + " has been loaded.");
o = null;
} catch (ClassNotFoundException e) {
System.out.println("Class " + className + " can not been loaded.");
System.out.println("Exception: " + e);
}
}
private void printInfo() {
System.out.println(c.toGenericString());
System.out.println("Full name: " + c.getName());
System.out.println("Simple name: " + c.getSimpleName());
System.out.println("Canonical name: " + c.getCanonicalName());
if(c.getSuperclass() != null) {
System.out.println("superclass: " + c.getSuperclass().getName());
}
if(c.getEnclosingClass() != null) {
System.out.println("enclosing class: " + c.getEnclosingClass().getName());
}
if(c.isArray()) {
System.out.println("This is array of " + c.getComponentType());
}
}
private void listFields() {
System.out.println("All accessible fields:");
for(Field field : c.getFields()) {
describeField(field);
}
System.out.println();
System.out.println("All fields declared in this class:");
for(Field field : c.getDeclaredFields()) {
describeField(field);
}
}
private void listMethods() {
System.out.println("All accessible methods:");
for(Method method : c.getMethods()) {
describeMethod(method);
}
System.out.println();
System.out.println("All methods declared in this class:");
for(Method method : c.getDeclaredMethods()) {
describeMethod(method);
}
}
private void listConstructors() {
System.out.println("All accessible methods:");
for(Constructor<?> constr : c.getConstructors()) {
describeConstructor(constr);
}
System.out.println();
}
private void describeField(Field field) {
System.out.print(" * " + field.getName() + " : " + field.getGenericType());
System.out.println(" / " + Modifier.toString(field.getModifiers()));
}
private void describeMethod(Method method) {
System.out.print(" * " + method.getName());
System.out.println(" / " + Modifier.toString(method.getModifiers()));
System.out.println(" parameters:");
for (Parameter parameter : method.getParameters()) {
System.out.println(" - " + parameter.getName() + " : " + parameter.getType());
}
System.out.println(" result type: " + method.getReturnType());
}
private void describeConstructor(Constructor<?> constr) {
System.out.print(" * " + constr);
System.out.println(" / " + Modifier.toString(constr.getModifiers()));
System.out.println(" parameters:");
for (Parameter parameter : constr.getParameters()) {
System.out.println(" - " + parameter.getName() + " : " + parameter.getType());
}
}
private void createObject() {
try {
Constructor<?> defaultConstructor = c.getConstructor();
o = defaultConstructor.newInstance();
System.out.println("New object has been created");
System.out.println(o);
} catch (NoSuchMethodException e) {
System.out.println("This class has no default constructor. " + e);
} catch (Exception e) {
System.out.println(e);
}
}
private void invokeConstructor() {
Constructor<?>[] constructors = c.getConstructors();
if(constructors.length == 0) {
System.out.println("No constructors available.");
return;
}
System.out.println("Choose one of the constructors:");
for (int i = 0; i < constructors.length; i++) {
System.out.printf(" * %2d : %s\n", i, constructors[i]);
}
System.out.print("Give the number: ");
while(!sc.hasNextInt()) {
sc.next();
}
int choice = sc.nextInt();
sc.nextLine();
try {
Constructor<?> constructor = constructors[choice];
Parameter[] parameters = constructor.getParameters();
Object[] args = new Object[constructor.getParameterCount()];
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
System.out.println("Give value of type " + parameter.getType() + " for parameter " + parameter.getName());
args[i] = sc.nextLine();
}
o = constructor.newInstance(args);
System.out.println("New object has been created");
System.out.println(o);
} catch (Exception e) {
System.out.println("Cannot create object " + e);
}
}
void run() {
loop: while(true) {
String action = menu();
switch(action) {
case "q" : break loop;
case "c" : changeClass(); break;
case "p" : printInfo(); break;
case "lf" : listFields(); break;
case "lm" : listMethods(); break;
case "lc" : listConstructors(); break;
case "o" : createObject(); break;
case "oc" : invokeConstructor(); break;
}
}
System.out.println("bye");
}
public static void main(String[] args) {
new PokazRefleksji().run();
}
}
package gotowe.p29_refleksja;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import gotowe.p29_refleksja.klasy.ABC;
import gotowe.p29_refleksja.klasy.Konto;
import gotowe.p29_refleksja.klasy.Osoba;
public class PrzykladRefleksji {
public static void main(String[] args) throws Exception {
// Różne sposoby uzyskiwania obiektu Class
Class<?> klasa = Osoba.class;
Class<Osoba> klasa1 = Osoba.class;
Osoba osoba = new Osoba();
Class<?> klasa2 = osoba.getClass();
if(klasa2 == klasa1) {
System.out.println("To jest ta sama klasa");
}
try {
Class<?> klasa3 = Class.forName("gotowe.p29_refleksja.klasy.Osoba");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("Obiekt klasy: " + klasa);
System.out.println("name: " + klasa.getName());
System.out.println("simpleName: " + klasa.getSimpleName());
System.out.println("nadklasa: " + klasa.getSuperclass().getName());
System.out.println();
System.out.println("Lista konstruktorów");
for (Constructor<?> constructor : klasa.getConstructors()) {
System.out.println(constructor);
}
System.out.println("Tworzę obiekt za pomocą konstr. bezarg.");
Object obiekt1 = klasa.newInstance();
System.out.println("Utworzyłem obiekt: " + obiekt1);
System.out.println("Klasa obiektu: " + obiekt1.getClass());
System.out.println();
System.out.println("Tworzę obiekt za pomocą konstruktora z argumentami");
Constructor<?> constructor3 = klasa.getConstructor(String.class, String.class, int.class);
Object obiekt2 = constructor3.newInstance("Ola", "Nowakowska", 33);
System.out.println("Utworzyłem obiekt: " + obiekt2);
System.out.println("Klasa obiektu: " + obiekt2.getClass());
System.out.println();
System.out.println("Zmienne klasy Osoba:");
for (Field field : klasa.getFields()) {
System.out.println(" + " + field.getName() + " : " +field.getType().getName());
}
System.out.println("Zmienne zadeklarowane w Osoba:");
for (Field field : klasa.getDeclaredFields()) {
System.out.println(" + " + field.getName() + " : " +field.getType().getName());
}
System.out.println("Metody klasy Osoba:");
for (Method field : klasa.getMethods()) {
System.out.println(" * " + field.getName());
}
System.out.println("Metody zadeklarowane w klasie Osoba:");
for (Method field : klasa.getDeclaredMethods()) {
System.out.println(" # " + field.getName());
}
System.out.println();
Field poleImie = klasa.getField("imie");
// System.out.println(poleImie);
poleImie.set(obiekt1, "Ala");
Field poleNazwisko = klasa.getField("nazwisko");
poleNazwisko.set(obiekt1, "Kowalska");
Field poleWiek = klasa.getField("wiek");
poleWiek.setInt(obiekt1, 44);
System.out.println("Ustawiłem pola, teraz obiekt wypisuje się jako:");
System.out.println(obiekt1);
System.out.println("nazwisko = " + poleNazwisko.get(obiekt1));
System.out.println();
for (Field field : klasa.getDeclaredFields()) {
if("haslo".equals(field.getName())) {
try {
field.set(obiekt1, "abc123");
System.out.println("Ustawiłem hasło " + field.get(obiekt1));
} catch(Exception e) {
System.out.println("Nie udało się ustawić prywatnego hasła po raz pierwszy");
System.out.println(e);
}
try {
System.out.println("Próbuję uzyskać dostęp za pomocą setAccessible");
field.setAccessible(true); // lub trySetAccessible() bez ryzyka wyjątku
field.set(obiekt1, "cba321");
System.out.println("Ustawiłem hasło " + field.get(obiekt1));
} catch(Exception e) {
System.out.println("Nie udało się ustawić prywatnego hasła po raz drugi");
System.out.println(e);
}
}
}
System.out.println();
System.out.println("Wywołam metodę:");
Method metodaPrzedstaw = klasa.getMethod("przedstawSie");
metodaPrzedstaw.invoke(obiekt1);
System.out.println();
// Poniżej widać co daje typ generyczny w Class i Constructor
// Dzięki niemu newInstance zwraca obiekt Konto bez żadnego rzutowania
System.out.println("Teraz utworzę obiekt klasy Konto");
Class<Konto> klasaKonto = Konto.class;
Constructor<Konto> constructorKonto = klasaKonto.getConstructor(int.class, int.class, Osoba.class);
Konto konto = constructorKonto.newInstance(123, 1000, obiekt1);
System.out.println(konto);
// mógłbym wywołać metodę w zwykły sposób:
konto.wplata(100);
// ale zobaczmy też jak wywołuje się metodę z parametrami przez API refleksji:
System.out.println("Teraz wywołam metodę wplata");
Method metodaWplata = klasaKonto.getMethod("wplata", int.class);
System.out.println(metodaWplata);
metodaWplata.invoke(konto, 300);
System.out.println(konto);
System.out.println();
Method metodaGetSaldo = klasaKonto.getMethod("getSaldo");
System.out.println(metodaGetSaldo);
Object wynik = metodaGetSaldo.invoke(konto);
System.out.println("getSaldo zwróciło w wyniku: " + wynik.getClass() + " " + wynik);
System.out.println();
System.out.println("A teraz przegląd informacji z deklaracji w klasie ABC");
Class<ABC> klasaABC = ABC.class;
System.out.println("Zadeklarowane pola:");
for (Field field : klasaABC.getDeclaredFields()) {
System.out.println(" * " + field);
System.out.println(" nazwa: " + field.getName());
System.out.println(" typ: " + field.getType());
if(field.getType().getDeclaringClass() != null) {
System.out.println(" Typ zadeklarowany wewnątrz: " + field.getType().getDeclaringClass());
}
Type genericType = field.getGenericType();
// wynikiem jest ParameterizedType tylko jeśli typ jest faktycznie sparametryzowany
if(genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
System.out.println(" To jest typ generyczny " + genericType);
System.out.println(" Parametry typowe:");
for (Type type : parameterizedType.getActualTypeArguments()) {
System.out.println(" > " + type);
}
}
Annotation[] adnotacje = field.getDeclaredAnnotations();
if(adnotacje != null && adnotacje.length > 0) {
System.out.println(" Adnotacje:");
for(Annotation an : adnotacje) {
System.out.println(" " + an);
Class<? extends Annotation> annoType = an.annotationType();
System.out.println(" parametry adnotacji:");
for (Method annoMethod : annoType.getDeclaredMethods()) {
System.out.println(" / " + annoMethod.getName() + " = " + annoMethod.invoke(an));
}
}
}
System.out.println();
}
}
}
package gotowe.p29_refleksja.klasy;
import java.util.List;
import java.util.Map;
public class ABC {
int i;
String s;
List<String> lista;
Map.Entry<String, Osoba> entry;
@SuppressWarnings("all")
String element;
@Deprecated
public String metoda(String arg) {
return "Hello " + arg;
}
}
package gotowe.p29_refleksja.klasy;
public class BrakSrodkow extends Exception {
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
}
package gotowe.p29_refleksja.klasy;
public class Konto {
// final oznacza, że pole numer jest ustawiane w tworzonym obiekcie, a później się nie zmienia
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
if(saldo < 0) {
throw new IllegalArgumentException("saldo nie może być ujemne");
}
if(wlasciciel == null) {
throw new IllegalArgumentException("właściciel konta nie może być null");
}
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
// "encapsulation" - "hermetyzacja"
// Tworząc klasę ukrywamy pola tej klasy jako prywatne
// i dajemy dostęp tylko w takim zakresie, jak chcemy.
// Tutaj: odczyt wszystkich pól,
// ale nie dajemy setterów do:
// - numeru - bo "numer nigdy się nie zmienia"
// - saldo - bo o zmianie salda decydują operacje biznesowe wykonywane na koncie (wplata/wyplata/przelew)
public Osoba getWlasciciel() {
return wlasciciel;
}
// Dzięki enkapsujacji mogę też pilnować, aby na zmiennych były wpisane poprawne wartości
// Np.: nie dopuszczamy wlaściciela null
// Dzięki wyjątkom mogę nie dopuścić do wykonania operacji, która zepsułaby wartość zmiennej w obiekcie
public void setWlasciciel(Osoba wlasciciel) {
if(wlasciciel == null) {
throw new IllegalArgumentException("właściciel konta nie może być null");
}
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
public void przelew(int kwota, Konto kontoDocelowe) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > this.saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
this.saldo -= kwota;
kontoDocelowe.saldo += kwota;
// Obiekt ma dostęp do zmiennych prywatnych innych obiektów tej samej klasy
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
}
package gotowe.p29_refleksja.klasy;
public class Osoba {
public String imie, nazwisko;
public int wiek;
private String haslo;
public Osoba() {
}
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
public void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " (" + wiek + " lat)";
}
private void metodaPrywatna() {
}
}
package gotowe.p29_refleksja.sklep_model;
import java.util.List;
public class Customer extends WspolnaNadklasa {
private static final long serialVersionUID = 1L;
private String customerEmail;
private String address;
private String city;
private String customerName;
private String phoneNumber;
private String postalCode;
private List<Order> orders;
public Customer() {
}
public String getCustomerEmail() {
return this.customerEmail;
}
public void setCustomerEmail(String customerEmail) {
this.customerEmail = customerEmail;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getCustomerName() {
return this.customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPostalCode() {
return this.postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public List<Order> getOrders() {
return this.orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public Order addOrder(Order order) {
getOrders().add(order);
order.setCustomer(this);
return order;
}
public Order removeOrder(Order order) {
getOrders().remove(order);
order.setCustomer(null);
return order;
}
}
\ No newline at end of file
package gotowe.p29_refleksja.sklep_model;
import java.util.Date;
import java.sql.Timestamp;
import java.util.List;
public class Order extends WspolnaNadklasa {
private static final long serialVersionUID = 1L;
private Integer orderId;
private Date deliveryDate;
private Timestamp orderDate;
private String status;
private List<OrderProduct> orderProducts;
private Customer customer;
public Order() {
}
public Integer getOrderId() {
return this.orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public Date getDeliveryDate() {
return this.deliveryDate;
}
public void setDeliveryDate(Date deliveryDate) {
this.deliveryDate = deliveryDate;
}
public Timestamp getOrderDate() {
return this.orderDate;
}
public void setOrderDate(Timestamp orderDate) {
this.orderDate = orderDate;
}
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}
public List<OrderProduct> getOrderProducts() {
return this.orderProducts;
}
public void setOrderProducts(List<OrderProduct> orderProducts) {
this.orderProducts = orderProducts;
}
public OrderProduct addOrderProduct(OrderProduct orderProduct) {
getOrderProducts().add(orderProduct);
orderProduct.setOrder(this);
return orderProduct;
}
public OrderProduct removeOrderProduct(OrderProduct orderProduct) {
getOrderProducts().remove(orderProduct);
orderProduct.setOrder(null);
return orderProduct;
}
public Customer getCustomer() {
return this.customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
\ No newline at end of file
package gotowe.p29_refleksja.sklep_model;
import java.math.BigDecimal;
public class OrderProduct extends WspolnaNadklasa {
private static final long serialVersionUID = 1L;
private BigDecimal actualPrice;
private BigDecimal actualVat;
private Integer quantity;
private Order order;
private Product product;
public OrderProduct() {
}
public BigDecimal getActualPrice() {
return this.actualPrice;
}
public void setActualPrice(BigDecimal actualPrice) {
this.actualPrice = actualPrice;
}
public BigDecimal getActualVat() {
return this.actualVat;
}
public void setActualVat(BigDecimal actualVat) {
this.actualVat = actualVat;
}
public Integer getQuantity() {
return this.quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Order getOrder() {
return this.order;
}
public void setOrder(Order order) {
this.order = order;
}
public Product getProduct() {
return this.product;
}
public void setProduct(Product product) {
this.product = product;
}
}
\ No newline at end of file
package gotowe.p29_refleksja.sklep_model;
import java.math.BigDecimal;
public class Product extends WspolnaNadklasa {
private Integer productId;
private String description;
private BigDecimal price;
private String productName;
private BigDecimal vat;
public Product() {
}
public Integer getProductId() {
return this.productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getProductName() {
return this.productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public BigDecimal getVat() {
return this.vat;
}
public void setVat(BigDecimal vat) {
this.vat = vat;
}
}
\ No newline at end of file
package gotowe.p29_refleksja.sklep_model;
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
Product product = new Product();
product.setProductId(123);
product.setProductName("pralka");
product.setDescription("Pralka bardzo dobrze pierze.");
product.setPrice(new BigDecimal("1390.90"));
product.setVat(new BigDecimal("0.23"));
System.out.println(product);
}
}
package gotowe.p29_refleksja.sklep_model;
import java.lang.reflect.Field;
abstract class WspolnaNadklasa {
@Override
public String toString() {
StringBuilder result = new StringBuilder();
Class<? extends WspolnaNadklasa> klasa = this.getClass();
result.append(klasa.getSimpleName()).append(" [");
int fieldNo = 0;
for(Field field: klasa.getDeclaredFields())
try {
if(fieldNo++ > 0) {
result.append(", ");
}
Object value;
if(field.trySetAccessible()) {
value = field.get(this);
} else {
value = "!";
}
result.append(field.getName()).append('=').append(value);
} catch(IllegalArgumentException | IllegalAccessException e) {
System.err.println(e);
}
result.append("]");
return result.toString();
}
}
package gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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 gotowe.p35_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);
}
}
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