package p12_kolekcje;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class A_Wprowadzenie {

	public static void main(String[] args) {
		// W języku Java mamy tablice:
		int[] ti = new int[10];
		String[] ts = {"Ala", "Ola", "Ela"};
		
		System.out.println(Arrays.toString(ti));
		System.out.println(Arrays.toString(ts));
		// Tablice mają swoje ograniczenia:
		// - nie posiadają metod, a pewne ogólne operacje dla tablic są dostępne w klasie Arrays
		Arrays.fill(ti, 4);
		System.out.println(Arrays.toString(ti));
		
		// - nie da się zmienić rozmiaru istniejącej tablicy; nie ma operacji "dodaj nowy element na końcu"
		// ewentualnie można użyć copyOf, aby stworzyć NOWĄ większą tablicę, ale to jest kosztowne i nie zawsze wygodne
		ts = Arrays.copyOf(ts, 5);
		ts[3] = "Ula";
		System.out.println(Arrays.toString(ts));
		System.out.println();
		
		// Kolekcja to klasa, której obiekty służą do przechowywania w pamięci wielu obiektów.
		// Główne rodzaje kolekcji: List, Queue, Set, Map, przy czym Map nie jest podinterfejsem interfejsu Collection
		
		List<String> lista = new ArrayList<>();
		// dodawanie elementu na koniec:		
		lista.add("Adam");
		lista.add("Ludwik");
		lista.add("Xawery");
		System.out.println(lista + " size = " + lista.size());
		// Dla kolekcji działa pętla for-each
		for(String s : lista) {
			System.out.println("Witaj " + s);
		}
		// Listy - ale już nie inne kolekcje - posiadają metody get oraz set, które dają dostęp do elementów o określonym numerze
		System.out.println("Element nr 2 to jest " + lista.get(2));
		lista.set(2, "Ksawery");
		lista.add("Adam");
		System.out.println("Element nr 2 to teraz jest " + lista.get(2));
		System.out.println(lista);
		System.out.println();
		
		// Kolejki tu pomińmy...
		
		// Zbiór:
		// - nie zawiera duplikatów
		// - ma prawo zmienić kolejność elementów - ale to zależy, której klasy użyjemy
		// - nie są dostępne operacje get(i) itp.
		Set<String> zbior = new HashSet<>();
		zbior.add("Warszawa");
		zbior.add("Kraków");
		zbior.add("Katowice");
		System.out.println(zbior);
		zbior.add("Kraków");
		System.out.println(zbior);
		// operacja add zwraca true, jeśli element został dodany, a false, jeśli nie został dodany (bo już istniał)
		// Dla zbiorów operacja contains (sprawdzająca, czy element należy) działa wydajnie.
		if(zbior.contains("Katowice")) {
			System.out.println("Katowice są");
		}
		
		// słownik / mapa służy do przechowywania par klucz → wartość
		Map<String, Integer> cennik = new HashMap<>();
		cennik.put("kawa", 15);
		cennik.put("herbata", 19);
		cennik.put("ciastko", 22);
		System.out.println(cennik);
		System.out.println("cena kawy: " + cennik.get("kawa"));
		System.out.println("cena szampana: " + cennik.get("szampan")); // brak klucza → null
		cennik.put("ciastko", 19);
		System.out.println(cennik);
		System.out.println();
		
		// Można utworzyć jeden kolekcji na podstawie innego:
		Set<String> zbiorImion = new TreeSet<>(lista);
		System.out.println(zbiorImion);
		
		// Nie istnieją kolekcje typów prostych - zawsze trzeba użyć klasy
		// List<int> liczby = new ArrayList<>();

		List<Integer> liczby = new ArrayList<>();
		liczby.addAll(List.of(5, 10, 15, 20, 25));
		System.out.println(liczby);
	}

}
