Kolekcije u Javi

Koje su to kolekcije u javi i kakve su njihove razlike. Šta možemo da očekujemo od svake struktore i koja su njena svojstva.

Liste

uml

ArrayList

Deklaracija:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable  

Karakteristike:

  • Može da sadrži duplikate
  • Zadržava red upisivanja
  • Nije sinhronizovana
  • Ima nasumični operator pristupa
  • Ukratko, dinamički array

Funkcije:

  • void add(int index, Object element)
  • boolean add(Object o)
  • void clear()
  • int lastIndexOf(Object o)
  • Object[] toArray()
  • int indexOf(Object o)

Primer:

ArrayList<String> korisnici = new ArrayList();

korisnici.add("Marko");
korisnici.add("Pera");
korisnici.add("Mika");

for ( int i = 0; i < korisnici.size(); i++ ) {
    System.out.println( korisnici.get(i) );
}
// Iterator
Iterator it = korisnici.iterator();
while ( it.hasNext() ) {
    System.out.println( it.next() );
}

LinkedList

Deklaracija:

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable  

Karakteristike:

  • Može da sadrži duplikate
  • Zadržava red upisivanja
  • Nije sinhronizovana
  • Može da se koristi kao stek ili red
  • Brža je od ArrayList zato što nema potrebe za shiftovanje elemenata.

Funkcije:

  • void add(int index, Object element)
  • void addFirst(Object o)
  • void addLast(Object o)
  • boolean add(Object o)
  • boolean contains(Object o)
  • boolean remove(Object o)
  • int indexOf(Object o)
  • int lastIndexOf(Object o)
  • Object getFirst()
  • Object getLast()

Primer:

LinkedList<String> korisnici = new LinkedList();

korisnici.add("Marko");
korisnici.add("Pera");
korisnici.add("Mika");

for ( int i = 0; i < korisnici.size(); i++ ) {
    System.out.println( korisnici.get(i) );
}

// Iterator
Iterator it = korisnici.iterator();
while ( it.hasNext() ) {
    System.out.println( it.next() );
}

Razlike

Ima tri vrsta listi, neke razlike:

  • ArrayList - je implementirana kao dinamički niz.
  • LinkedList - je implementirana kao dvostruka lančana lista, ima mnogo bolje performanse na dodavanju i brisanju elemenata, ali i loši performanse prilikom get() i set() metode.
  • Vector - kao ArrayList samo je sinhronizovana.

test-liste
Slika preuzeta sa: programcreek.com

Setovi

HashSet

Deklaracija:

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable  

Karakteristike:

  • Ne može da sadrži duplikate
  • Elemente pamti pomoću mehanizma heširanje
  • Ne pamti redosled dodavanja
  • Moguće je pisati svoj hashCode

Funkcije:

  • boolean add(Object o)
  • boolean contains(Object o)
  • boolean remove(Object o)
  • void clear()

Primer:

HashSet<String> korisnici = new HashSet();

korisnici.add("Marko");
korisnici.add("Pera");
korisnici.add("Mika");
korisnici.add("Marko"); // Nece da se pojavi

// Iterator
Iterator it = korisnici.iterator();
while ( it.hasNext() ) {
    System.out.println( it.next() );
}

/*
Output:
    Pera
    Mika
    Marko
 */

Napomena:

  • Kad god se preklapa equals() metoda mora da se prekolopi i hashCode(). Važi i suprotno!
  • Koristiti ista polja za izračunavanje equals() za izračunavanje hashCode()!

TreeSet

Deklaracija:

public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable 

Karakteristike:

  • Ne može da sadrži duplikate, kao HashSet.
  • Elemente pamti pomoću mehanizma heširanje
  • Sortirana kolekcija, pamti u rastućem redosledu.

Funkcije:

  • boolean add(Object o)
  • Object first()
  • Object last()
  • boolean contains(Object o)
  • boolean remove(Object o)
  • void clear()

Primer:

TreeSet<String> korisnici = new TreeSet();

korisnici.add("Marko");
korisnici.add("Pera");
korisnici.add("Marko"); // Nece da se pojavi
korisnici.add("Aca");

// Iterator
Iterator it = korisnici.iterator();
while ( it.hasNext() ) {
    System.out.println( it.next() );
}

/*
Output:
    Aca
    Marko
    Pera
 */

Razlike

  • HashSet je znatno brža strukturna od TreeSet-a. Zato što pruža konstantno vreme osnovnim operacijama (add(), remove(),size() i contains()). Dok je TreeSet implementirano kao stablo samim tim su sve operacije log(n).
  • HashSet nije uređena kolekcija.
  • Obe kolekcije nisu thread-safe.
  • Generalno je brže da se elementi dodaju u HashSet i zatim da se prebaci u TreeSet za sortiranu kolekciju.

Mape

Mape sadrže dva polja ključ i vrednost. Mapa sadrži samo jedinstvene ključeve. Par ključ i vrednost se nazivaju entry.

TreeMap

Deklaracija:

public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, Serializable  

Karakteristike:

  • Ne može da sadrži duplikate.
  • Elemente pamti pomoću mehanizma heširanje
  • Sortirana kolekcija, sortira po ključu.

Funkcije:

  • Object put(K key, V value)
  • boolean containsKey(Object key)
  • boolean containsValue(Object value)
  • Object firstKey()
  • Object lastKey()
  • Object get(Object key)
  • Object remove(Object key)
  • Set entrySet()
  • int size()

Primer:

TreeMap<Integer, String> korisnici = new TreeMap();

korisnici.put(40, "Aca");
korisnici.put(20, "Pera");
korisnici.put(10, "Marko");
korisnici.put(30, "Marko"); // Pojavljuje se, ima jedinstven kljuc

for ( Map.Entry<Integer, String> entry : korisnici.entrySet() ) {
    System.out.println( entry.getKey() + " => " + entry.getValue() );
}

// Drugi nacin za iteraciju, iteracija po kljucevima
Iterator<Integer> itr = korisnici.keySet().iterator();

while (itr.hasNext()) {
    Integer key = itr.next(); // Ovo vraca kljuc (10, 20, 30...)
    String user = korisnici.get(key);
    System.out.println( key + " => " + user );
}

/*
Output:
    10 => Marko
    20 => Pera
    30 => Marko
    40 => Aca
 */

Razlike

Ima četiri tipa mapa, evo i neke razlike:

  • HashMap - je implementirana kao heš tabela, nije uređena kolekcija.
  • TreeMap - je implementirana kao crno-crveno stablo, uređena kolekcija po ključu.
  • LinkedHashMap - sadržava redosled upisivanja.
  • Hashtable - sinhronizovana HashMap-a.