18Mitä ovat geneeriset tyypit (generics) ja mitä tarkoittaa tyyppien poisto (type erasure)?
Geneeristen tyyppien avulla koodissa voidaan ilmaista tyyppiturvallisia säiliöitä ja API-rajapintoja (Application Programming Interface), kuten `List<String>`. Käännösaikana kääntäjä tarkistaa tyypit ja lisää tarvittaessa tyyppimuunnoksia. Suoritusaikana suurin osa geneerisestä tyyppitiedosta poistetaan, joten `List<String>` ja `List<Integer>` käyttävät samaa suorituksenaikaista luokkaa. Tämän vuoksi ei voida suoraan luoda instanssia `new T()`, käyttää alkeistietotyyppejä tyyppiparametreina tai tarkistaa tyyppiä luotettavasti rakenteella `instanceof List<String>`.
List<String> names = new ArrayList<>();
names.add("Alice");
List<? extends Number> producer;
List<? super Integer> consumer;
Kokeile vastata tähän kysymykseen tekoälyvalmentajan kanssa
19Mikä on Java Collections Framework?
Collections Framework on kokoelma rajapintoja ja toteutuksia oliojoukkojen tallentamiseen ja käsittelyyn. Ydinrajapintoihin kuuluvat `List`, `Set`, `Queue`, `Deque` ja `Map`. Toteutuksiin kuuluvat puolestaan muun muassa `ArrayList`, `LinkedList`, `HashSet`, `TreeSet`, `HashMap`, `TreeMap` ja `PriorityQueue`. Oikea kokoelma valitaan hakumallin, järjestysvaatimusten, yksilöllisyyden, hakuoperaatioiden aikavaativuuden, muistinkulutuksen ja samanaikaisuusvaatimusten perusteella.
List<String> list = new ArrayList<>();
Set<Long> ids = new HashSet<>();
Map<Long, User> usersById = new HashMap<>();
Deque<String> queue = new ArrayDeque<>();
Kokeile vastata tähän kysymykseen tekoälyvalmentajan kanssa
20Miten `HashMap` toimii?
`HashMap` tallentaa avain-arvoparit lokeroihin (buckets), jotka valitaan avaimen tiivisteen (hash) perusteella. Hakua varten se laskee tiivisteen, etsii oikean lokeron ja vertailee avaimia `equals`-metodilla. Törmäykset käsitellään lokeron sisällä; nykyaikaisessa Javassa pitkät ketjut voidaan muuttaa tasapainotetuiksi puiksi tiettyjen ehtojen täyttyessä. `HashMap` sallii yhden `null`-avaimen ja useita `null`-arvoja, se ei ole säieturvallinen, ja sen koko kasvaa automaattisesti, kun kuormituskertoimen kynnysarvo ylittyy.
Map<Long, User> users = new HashMap<>();
users.put(user.id(), user);
User found = users.get(user.id());
Kokeile vastata tähän kysymykseen tekoälyvalmentajan kanssa
21Mitä eroa on HashMap-, LinkedHashMap-, TreeMap- ja ConcurrentHashMap-luokilla?
`HashMap` tarjoaa nopean järjestämättömän pääsyn eikä ole säieturvallinen. `LinkedHashMap` säilyttää lisäys- tai käyttöjärjestyksen ja on hyödyllinen LRU (Least Recently Used) -tyyppisissä välimuisteissa. `TreeMap` pitää avaimet lajiteltuna luonnollisen järjestyksen tai `Comparator`-rajapinnan mukaan ja sen operaatioiden aikavaativuus on O(log n). `ConcurrentHashMap` on suunniteltu samanaikaiseen käyttöön segmentoidun tai sisäisen synkronoinnin avulla, se ei salli null-avaimia tai -arvoja, ja sitä kannattaa suosia `synchronizedMap`:n sijaan raskaassa kuormituksessa.
map.computeIfAbsent(key, ignored -> loadValue());
Kokeile vastata tähän kysymykseen tekoälyvalmentajan kanssa
22Mitä eroa on ArrayList- ja LinkedList-luokilla?
`ArrayList` perustuu taulukkoon. Se tarjoaa nopean indeksipohjaisen haun, tiiviin muistiasettelun ja tehokkaan läpikäynnin, mutta alkioiden lisääminen keskelle vaatii muiden alkioiden siirtämistä. `LinkedList` on kaksisuuntaisesti linkitetty lista. Siihen lisääminen on kevyempää, jos kohdesolmu on jo tiedossa, mutta indeksipohjaisen haun aikavaativuus on O(n), muistin lisäkuorma on suurempi ja välimuistin paikallisuus on huonompi. Monissa todellisissa sovelluksissa `ArrayList` on nopeampi, vaikka mukana olisi jonkin verran lisäyksiä.
Kokeile vastata tähän kysymykseen tekoälyvalmentajan kanssa
23Mitä eroa on Comparable- ja Comparator-rajapinnoilla?
`Comparable` määrittää luokan sisäisen luonnollisen järjestyksen `compareTo`-metodin avulla. `Comparator` on erillinen olio tai lambda, joka määrittää ulkoisen järjestyksen. `Comparable` on hyödyllinen silloin, kun tyypillä on yksi ilmeinen oletusjärjestys. `Comparator` on parempi valinta, kun on olemassa useita eri järjestämistapoja, kuten nimen, päivämäärän tai prioriteetin mukaan. `compare`- ja `compareTo`-metodien on oltava johdonmukaisia ja mieluiten yhteensopivia `equals`-metodin kanssa, kun niitä käytetään lajitelluissa Set- tai Map-tietorakenteissa.
class User implements Comparable<User> {
private int age;
@Override
public int compareTo(User other) {
return Integer.compare(age, other.age);
}
}
Comparator<User> byName =
Comparator.comparing(User::getName);
Comparator<User> byAgeThenName =
Comparator.comparingInt(User::getAge)
.thenComparing(User::getName);
Kokeile vastata tähän kysymykseen tekoälyvalmentajan kanssa