Kolekcje są alternatywą dla tablic, nie mają ograniczeń wielkości.
Zamiast tworzyć tablicę, możemy użyć klasy ArrayList, z gotowymi metodami manipulującymi danymi.
Gdy korzystamy z metod ArrayList, musimy pamiętać, że należy rzutować typy, dlatego korzystając z kolekcji możemy od razu określić jaki typ danych będzie przechowywany.
Do obsługi danych w kolekcjach, możemy zastosować klasę Collections, która pozwala np. na sortowanie elementów
ArrayList
ArrayList jest tablicą, która może zostać zastąpiona inną, można jej używać do losowego pobierania danych i dodawania lub usuwania elementów.
Przykład:
import java.util.ArrayList;
import java.util.Collections;
public class ArrayList_Basics {
public static void main(String[] args) {
//tworzymy nowy obiekt ArrayList bez deklaracji typu
ArrayList simpleList = new ArrayList();
//dodajemy element do listy
simpleList.add(new String("pierwszy tekst"));
simpleList.add(new String("drugi tekst"));
//pobieramy element listy, odwołujemy się do niego tak jak w tablicy, czyli po indeksie licząc od 0
String element = (String)simpleList.get(0);//musimy dokonać rzutowania, bo przy deklaracji kolekcji nie określiliśmy typu
System.out.println(element); //otrzymamy:pierwszy tekst
//teraz skorzystamy z listy z deklaracją typu
ArrayList<String> typedList = new ArrayList<>();//drugi raz nie musimy wpisywać typu
//dodamy teraz nowe elementy, teraz będziemy mogli wybrać z listy String
typedList.add("string 1");
typedList.add("string 2");
typedList.add("string 3");
//pobieramy elementy
String el = typedList.get(1);//nie musimy rzutować
System.out.println(el);
//przeglądamy kolekcję
System.out.println("Lista:");
for (String s: typedList){
System.out.println(s);
}
//usuwamy elementy
typedList.remove(2);
System.out.println("Lista po usunięciu 3 elementu:");
for (String s: typedList){
System.out.println(s);
}
//dodamy element pod konkretny indeks - pozostałe się przesuną
typedList.add(0,"string 0");
System.out.println("Dodany element pod indeks 0:");
for (String s: typedList){
System.out.println(s);
}
//podmieniamy element listy
typedList.set(2,"podmieniony element");
System.out.println("Podmieniony element pod indeks 2:");
for (String s: typedList){
System.out.println(s);
}
//aby posortować elementy skorzystamy z klasy Collecttions
System.out.println("Sortujemy:");
Collections.sort(typedList);
for (String s: typedList){
System.out.println(s);
}
}
}
Metody ArrayList
Przetestujmy teraz możliwe metody ArrayList.
plik Person.java
//dodajemy nową prostą klasę operacyjną
public class Person {
private String name; //ustawiamy prywatną zmienną
//dodajemy konstruktor oraz gettery, settery i toString
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
plik ArrayListMethods.java
import java.util.ArrayList;
public class ArrayListMethods {
public static void main(String[] args) {
//tworzymy nowe obiekty
Person prs1 = new Person("Adam");
Person prs2 = new Person("Anna");
Person prs3 = new Person("Piotr");
Person prs4 = new Person("Damian");
Person prs5 = new Person("Jagoda");
//dodajemy ArrayList z typem Person
ArrayList<Person> al1 = new ArrayList<>();
//dodajemy do listy obiekty utworzone wyżej
al1.add(prs1);
al1.add(prs2);
al1.add(prs3);
al1.add(prs4);
al1.add(prs5);
for (Person p : al1) {
System.out.println(p);
}
//tworzymy nowe obiekty, które następnie będziemy dodawać do nowej listy
//następnie nową listę dołączymy do istniejącej
Person prs6 = new Person("Andrzej");
Person prs7 = new Person("Julia");
//tworzymy nową kolekcję
ArrayList<Person> al2 = new ArrayList<>();
//dołączamy nowe obiekty do listy al2
al2.add(prs6);
al2.add(prs7);
//-------------------------------------------------
//dołączamy drugą kolekcję do pierwszej kolekcji
al1.addAll(al2);
System.out.println("Uzupełniona kolekcja o nową kolekcję");
for (Person p : al1) {
System.out.println(p);
}
//--------------------------------------------------
//czy dany element istnieje w kolekcji
if (al1.contains(prs6)){
System.out.println("al1 zawiera prs6");
}
//--------------------------------------------------
//czy kolekcja zawiera wszystkie elementy innej kolekcji
if (al1.containsAll(al2)){
System.out.println("al1 zawiera elementy al2");
}
//jeżeli teraz dodalibyśmy do al2 nowy element to powyższy warunek zwróciłby false
//--------------------------------------------------
//usuwanie wszystkich elementów z jednej kolekcji, należących do innej kolekcji
al1.removeAll(al2);
if (al1.containsAll(al2)){
System.out.println("al1 zawiera elementy al2");
} else {
System.out.println("al1 nie zawiera elementów al2");
}
//--------------------------------------------------
//tworzenie tablicy z listy
Person[] people = new Person[al1.size()];
people = al1.toArray(people);
System.out.println("Tablica stworzona z listy ma " + people.length + " elementów.");
//--------------------------------------------------
//czyszczenie kolekcji
al1.clear();
if (al1.isEmpty()){
System.out.println("Kolekcja jest pusta");
}
}
}
Iterator
Iterator – alternatywa dla foreach. Do przeglądania kolekcji należy używać iteratora, pozwala on na uniknięcie błędów off-by-one oraz na jednolity sposób dostępu do struktur danych.
Przykład:
plik Animals.java
public class Animals {
//stworzymy kilka prywatnych pól
private String name, ocurrance;
int size; //1-mały, 2-średni, 3-duży, 4-olbrzymi
//dodajemy konstruktor
public Animals(String name, String ocurrance, int size) {
this.name = name;
this.ocurrance = ocurrance;
this.size = size;
}
//dodajemy gettery i settery
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOcurrance() {
return ocurrance;
}
public void setOcurrance(String ocurrance) {
this.ocurrance = ocurrance;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
//dodajemy toString
@Override
public String toString() {
return "Animals{" +
"name='" + name + '\'' +
", ocurrance='" + ocurrance + '\'' +
", size=" + size +
'}';
}
}
plik ArrayListIterator.java
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListIterator {
public static void main(String[] args) {
//tworzymy kolekcję przechowującą typ Animal
ArrayList<Animals> animal = new ArrayList<>();
//uzupełniamy kolekcję
animal.add(new Animals("Ryś", "Europe", 2));
animal.add(new Animals("Frog", "All world", 1));
animal.add(new Animals("Lion","Africa", 3));
animal.add(new Animals("Medusa", "Oceans", 1));
//Jak możemy iterować listy
//1. pętla for
System.out.println("\nPętla for:");
for (int i = 0; i<animal.size(); i++){//możemy ją stosowac gdy chcemy rozpocząc iterację od innego elementu niż 0
Animals animals = animal.get(i);
System.out.println(animals);
}
//2. pętla foreach
System.out.println("\nPętla foreach:");
for (Animals animals : animal) {
System.out.println(animals);
}
//3. Iterator
System.out.println("\nIterator:");
//iterator jest interfejsem, czyli pewnego rodzaju szablonem.
Iterator<Animals> iterator = animal.iterator(); //jeżeli chcemy zobaczyć jakie metody udostępnia iterator, ustawiamy kursor na napisie Iterator i naciskamy ctrl+b lub ctrl+LPM
//zastosujemy pętlę while, która sprawdzi, czy następny element listy istnieje
while (iterator.hasNext()){
Animals animals = iterator.next();//next() możemy użyć jeżeli wcześniej użyliśmy hasnext()
System.out.println(animals);
}
//-----------------------------------------------------------------
//METODY
//domknięcia inaczej zwane wyrażeniem lambda - to taki skrócony zapis
System.out.println("\nstosujemy wyrażenie lambda:");
animal.iterator().forEachRemaining(element -> {
System.out.println(element);
});
//tworzymy nową listę
ArrayList<String> subject = new ArrayList<>();
subject.add("PHP");
subject.add("JAVA");
subject.add("Python");
subject.add("HTML");
//usuwamy elementy
System.out.println("Usuwanie elementów");
Iterator<String> iterator1 = subject.iterator();
while (iterator1.hasNext()){
String str = iterator1.next();//next() możemy użyć jeżeli wcześniej użyliśmy hasnext()
//System.out.println(animals1);
if (str.equalsIgnoreCase("HTML")){
iterator1.remove();
}
System.out.println(subject);
}
}
}
LinkedList
LinkedList ma takie same metody jak ArrayList, ale jest listą powiązaną, dwukierunkową.
Poszczególne elementy mają powiązania z sąsiadującymi elementami. Ten typ sprawdza się przy iteracji i wielu modyfikacjach.
Przykład:
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
LinkedList<String> ll = new LinkedList<>();
ll.add("Pies");
ll.add("Kot");
String animal = "Papuga";
ll.add(animal);
System.out.println(ll);
//dodawanie na początku
ll.addFirst("Rybki");
//dodawanie na końcu
ll.addLast("Królik");
System.out.println(ll);
//pobieranie pierwszego elementu
System.out.println(ll.getFirst());
//pobieranie ostatniego elementu
System.out.println(ll.getLast());
//usuwanie pierwszego elementu
System.out.println(ll.removeFirst());
//usuwanie ostatniego elementu
System.out.println(ll.removeLast());
System.out.println(ll);
//sprawdzamy czy element występuje na liście
System.out.println(ll.contains(animal));
ll.add("Pies");
ll.add("Kot");
System.out.println(ll);
//usuwanie wystąpienia pierwszego
System.out.println(ll.removeFirstOccurrence("Pies"));
//usuwanie wystąpienia ostatniego
System.out.println(ll.removeLastOccurrence("Kot"));
System.out.println(ll);
//dodawanie lub usuwanie elementów po indeksię będą wolniejsze niż w ArrayList ponieważ w LinkedList elementy są powiązane między sobą, posiadają referencje do sąsiadujących elementów
ll.add(2,"królik");
ll.set(0,"Rybki");
System.out.println(ll.size());
}
}
ListIterator
Do iteracji list wykorzystuje się ListIterator, który posiada wiele przydatnych metod.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
public class ListIteratorExample {
public static void main(String[] args) {
LinkedList<String> ll = new LinkedList<>();
ll.add("Pierwszy");
ll.add("Dwa");
ll.add("Trzy");
ll.add("Cztery");
//przeglądanie listy za pomoca while
ListIterator<String> iterator = ll.listIterator();
while(iterator.hasNext()){//sprawdzamy czy jest dostępny następny element
String str = iterator.next();//pobieramy następny element
if(str.equalsIgnoreCase("Pierwszy")){
iterator.set("Jeden");//podmieniamy pobrany element na inny
}
if(str.equalsIgnoreCase("Cztery")){
iterator.add("Pięć");//dodajemy kolejny element do listy
}
}
ListIterator<String> iterator1 = ll.listIterator();
while(iterator1.hasNext()){//sprawdzamy czy jest dostępny następny element
String str = iterator1.next();
if(str.equalsIgnoreCase("Pięć")){
iterator1.remove();
}
}
//wyświetlimy listę po zmianach
System.out.println("Lista po zmianach:");
Iterator<String> itr = ll.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
//przeglądanie list od końca
System.out.println("LIsta od tyłu:");
ListIterator<String> iterator2 = ll.listIterator(ll.size());
while (iterator2.hasPrevious()){//sprawdzamy czy jest dostępny poprzedni element
String str = iterator2.previous();
System.out.println(str);
}
}
}
HashSet
HashSet pozwala na stworzenie kolekcji elementów o unikalnym hashu, czyli unikalnym kodzie wyróżniającym dany element. HashSet nie pozwoli na dodanie do kolekcji więcej niż jednego unikalnego elementu.
Każdy kolejny element kolekcji ma swój unikalny hash.
HashSet nie zachowuje kolejności elementów.
Przykład:
plik Animals.java
//tworzymy przykładową klasę i dodajemy konstruktor, gettery, settery i toString
import java.util.Objects;
public class Animals {
private String name;
public Animals(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animals{" +
"name='" + name + '\'' +
'}';
}
//przesłaniamy metody celem uniknięcia problemu duplikaji elementów na liście
//zaczynamy pisać public boolean i wybieramy opcję z listy, klikamy next... next.. itd
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; //jeżeli przekazany obiekt jest null lub nie zgadzają się klasy to zwraca false
Animals animals = (Animals) o; //konwertuje obiekt na animals
// poniższą linijkę modyfikujemy
// return Objects.equals(name, animals.name);
return this.name.equals(animals.getName()); //sprawdzamy czy nazwy są takie same
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
plik HashSetExample.java
import java.util.HashSet;
import java.util.Iterator;
public class HashSetExample {
public static void main(String[] args) {
//spróbujemy rozwiązać problem, który może się zdarzyć podczas stosowania HashCode: kiedy nowo stworzony obiekt przypiszemy do zmiennej i dodamy do kolekcji, a następnie
//dodamy następny element za pomocą add(), to oba elementy znajdą się na liście (będą miały różne hashe, a taką samą wartość)
HashSet<Animals> animal = new HashSet<>();
Animals animal1 = new Animals("dog"); //tworzymy nowy obiekt o unikalnym hashu
//próbujemy dodać 2 razy ten sam obiekt - 2 razy ten sam hash
animal.add(animal1);
animal.add(animal1);//ten element nie zostanie dodany, bo na liście jest już element o takim hashu
animal.add(new Animals("cat"));
animal.add(new Animals("fish"));
animal.add(new Animals("dog")); //ten element zostanie dodany pomimo, że "dog" już istnieje na liście, bo ma inny hash
//przeglądamy naszą kolekcję
Iterator<Animals> iterator = animal.iterator();//tworzymy iterator typu Animals - tak jak nazwa klasy
while (iterator.hasNext()){
Animals a = iterator.next();
System.out.println(a);
}
/*
W wyniku działania programu mamy 2 razy ten sam wpis, a tego chcemy uniknąć
Animals{name='dog'}
Animals{name='fish'}
Animals{name='cat'}
Animals{name='dog'}
musimy przesłonić 2 metody w klasie Animals - equals i hashcode i to rozwiąże problem
*/
}
}
TreeSet
TreeSet używamy do dużych zbiorów, sortuje on od razu rosnąco wszystkie elementy.
Do porównywania elementów tej samej klasy będziemy używali interfejsu Comparator i będziemy przesłaniali metodę compare.
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
ts.add(12);
ts.add(10);
ts.add(5);
ts.add(25);
//korzystamy z iteratora
Iterator<Integer> it = ts.iterator();
while (it.hasNext()){
System.out.println(it.next()); //otrzymuje posortowaną rosnąco listę
}
//iteracja od końca
Iterator<Integer> di = ts.descendingIterator();
while (di.hasNext()){
System.out.println(di.next());
}
}
}
TreeSet i Comparator
import java.util.Comparator;
import java.util.TreeSet;
/*
jeżeli w TreeSet korzystamy z własnych klas to używamy komparatora
*/
//stwórzmy klasę w tym samym pliku
class Animals{
private String name;
public Animals(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animals{" +
"name='" + name + '\'' +
'}';
}
}
//tworzymy nową klasę na bazie interfejsu Comparator, która umożliwi porównywanie elementów
class AnimalsComparator implements Comparator<Animals>
{
//zaimplementujemy metody
@Override
public int compare(Animals o1, Animals o2) {
//return 0;
return o1.getName().compareTo(o2.getName());//tak porównamy 2 elementy
}
}
public class TreeSetComparator {
public static void main(String[] args) {
TreeSet<Animals> animal = new TreeSet<>(new AnimalsComparator());//przekazujemy do konstruktora element AnimalsComparator
animal.add(new Animals("dog"));
animal.add(new Animals("cat"));
animal.add(new Animals("fish"));
animal.add(new Animals("rabbit"));
for (Animals a : animal) {
System.out.println(a);
}
/*
Otrzymujemy posortowaną listę
Animals{name='cat'}
Animals{name='dog'}
Animals{name='fish'}
Animals{name='rabbit'}
*/
}
}
HashMap
W języku Java nie istnieje tablica asocjacyjna, tak jak np. w PHP (tablica asocjacyjna pozwala na zamieanę indeksów liczbowych na słowne) i tu z pomocą przychodzi nam HashMap.
Iterując mapę musimy odwołać się do entrySet().
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
class Employee{
private String name;
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
'}';
}
}
public class HashMapExample {
public static void main(String[] args) {
HashMap<String, Employee> map = new HashMap<>(); //w nawiasach<> przekazujemy pary klucz->wartość
//dodamy teraz kilka elementów
map.put("worker", new Employee("Andrzej"));
map.put("manager", new Employee("Janina"));
map.put("HR", new Employee("Stefan"));
map.put("CEO", new Employee("Kasia"));
//pobierzemy wartość przechowywaną w kluczu CEO
Employee emp = map.get("CEO");
System.out.println(emp);
//wykonamy teraz iterację
Iterator i = map.entrySet().iterator();
//zastosowanie pętli while
while (i.hasNext()){
Map.Entry me = (Map.Entry) i.next(); //dokonujemy rzutowania
String key = (String) me.getKey(); //pobieramy klucz
Employee value = (Employee) me.getValue();//pobieramy wartość
System.out.println(key + " - " + value);
}
//zastosowanie pętli foreach
for (Map.Entry<String, Employee> e : map.entrySet()) {
String key = e.getKey(); //pobieramy klucz
Employee value = e.getValue();//pobieramy wartość
System.out.println(key + " - " + value);
}
}
}
PriorityQueue
PriorityQueue(czyt. pioriti kju), kolejki
Przykład:
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
//peek - pobiera element z kolejki, ale go nie usuwa
//poll - wyciąga element z kolejki, usuwa go
//tworzymy kolejkę priorytetów przechowującą liczby
PriorityQueue<Integer> pqInt = new PriorityQueue<>();
//dodajemy elementy do kolejki
pqInt.add(17);
pqInt.add(1);
pqInt.add(66);
pqInt.add(44);
System.out.println(pqInt.peek()); //kolejka jest już posortowana, możemy to zobaczyć wyświetlając pierwszy element
//celowo użyłam peek, aby nie usunąć elementu z kolejki
//wylistujmy kolejkę
//użyjemy metody poll, która usuwa elementy z kolejki więc po wylistowaniu wszystkich będzie pusta
//korzystamy z pętli while, która ma się zatrzymać kiedy nie będzie elementów w kolejce
while(!pqInt.isEmpty()){//sprawdzamy czy pqInt nie jest pusty
System.out.println(pqInt.poll());
}
//dodamy następne elementy
for (int i = 13; i > 10; i--) {
pqInt.add(i) ;
}
//wyświetlamy pierwszy element kolejki
System.out.println("pierwszy element kolejki: " + pqInt.peek());
while(!pqInt.isEmpty()){//sprawdzamy czy pqInt nie jest pusty
System.out.println(pqInt.poll());//listujemy kolejkę, widzimy że pierwszy element nadal jest
}
//już nic tam nie ma
System.out.println("Końcowa PriorityQueue: " + pqInt);
//SORTOWANIE KOLEJEK
//Comparator - interfejs Javy, który służy do kontroli nad sortowaniem elementów
//SORTOWANIE ROZSNĄCO
//tworzymy kolejkę priorytetów przechowującą liczby z komparatorem rosnącym
PriorityQueue<Integer> pqIntASC = new PriorityQueue<>(new PriorityQueueAndComparatorASC());//musimy przekazać do konstruktora nowy obiekt klasy PriorityQueueAndComparatorASC
//dodajemy elementy do kolejki
pqIntASC.add(17);
pqIntASC.add(1);
pqIntASC.add(66);
pqIntASC.add(44);
//wylistujmy kolejkę
//użyjemy metody poll, która usuwa elementy z kolejki więc po wylistowaniu wszystkich będzie pusta
//korzystamy z pętli while, która ma się zatrzymać kiedy nie będzie elementów w kolejce
System.out.println("kolejka posortowana rosnąco przez komparator");
while(!pqIntASC.isEmpty()){//sprawdzamy czy pqInt nie jest pusty
System.out.println(pqIntASC.poll());
}
//SORTOWANIE MALEJĄCO
//tworzymy kolejkę priorytetów przechowującą liczby z komparatorem malejącym
PriorityQueue<Integer> pqIntDESC = new PriorityQueue<>(new PriorityQueueAndComparatorDESC());//musimy przekazać do konstruktora nowy obiekt klasy PriorityQueueAndComparatorDESC
//dodajemy elementy do kolejki
pqIntDESC.add(17);
pqIntDESC.add(1);
pqIntDESC.add(66);
pqIntDESC.add(44);
//wylistujmy kolejkę
//użyjemy metody poll, która usuwa elementy z kolejki więc po wylistowaniu wszystkich będzie pusta
//korzystamy z pętli while, która ma się zatrzymać kiedy nie będzie elementów w kolejce
System.out.println("kolejka posortowana malejąco przez komparator");
while(!pqIntDESC.isEmpty()){//sprawdzamy czy pqInt nie jest pusty
System.out.println(pqIntDESC.poll());
}
//SORTOWANIE PO DŁUGOŚCI
//tworzymy kolejkę przechowującą wpisy i będziemy je sortować wg długości znaków
PriorityQueue<String> pqIntLength = new PriorityQueue<>(new PriorityQueueAndComparatorLength());//musimy przekazać do konstruktora nowy obiekt klasy PriorityQueueAndComparatorLength
//dodajemy elementy do kolejki
pqIntLength.add("mały");
pqIntLength.add("najdłuższy");
pqIntLength.add("średni");
//wylistujmy kolejkę
//użyjemy metody poll, która usuwa elementy z kolejki więc po wylistowaniu wszystkich będzie pusta
//korzystamy z pętli while, która ma się zatrzymać kiedy nie będzie elementów w kolejce
System.out.println("kolejka posortowana rosnąco przez komparator wg długości znaków");
while(!pqIntLength.isEmpty()){//sprawdzamy czy pqInt nie jest pusty
System.out.println(pqIntLength.poll());
}
//COMPARABLE vs COMPARATOR i SORTOWANIE PO PRIORYTECIE
/*
Poznaliście do tej pory Comparator, który pozwala porównać ze sobą 2 różne obiekty, np. gdy trzeba porównać ludzi wg wieku, imienia itp.
Comparable pozwala porównać "siebie" z innym obiektem
*/
//tworzymy nową kolejkę
PriorityQueue<PriorityQueueAndComparable> comparable = new PriorityQueue<>();
//stwórzmy sobie listę języków do nauczenia się z priorytetami
comparable.add(new PriorityQueueAndComparable(1, "Python"));
comparable.add(new PriorityQueueAndComparable(4, "PHP"));
comparable.add(new PriorityQueueAndComparable(3, "Java"));
comparable.add(new PriorityQueueAndComparable(2, "C++"));
//te elementy będą z automatu porównywane z tymi, które znajdują się w kolejce
while (!comparable.isEmpty()){
System.out.println(comparable.poll());
}
//a teraz rozwiązanie powyższego z użyciem komparatora
PriorityQueue<PriorityQueueAndComparator> comparator = new PriorityQueue<>();
//stwórzmy sobie listę języków do nauczenia się z priorytetami
comparable.add(new PriorityQueueAndComparable(1, "Python"));
comparable.add(new PriorityQueueAndComparable(4, "PHP"));
comparable.add(new PriorityQueueAndComparable(3, "Java"));
comparable.add(new PriorityQueueAndComparable(2, "C++"));
//te elementy będą z automatu porównywane z tymi, które znajdują się w kolejce
while (!comparator.isEmpty()){
System.out.println(comparator.poll());
}
}
}
PriorityQueue, Comparable i Comparator
Stworzymy listę priorytetów, którą musimy posortować na kilka sposobów:
plik PriorityQueueAndComparable.java
public class PriorityQueueAndComparable implements Comparable<PriorityQueueAndComparable>{
//dodajemy 2 pola klasy
private int priority;//pole z priorytetem zadania
private String name;
//dodajemy następujące elementy: konstruktor, gettery i settery oraz toString
//implementujemy metodę CompareTo, którą musimy lekko zmodyfikować
public PriorityQueueAndComparable(int priority, String name) {
this.priority = priority;
this.name = name;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "PriorityQueueAndComparable{" +
"priority=" + priority +
", name='" + name + '\'' +
'}';
}
@Override
//będziemy porównywali ten element z tym co przekaże Java w nawiasie
public int compareTo(PriorityQueueAndComparable o) {
//ustawiamy wartość z tego obiektu jako "a" i przekazaną jako parametr wartość jako "b" i dokonujemy porównania
int a = this.priority;
int b = o.priority;
if(a==b) return 0;
if (a>b)
return 1;
else
return -1;
}
}
plik PriorityQueueAndComparator.java
import java.util.Comparator;
//tworzymy nową klasę, która implementuje metody z Comparator wykorzystując klasę PriorityQueueAndComparable
public class PriorityQueueAndComparator implements Comparator<PriorityQueueAndComparable> {
//implementujemy metodę Compare
@Override
public int compare(PriorityQueueAndComparable o1, PriorityQueueAndComparable o2) {
//porównamy 2 elementy o1 i o2
int a = o1.getPriority();
int b = o2.getPriority();
if(a==b) return 0;
if(a>b) //kolejność rosnąca
return 1;
else
return -1;
}
}
plik PriorityQueueAndComparatorLength.java
import java.util.Comparator;
//będziemy sortować wpisy wg długości znaków
public class PriorityQueueAndComparatorLength implements Comparator<String> {
@Override
public int compare(String str1, String str2) {
return str1.length()-str2.length();//dla kolejności od najkrótszego do najdłuższego
//return str2.length()-str1.length();//dla kolejności od najkrótszego do najdłuższego
}
}
plik PriorityQueueAndComparatorASC.java
import java.util.Comparator;
//KOLEJNOŚĆ ROSNĄCA
//tworzymy klasę implementującą komparator
public class PriorityQueueAndComparatorASC implements Comparator<Integer> {
//ALT+g i implementujemy metodę - compare, którą musimy lekko zmienić
//sprawdzimy 3 warunki jeżeli elementy są równe, jeden jest mniejszy lub większy
@Override
public int compare(Integer x, Integer y) {
if (x==y) return 0;
if(x>y)
return 1;
else
return -1;
}
}
plik PriorityQueueAndComparatorASC.java
import java.util.Comparator;
//KOLEJNOŚĆ MALEJĄCA
//tworzymy klasę implementującą komparator
public class PriorityQueueAndComparatorDESC implements Comparator<Integer> {
//ALT+g i implementujemy metodę - compare, którą musimy lekko zmienić
//sprawdzimy 3 warunki jeżeli elementy są równe, jeden jest mniejszy lub większy
@Override
public int compare(Integer x, Integer y) {
if (x==y) return 0;
if(x<y)
return 1;
else
return -1;
}
}
Zadanie 1:
Napisz program, który sprawdzi czy podany element (target) znajduje się w posortowanej liście (numbers). Zadeklaruj:
listę postaci [1, 2, 3, 4, 5, 6, 7, 8, 9]
zmienną target = 7
Zasada działania algorytmu:
- Ustalamy indeks startowy (start) oraz końcowy (end) oraz flagę flag = None.
- Dopóki indeks startowy jest nie większy niż indeks końcowy wybieramy środkowy indeks (mid) listy (średnia arytmetyczna indeksu startowego i końcowego -> należy pamiętać o skonwertowaniu wyniku funkcją int). Jeżeli indeks startowy jest większy niż indeks końcowy kończymy działanie algorytmu.
- Sprawdzamy czy element listy dla tak obliczonego indeksu jest naszym szukanym (target). Jeżeli tak, ustawiamy flagę flag na wartość True i kończymy działanie algorytmu. Jeżeli nie -> krok 4.
- Sprawdzamy, czy wartość elementu listy dla indeksu mid jest mniejsza niż target. Jeśli tak, to zwiększamy indeks startowy o 1. Jeśli nie, zmniejszamy indeks końcowy o 1 i przechodzimy do kroku 2.
Po wykonaniu pętli while w zależności od wartości flagi flag wydrukuj do konsoli tekst: 'Znaleziono’, 'Nie znaleziono’.
Oczekiwany wynik:
Znaleziono
Zadanie 2: Zadeklaruj listę liczb:
items = [1, 3, 4, 5, 6, 9, 10, 17, 23, 24]
Napisz program, który usunie liczby nieparzyste i zwróci pozostałe. Wynik wydrukuj do konsoli.
Oczekiwany wynik:
[4, 6, 10, 24]
Zadanie 3:
Zadeklaruj listę liczb:
items = [1, 5, 3, 2, 2, 4, 2, 4]
Napisz program, który usunie duplikaty z listy (kolejność musi zostać zachowana).
Oczekiwany wynik:
[1, 5, 3, 2, 4]
Zadanie 4:
Zadeklaruj listę postaci: probabilities = [0.21, 0.91, 0.34, 0.55, 0.76, 0.02]
Napisz program, który z podanej listy zwróci listę wartości powyżej ustalonego progu 0.5.
Oczekiwany wynik:
[0.91, 0.55, 0.76]
Zadanie 5:
Rozważmy problem klasyfikacji binarnej. Model uczenia maszynowego zwraca prawdopodobieństwo przynależności do klasy. Jeżeli jest ono mniejsze niż 0.5 próbka zostaje przypisana do klasy 0, przeciwnie do klasy 1.
Podana jest lista prawdopodobieństw otrzymanych z modelu uczenia maszynowego:
probabilities = [0.21, 0.91, 0.34, 0.55, 0.76, 0.02]
Napisz program, który przypisze klasę 0 dla wartości mniejszych niż 0.5 oraz 1 dla wartości większych lub równych 0.5. Wynik w postaci listy wydrukuj do konsoli.
Oczekiwany wynik:
[0, 1, 0, 1, 1, 0]
Zadanie 6: Napisz program, który porówna dwie listy i zwróci wartość True w przypadku gdy listy będą zawierały co najmniej jeden ten sam element. W przeciwnym razie zwróci wartość False. Użyj instrukcji break.
Podane listy:
- list1 = [1, 2, 0]
- list2 = [4, 5, 6, 1]
Wynik wydrukuj do konsoli.
Zadanie 7: Podana jest lista hashtags:
- hashtags = [’holiday’, 'sport’, 'fit’, None, 'fashion’]
Sprawdź, czy każdy obiekt z listy jest obiektem klasy str. Jeżeli tak wydrukuj wartość True, w przeciwnym przypadku wydrukuj wartość False. Użyj instrukcji break.
Zadanie 8:
Podana jest lista spółek z indeksu WIG.GAMES wraz z ceną zamknięcia i walutą:
gaming = {
’11B’: [362.5, 'PLN’],
’CDR’: [74.25, 'USD’],
’CIG’: [0.85, 'PLN’],
’PLW’: [79.5, 'USD’],
’TEN’: [300.0, 'PLN’]
}
Używając instrukcji continue zbuduj pętlę, która pozwoli zmienić cenę zamknięcia wyrażoną w USD na PLN. Przyjmij kurs USDPLN = 4.0.
Słownik gaming wydrukuj do konsoli.
Pomocniczy wynik:
{’11B’: [362.5, 'PLN’],
’CDR’: [297.0, 'PLN’],
’CIG’: [0.85, 'PLN’],
’PLW’: [318.0, 'PLN’],
’TEN’: [300.0, 'PLN’]}
Oczekiwany wynik:
{’11B’: [362.5, 'PLN’], 'CDR’: [297.0, 'PLN’], 'CIG’: [0.85, 'PLN’], 'PLW’: [318.0, 'PLN’], 'TEN’: [300.0, 'PLN’]}
Zadanie 9:
Podana jest niepełna lista imion (jednego brak):
names = [’Jack’, 'Leon’, 'Alice’, None, 'Bob’]
Lista składa się tylko z obiektów typu str lub wartości None. Posługując się instrukcją continue wydrukuj do konsoli tylko poprawnie przekazane imiona (obiekty typu str).
Oczekiwany wynik:
Jack
Leon
Alice
Bob
Zadanie 10:
Podana jest poniższa lista:
project_ids = [’02134′, '24253′]
Sprawdź czy następujące id projektu:
project_id = '02135′
występuje w liście project_ids. Jeśli nie dodaj id tego projektu do listy. Następnie wydrukuj listę project_ids do konsoli.
Oczekiwany wynik:
[’02134′, '24253′, '02135′]
Zadanie 11:
Napisz program, który utworzy histogram – rozkład częstości w postaci słownika z podanych wartości:
items = [’x’, 'y’, 'z’, 'y’, 'x’, 'y’, 'y’, 'z’, 'x’]
W odpowiedzi utworzony słownik wydrukuj do konsoli.
Oczekiwany wynik:
{’x’: 3, 'y’: 4, 'z’: 2}
Zadanie 12:
Podana jest lista indeksów notowanych na GPW:
indexes = [
„WIG”,
„WIG-banki”,
„WIG-budownictwo”,
„WIG-CEE”,
„WIG-chemia”,
„WIG-energia”,
„WIG-ESG”,
„WIG-górnictwo”,
„WIG-informatyka”,
„WIG-leki”,
„WIG-media”,
„WIG-motoryzacja”,
„WIG-nieruchomości”,
„WIG-odzież”,
„WIG-paliwa”,
„WIG-Poland”,
„WIG-spożywczy”,
„WIG-telekomunikacja”,
„WIG-Ukraine”,
„WIG.GAMES”,
„WIG.MS-BAS”,
„WIG.MS-FIN”,
„WIG.MS-PET”,
„WIG20”,
„WIG20dvp”,
„WIG20lev”,
„WIG20short”,
„WIG20TR”,
„WIG30”,
„WIG30TR”,
„WIGdiv”,
„WIGtech”,
]
Dokonaj iteracji po liście indexes oraz wydrukuj do konsoli tylko te indeksy, które zwierają w nazwie ’20’ lub ’30’.
Oczekiwany wynik:
WIG20
WIG20dvp
WIG20lev
WIG20short
WIG20TR
WIG30
WIG30TR
Zadanie 13:
Podany jest słownik spółek z indeksu sektorowego WIG.GAMES. Kluczem jest 3-literowy kod spółki (ticker), wartością cena zamknięcia:
gaming = {
’11B’: 362.5,
'CDR’: 297.0,
'CIG’: 0.85,
'PLW’: 318.0,
'TEN’: 300.0
}
Przeprowadź iterację po słowniku. Wydrukuj kody (tickery) tych spółek, których cena zamknięcia jest większa niż 100.00 PLN.
Oczekiwany wynik:
11B
CDR
PLW
TEN
Zadanie 14: Podana jest lista imion wprowadzonych do systemu przez użytkowników (bez procesu walidacji):
names = [’Jack’, 'Leon’, 'Alice’, ’32-3c’, 'Bob’]
Sprawdź, czy każde imię jest poprawne (składa się tylko z liter). Jeżeli tak, wynik wydrukuj do konsoli w następującej postaci, np. Hello Jack!
Wskazówka: Użyj metody str.isalpha().
Oczekiwany wynik:
Hello Jack!
Hello Leon!
Hello Alice!
Hello Bob!