Professional Documents
Culture Documents
Collections
Java Data Structures
- no restrictions/guarantees regarding:
● order (element position)
● uniqueness
● sorting
List
ArrayList<E>
● fast access by index
● slow add/remove operations
● backed by an array, needs a contiguous
memory area
LinkedList<E>
● slow access by index
● fast add/remove operations
● no need for contiguous memory area
● needs slightly more memory
List - Example
System.out.println(names.size()); //4
System.out.println(names); //[john, mary, anna, mary] - nice toString
HashSet<E>
● Safest option, good performance
● Iteration order can be random
● Uses a HashMap internally (details to follow)
LinkedHashSet<E>
● In addition to a normal HashSet, also stores the elements in a double linked list
● Preserves insertion order (not required by Set interface, but happens due to the
actual implementation)
Set - HashSet example
TreeSet<E>
● elements are sorted (don’t keep insertion order, but are ordered by a specific
criteria - using either compareTo or with a custom Comparator)
● specific methods:
■ first, last
■ floor: find the greatest element lower or equal to the given argument
■ ceiling: find the lowest element greater or equal to the given argument
■ higher, lower: greatest/lowest elem strictly lower/greater than given arg
■ subSet, tailSet, headSet, descendingSet, pollFirst, pollLast, etc.
names.add("john");
names.add("mary");
names.add("anna");
names.add("mary"); //duplicate (so not added)
names.add("dan");
names.add("emma");
HashSet
TreeSet
Collection - Other types
java.lang.Collections - class with some static utility methods you may use/explore:
- sort - sort a collection by natural ordering of the elements
- binarySearch - searches for an element in a sorted collection (fast)
- min, max - find min/max element of a collection (according to their natural ordering)
- replaceAll - replace all occurrences of a specific element
- reverse, rotate, shuffle - reorder the collection in various ways
- swap - swap 2 elements of the collection
- indexOfSublist - find position of a sublist
- frequency - return frequency (count) of a given element in the collection
Notes:
- remember about Arrays.asList() method (convert an array to a List)
- check the constructors of common Set/List implementations - besides the default one (for an
empty collection), they usually have copy constructors (start with elements of existing collection)
Maps
Maps – Map interface
interface Map<K,V>
• Useful when you have to search, update or delete (more complex) elements
based on a (simpler) unique key
Maps – Map.Entry interface
interface Map<K,V> {
interface Entry<K,V> {…}
…
}
- V get(Object key) - return the value for the specified key (if found)
- boolean containsKey(Object key) - returns true if map contains given key
- boolean containsValue(Object value) - returns true if map contains (at least) a key
with given value
- V put(K key, V value) - add a map entry (or update existing one)
- void putAll(Map<? extends K, ? extends V> map) - insert all entries of specified
map into this map
- V remove(K key) - remove an entry from map (and returns it)
- void clear() - removes all map entries
• Characteristics:
○ holds key-value pairs (unique keys)
○ maintains no order
○ based on hashing (needs correct hashCode()/equals() for keys)
○ nulls: allows one null key, multiple null values
https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html
Maps – Example
m.remove(101);
for (Map.Entry e : m.entrySet()) {
System.out.println(e.getKey() + ": " + e.getValue());
}
//prints entries in random order
//-> 102: Catalin
//-> 100: Alex
Maps – LinkedHashMap
● Characteristics:
○ holds key-value pairs (unique keys)
○ maintains insertion order (unlike HashMap)
○ based on hashing (needs correct hashCode()/equals() for keys)
○ slightly slower than HashMap
○ nulls: allows one null key, multiple null values
https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html
Maps – Example
m.remove(101);
for (Map.Entry e : m.entrySet()) {
System.out.println(e.getKey() + ": " + e.getValue());
}
//prints entries in insertion order
//-> 100: Alex
//-> 102: Catalin
Maps – TreeMap
• Characteristics:
○ holds key-value pairs (unique keys)
○ maintains entries in sorted order (unlike HashMap)
■ key comparison: see Comparable or Comparator later
○ slower than HashMap, LinkedHashMap (due to sorting)
○ nulls: null keys not allowed, allows null values
https://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html
TreeMap– Example
● Characteristics:
○ holds key-value pairs (unique keys)
○ maintains no order
○ based on hashing (needs correct hashCode()/equals() for keys)
○ nulls: doesn’t allow null keys or values
○ synchronized (safe for multi-threaded access)
- Declaration: using ‘enum’ instead of class/interface, and giving the list of possible values:
enum Level {
HIGH, MEDIUM, LOW
}
Level(int levelCode) {
this.levelCode = levelCode;
}
import java.util.*;
class EnumMapExample {
//create an enum
enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
//print the entries of enum map, in the order of the constants in enum definition
for (Map.Entry m : map.entrySet()) { System.out.println(m.getKey() + " " + m.getValue()); }
}
}
Object.equals()
Object.equals()
- with equals() - a method defined in base class Object, so inherited by all objects:
You may override it in your classes, to make it test the logical equality of your objects!
Tip: IntelliJ IDEA can generate it: right click / Generate… / equals() and hashCode()
Object.equals() - Example
class Point {
private double x, y;
Point(int x, int y) { this.x = x; this.y = y; }
@Override
public boolean equals(Object obj) { //note the type: Object, not Point!
if (!(obj instanceof Point)) { return false; } //need to be of same type
Point that = (Point) obj; //may cast now from Object to specific type
return this.x == that.x && this.y == that.y; //check to have fields with same values
}
}
Usage rule:
- == should be used for primitives (+ enums)
- equals() should always be used for reference types
- including String
- including wrapper types (Long, Integer, Double…)
Notes:
- pay attention to keeping equals() up to date (on changes of class structure/fields)
- pay attention to inheritance scenarios - if a base class overrides equals, derived
classes most probably need to override it too! (parent impl is not good enough)
Object.hashCode()
Object.hashCode()
- hashCode() - method inherited from Object by all reference types; may be overridden...
- return value:
- should be an integer value representing the current instance of the class
- the returned value should be consistent with definition of equality for that class
Implementation details:
- HashSet / HashMap(for keys): elements organized in a series of “buckets”, elements of a bucket having the
same hashCode value (may be multiple ones if collisions occurred)
- when putting a new object in a HashSet/HashMap:
- its hashCode value is computed, and based on it the element is added to the right bucket
- when getting an element from the collection, or checking existence:
- the hashCode of the given object is computed, and then based on this value the right bucket is
checked (and after this equals() will also be called)
- if hashCode is wrong/missing/breaks contract: may make collection actions wrong/unpredictable!
(failing to correctly add new elements, like allowing duplicates, or failing to get existing elements…)
Object.hashCode() - Example