Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Collections CS3250 Sources Slides by Professor Chuck Allison Core Java, by Cay S. Horstmann and Gary Cornell The Java Tutorial http://java.sun.com/docs/books/tutorial/index.html Outline java.util.Arrays Comparing objects Generics Collections java.util.Collections Maps java.util.Arrays Binary search equals fill sort asList toString Comparing objects Comparable – implemented in class of objects being compared public interface Comparable<T> { public int compareTo(T o); } "natural ordering" Comparator – implemented in class that is separate from the class of the objects being compared public interface Comparator<T> { public int compare(T o1, T o2); } Generics New in Java 1.5 Generic programming: write code that can be reused for objects of many different types --Core Java (7th ed., p. 707) Example The old way: List inventory = new LinkedList(); inventory.add("Brass Lantern"); . . . String item = (String) inventory.get(0); With generics: List<String> inventory = new LinkedList<String>(); inventory.add("Brass Lantern"); . . . String item = inventory.get(0); Advantages? The old way: List inventory = new LinkedList(); inventory.add("Brass Lantern"); . . . String item = (String) inventory.get(0); With generics: List<String> inventory = new LinkedList<String>(); inventory.add("Brass Lantern"); . . . String item = inventory.get(0); Advantages No casts needed List inventory = new LinkedList(); inventory.add("Brass Lantern"); . . . String item = (String) inventory.get(0); Compiler can check types List<String> inventory = new LinkedList<String>(); inventory.add("Brass Lantern"); . . . String item = inventory.get(0); Iterators public interface Iterator<E> { boolean hasNext(); E next(); void remove(); //optional } Used to traverse collections How can a method be optional when implementations are required for every method in the interface? Using iterators Should always call hasNext before calling next Otherwise could get NoSuchElement exception Iterator iter = c.iterator(); while (iter.hasNext()) { String element = (String) iter.next(); // Do something with element } Can use "for each" loop with any object that implements Iterable interface for (String element: c) { // Do something with element } Iterators: C++ vs. Java C++: iterators are modeled after array indexes (pointers) Can advance position independently of accessing element vector<int>::iterator iter; for (iter = v.begin(); iter != v.end(); iter++) { cout << *iter; // Do more stuff with *iter } Groucho Harpo Chico Java: like reading from a file Accessing elements and advancing position are inseparable Iterator is always "between" elements Iterator iter = c.iterator(); while (iter.hasNext()) { String element = iter.next(); // Do something with element } Groucho Harpo Chico Collections Interfaces Implementations List Set Queue Map Separating interfaces and implementations Specify implementation only when you construct the collection object: List<String> inventory = new LinkedList<String>(); inventory.add("Brass Lantern); Why is this a good approach? Interface Hierarchy Collection List Queue Map Set SortedSet SortedMap public interface Collection<E> extends Iterable<E> { // Basic operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optional boolean remove(Object element); //optional Iterator<E> iterator(); // Bulk operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); //optional boolean removeAll(Collection<?> c); //optional boolean retainAll(Collection<?> c); //optional void clear(); //optional // Array operations Object[] toArray(); <T> T[] toArray(T[] a); } public interface Collection<E> extends Iterable<E> { // Basic operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optional boolean remove(Object element); //optional Iterator<E> iterator(); // Bulk operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); //optional boolean removeAll(Collection<?> c); //optional boolean retainAll(Collection<?> c); //optional void clear(); //optional // Array operations Object[] toArray(); <T> T[] toArray(T[] a); } public interface Collection<E> extends Iterable<E> { // Basic operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optional boolean remove(Object element); //optional Iterator<E> iterator(); // Bulk operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); //optional boolean removeAll(Collection<?> c); //optional boolean retainAll(Collection<?> c); //optional void clear(); //optional // Array operations Object[] toArray(); <T> T[] toArray(T[] a); } For more information about generic wildcards (? and ? extends E) see http://docs.oracle.com/javase/tutorial/ extra/generics/subtype.html public interface Collection<E> extends Iterable<E> { // Basic operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optional boolean remove(Object element); //optional Iterator<E> iterator(); // Bulk operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); //optional boolean removeAll(Collection<?> c); //optional boolean retainAll(Collection<?> c); //optional void clear(); //optional // Array operations Object[] toArray(); <T> T[] toArray(T[] a); } public interface Collection<E> extends Iterable<E> { // Basic operations int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); //optional boolean remove(Object element); //optional Iterator<E> iterator(); // Bulk operations boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); //optional boolean removeAll(Collection<?> c); //optional boolean retainAll(Collection<?> c); //optional void clear(); //optional // Array operations Object[] toArray(); <T> T[] toArray(T[] a); } What do these optional methods have in common? Implementations Interface Implementations Hash table Set Resizable array HashSet List Tree TreeSet ArrayList Hash table + linked list LinkedHashSet LinkedList Queue Map Linked list LinkedList HashMap TreeMap LinkedHashMap List Ordered Collection Allows duplicate elements Provides positional access Permits arbitray range operations (sublists) System.out.println(list.get(2)); 0 1 2 3 pie ice cream cake pie List implementations LinkedList Quickly add and remove elements anywhere in the list Not well-suited for random access ("staggeringly inefficient") ArrayList Works well for random access Takes more time to add and remove elements (except at the end) List iterators public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); boolean hasPrevious(); Can move forward E previous(); int nextIndex(); int previousIndex(); void remove(); //optional void set(E e); //optional void add(E e); //optional } • Must call next (or previous) before calling remove. • remove deletes the element just accessed. or backward element = iter.next() System.out.println(element); iter.remove(); Groucho Harpo Chico Set Set interface contains only methods from Collection. Cannot contain duplicate elements. Two sets are equal if they contain the same elements. (Order is not important.) pie ice cream cake Set implementations HashSet – best performance, "chaotic ordering" LinkedList – substantially slower, orders elements based on values LinkedHashSet – orders elements based on order of insertion into the set, performance almost as good as HashSet Set operations s1.containsAll(s2) – Returns true if s2 is subset of s1 s1.addAll(s2) – Transforms s1 into union of s1 and s2 s1.retainAll(s2) – Transforms s1 into intersection of s1 and s2 s1.removeAll(s2) – Transforms s1 into the set difference of s1 and s2 Queue public interface Queue<E> extends Collection<E> { E element(); boolean offer(E e); E peek(); E poll(); E remove(); } "A collection for holding elements prior to processing" (Java Tutorial) Typically use FIFO ordering, but there are other orderings (e.g., priority queue) Ordering determines where an element will be added and which element will be deleted. Two forms of queue methods Throws exception Returns special value Insert add(e) offer(e) Remove remove() poll() Examine element() peek() offer is intended only for use on bounded (fixed size) queues. Returns false if element cannot be added. remove and poll remove and return the head of the queue, which is determined by the queue's ordering. poll and peek return null if the queue is empty java.util.Collections Sorting merge sort: fast (n log(n)) and stable Shuffling "Routine data manipulations" reverse, fill, copy, swap, addAll Searching – binarySearch Composition frequency, disjoint Maps Stores key/value pairs of objects Duplicate keys are not allowed Not part of the Collection hierarchy Returns keys as a Set view Returns values as a Collection public interface Map<K,V> { V put(K key, V value); V get(Object key); V remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty(); Basic Operations Bulk Operations void putAll(Map<? extends K, ? extends V> m); void clear(); public Set<K> keySet(); public Collection<V> values(); public Set<Map.Entry<K,V>> entrySet(); public interface Entry { K getKey(); V getValue(); V setValue(V value); } } Collection Views Interface for entrySet elements Word Frequency import java.util.*; public class Freq { public static void main(String[] args) { Map<String, Integer> m = new HashMap<String, Integer>(); // Initialize frequency table from command line for (String a : args) { Integer freq = m.get(a); m.put(a, (freq == null) ? 1 : freq + 1); } System.out.println(m.size() + " distinct words:"); System.out.println(m); } } java Freq if it is to be it is up to me to delegate 8 distinct words: {to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2} From the Java Tutorial: http://java.sun.com/docs/books/tutorial/collections/interfaces/map.html Map<String, Integer> m = new _______<String, Integer>(); HashMap java Freq if it is to be it is up to me to delegate 8 distinct words: {to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2} TreeMap java Freq if it is to be it is up to me to delegate 8 distinct words: {be=1, delegate=1, if=1, is=2, it=2, me=1, to=3, up=1} LinkedMap java Freq if it is to be it is up to me to delegate 8 distinct words: {if=1, it=2, is=2, to=3, be=1, up=1, me=1, delegate=1} Summary of implementations The Java Tutorial gives this list of "most commonly used" implementations: Set List Map Queue HashSet ArrayList HashMap LinkedList