Ús de col·leccions
Tota Collection és un Iterable, la qual cosa serveix per iterar qualsevol List, Set o Queue.
Per iterar tenim el mètode iterator():
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
Integer nextInt = iterator.next();
}
També es pot utilitzar el format for-each loop:
for (Integer nextInt: list) {
// ...
}
Hi ha dos mètodes d’Object que utilitzem en relació a les col·leccions, i que sovint cal sobreescriure:
public int hashCode(): retorna un sencer diferent per a cada objecte. Siequals()retornatrue, han de retornar el mateix sencer. S’utilitza per a inserir i cercar a col·leccions que utilitzen taules hash.public boolean equals(Object obj): retornatruesi els dos objectes es consideren iguals. Si es retornatrue, cal que també hashCode() retorni el mateix sencer.Objectté aquesta implementació per defecte:this == obj, que significa que són el mateix objecte. Però sovint volem retornartrueencara que no es tracti del mateix objecte. Per exemple,Integerretornatruesi els dos objectes contenen el mateix valorint.
Implementació típica de equals():
public boolean equals(Object o){
if (o == null)
return false;
if (!(o instanceof Treballador))
return false;
Treballador altre = (Treballador) o;
return this.treballadorId == altre.treballadorId;
}
Implementació típica de hashcode():
public int hashCode(){
return (int) treballadorId;
}
Implementació alternativa de hashcode() utilitzant Objects:
public int hashCode(){
return Objects.hash(treballadorId); // llista de camps de l'objecte
}
Altres mètodes Collection<E>:
boolean add(E e);void clear();boolean contains(Object o);boolean isEmpty();boolean remove(Object o);int size()
El mètode contains() utilitza el mètode equals() per veure si existeix l’element. Per tant, depèn de la implementació de cada classe. En el cas de Integer, la documentació diu:
- The result is
trueif and only if the argument is notnulland is anIntegerobject that contains the sameintvalue as this object.
Per tant, són iguals dos objectes Integer que contenen el mateix valor sencer. Object implementa el mètode equals() com la igualtat (this == o). Compte, perquè si es pretén sobreescriure el mètode equals(), sempre s’ha de sobreescriure també el mètode hashcode(). Veure Objects.hash().
List<E> afegeix operacions per posicions:
void add(int index, E element)E get(int index)E set(int index, E element)E remove(int index)
La implementació més clàsica és la de ArrayList. LinkedList podria ser interessant si s’insereixen elements al començament amb freqüència.
Set<E> és una col·lecció que no conté repeticions. O sigui, no hi ha dos elements tals que e1.equals(e2). No conté mètodes addicionals respecte Collection.
Tenim tres implementacions:
HashSetutilitza elhashCode()de la clau per a optimitzar l’accés als elements.TreeSetutilitza una estructura en arbre navegable segons l’ordre dels elements, que han de ser comparables (implementen la interfície Comparable). Es basa enTreeMap.LinkedHashSetpermet navegar els elements segons l’ordre d’inserció.
Queue<E> és una col·lecció amb dos extrems: el cap, per on surten els elements, i la cua, per on entren. Habitualment funciona en ordre FIFO, i el primer que entra és el primer que surt.
boolean add(E e): afegeix un element per la cua (amb excepció).boolean offer(E e): afegeix un element per la cua.E remove(): treu l’element del cap (amb excepció).E poll(): treu l’element del cap.E element(): consulta l’element del cap sense treure’l (amb excepció).E peek(): consulta l’element del cap sense treure’l.
Com es veu, hi ha dos mètodes per a cada operació (afegir, treure, consultar). Els marcats “amb excepció” llancen una excepció quan l’operació no es pot fer, mentre que els altres retornen false o null. Amb una cua buida, remove() llança NoSuchElementException i poll() retorna null.
Aquestes són les implementacions habituals:
ArrayDeque: la tria per defecte, tant per aQueuecom per aDeque.LinkedList: útil si necessites tractar la mateixa estructura també com aList.PriorityQueue: la sortida segueix l’ordre natural dels elements o un comparador, en lloc de l’ordre d’entrada.
Deque<E> és una Collection i també una Queue<E>. Permet afegir i treure elements pels dos extrems, ‘first’ i ‘last’. També és la manera recomanada d’implementar una pila (LIFO) amb els mètodes:
void push(E e): afegeix un element a la pila (cap)E pop(): treu un element de la pila (cap)E peek(): examina l’element de la pila (cap)
Existeix una classe Stack, però la seva documentació recomana fer servir Deque al seu lloc: Deque<Integer> pila = new ArrayDeque<>();.
LinkedList també implementa Deque.