1 / 49

Disadvantages of ArrayLists

Disadvantages of ArrayLists. We've seen that using an ArrayList is one way to represent a sequence. But using an ArrayList here has disadvantages. Most importantly, when an element is added or removed, the elements to the right have to be moved as well.

uzuri
Download Presentation

Disadvantages of ArrayLists

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Disadvantages of ArrayLists • We've seen that using an ArrayListis one way to represent a sequence. • But using an ArrayList here has disadvantages. • Most importantly, when an element is added or removed, the elements to the right have to be moved as well. • List implementations needn’t have this drawback.

  2. Lists in general • To understand list implementations, it’s helpful to imagine an abstract notion of a list. • This sort of abstract thinking is helpful • we needn’t worry about implementation details

  3. List as an abstract data type Abstractly, the list data type has operations like • addToEnd(E) • add(index,E) • get(index) • remove(index) • set(index,E) • size() • isEmpty() • Here E is an element and index specifies a position in the list.

  4. Implementing the List ADT • It’s possible to implement such an abstract data type (ADT) List either in terms of • an array, or • a collection of nodes where each node has a link to its predecessor or successor

  5. Linked lists • In the linked case, suppose the place where an item is to be added or removed is known. • Then it can be added or removed by looking only at the nodes on either side of that place. • we skip the details (from Section 15.2), since they are covered in CS 46B. • This linked implementation is known as a linked list.

  6. Efficiency and linked lists • You needn't understand implementation details in order to use a list implementation. • But you should know the relative efficiency of each fundamental operation. • As summarized on p. 574 of the text • Here O(1) to means bounded time, and O(n) means time proportional to the list size.

  7. Issues in measuring efficiency • Strictly speaking, we should distinguish between worst-case time and average-case time. • But for the three operations on p. 574, these times are always the same. • With these three operations to start with, we can evaluate more complicated operations. • again we leave the details for CS 46B.

  8. Lists and linked lists in Java • In Java, the List ADT is represented by a List interface. • It has all of the list methods given above. • except that addToEnd(E) becomes add(E) • The ArrayList and LinkedList classes implement this interface. • The LinkedList class uses a linked implementation of lists. • so it has the advantages and disadvantages of this implementation.

  9. The LinkedList class • The LinkedList class is generic, like ArrayList. • It has several important methods of its own, that aren’t part of the interface. • Some of these methods would be very inefficient for ArrayLists.

  10. The LinkedList class • Methods particular to LinkedListinclude (cf. p. 557) • addFirst(E) • addLast(E) • getFirst() • getLast() • removeFirst() • removeLast()

  11. Iterators • Normally, linked lists are processed (traversed) by means of an iterator. • the intuition behind the use of iterators is the similar to that behind scanners • A new iterator can be created by sending an iterator message to a linked list. • An iterator accepts the messages next(), hasNext(), and remove() • Iterator is a generic interface, and so should be used with a class as parameter.

  12. Iterators and the LinkedList class • The LinkedList class actually supports a bidirectional iterator. • To get a bidirectional iterator for a linked list, send it the listIterator()message. • This iterator accepts all Iterator and ListIterator messages, notably • previous() • hasPrevious() • add(E) • remove()

  13. Behavior of Iterators • Iterators can be used for straightforward traversal, • as at the bottom of p. 558 of the text. • However, they can be used more generally. • For example, they can be used to remove elements that don’t satisfy a condition. • The enhanced for loop cannot do this • although it can be used for simple traversal of a list

  14. Intuitions for iterators • It’s most useful to think of iterators as pointing between consecutive elements of a list. • The next() and previous()methods both move the iterator past a list element, but in different directions. • The remove and set methods both operate on the last element that was returned by a call to next or previous.

  15. Stacks • Stack is an abstract data type with insertion and deletion operations that are inverses. • That is, the item deleted is the item most recently inserted. • This property is often called the LIFO (last in, first out) property. • The insertion operation is conventionally called push, while the deletion operation is conventionally called pop.

  16. Queues • Queue is an abstract data type with insertion and removal operations for which the item deleted is the item least recently inserted. • This property is often called the FIFO (first in, first out) property.

  17. Priority queues • PriorityQueue is an abstract data type with insertion and removal operations. • Here the item deleted is the item with the highest priority.

  18. Applications of stacks • Stacks are used to store postponed portions of method or function calls. • Note that the LIFO property is just what is wanted here – a called method should finish before its caller can finish.

  19. Applications of queues and priority queues • A priority queue is typically used to store events waiting for a resource such as a printer. • Here the event waiting the longest should perhaps not be the one that gets the next chance at the resource. • A queue is a special case of a priority queue where the longest waiting event should be the winner.

  20. Stacks in Java • Java has a (generic) Stack class, with push and pop methods. • It implements Iterable, Collection, and List.

  21. Queues in Java • Queues can be implemented in Java in terms of LinkedLists, by adding at one end and removing from another. • The sample implementation of p. 577 of the text adds at the end and removes from the beginning.

  22. Priority queues in Java • Java has a (generic) PriorityQueue class. • it implements Iterable and Collection • It uses compareTo (or compare) to compare priorities. • an earlier value in the ordering corresponds to a higher priority • Insertion (of an element of type E) and removal correspond to the messages • add(E) and remove() • There is also a 1-argument remove method.

  23. Sets and Maps • Two important abstract data types are represented by generic interfaces in java.util. • the Set interface represents sets • the Map interface represents functions • Two implementations are provided in each case.

  24. Sets in Java • A set does not allow repeated elements. • so insertion of an item already in a set should fail • It’s an unordered collection, so items can’t be added at a particular numbered position. • Set’s add method returns false if the item was already present; true otherwise. • The remove method returns true if the element was present, and false otherwise. • i.e., both methods return true if and only if the set was modified

  25. Iterating over sets • The iterator method returns an iterator that in general may iterate over the set in an arbitrary order. • You can still use iterators to remove -- but not add --at the position of the iterator. • There's no notion of iterating in reverse over sets.

  26. The Set interface • The Set interface extends Collection, and provides all of its methods. • In particular, it provides a boolean-valued contains method. • This method may take an Object as argument. • It uses this object's equals method to check for membership.

  27. The Map interface • The Map interface represents functions from a key type to a value type. • Map types need two parameters. • For example, a data structure that can be used to look up banks by their name could be of interface type • Map<String, Bank>

  28. Methods of the Map interface • Maps have a method containsKey that checks whether a given object exists as a key in the map. • A containsValue method behaves similarly. • The put method of Map takes a key and a value and adds the association between the two to the map. • if the key is already associated with another value, that association will be overwritten.

  29. Methods of the Map interface • The get method for Map takes a key and returns the associated value if there is one • and null otherwise • The remove method takes a key and removes it and any associated value from the map. • Both put and remove return the old associated value if there was one, • and null otherwise

  30. Maps and collections • Maps are not collections. • But from a map, you can get • the set of keys (use keySet) • the collection of values (use values) • the set of key-value pairs (use entrySet) • these pairs are of interface type Map.Entry. • The methods getKey and getValue return the key and value from an entry of this type. • The collection of values can’t be a set • it may contain repeated elements

  31. Implementing Set and Map • Both Set and Map have hashed implementations and tree implementations. • The implementing classes are HashSet, HashMap, TreeSet, and TreeMap. • The first two give fast insertion and lookup. • Iteration traverses a TreeSet in sorted order • if the element type implements Comparable, or • if it was constructed with a Comparator object. • The same applies to key sets of a TreeMap.

  32. Hashed implementations • In hashed implementations, the hashCode method must be defined appropriately for the element or key type. • This method takes an Object and returns an int. • For reasons given in Section 16.3 of the text, the function value should be equally likely to be any int.

  33. Defining hashCode • Normally an object’s hashCode value is defined in terms of the hashCode values of its instance variables. • Section 16.4 suggests how to do this. • You should make sure that equal elements get the same hash code value.

  34. Recursion • Recursion simply means that a function or method calls itself • perhaps indirectly • Recursion is your friend! • Specifically, it simplifies the important design technique of divide and conquer

  35. Divide-and-conquer problem solving • A divide-and-conquer algorithm works by • dividing the input into pieces • processing each piece • combining the processed pieces • If there are no pieces, the input is likely small • and processing it is likely simple • Pieces of the same type as the original input may be processed recursively • using the same method being defined • so no new method is needed!

  36. Binary search trees (BSTs) • Binary search tree (BST) is a data type used to implement TreeSets and TreeMaps. • A BST is empty, or has three pieces • a root data item, a left subtree (LST), and a right subtree (RST) • the LST contains all set members that precede the root in the ordering of the element type • the RST contains all members that follow the root • if the element type isn’t Comparable, an ordering must be specified by a Comparator object.

  37. Binary search tree operations • Simple divide-and-conquer algorithms exist for BST search, insertion, and deletion. • In the worst case, these algorithms take time proportional to the height of the tree • the largest distance from the root to a member • TreeSet and TreeMap operations modify the tree as needed to keep its height small • search is still simple • it’s helpful to understand the search algorithm when debugging TreeSets and TreeMaps

  38. Generic programming in Java • Generic programming is "the creation of programming constructs that can be used with many different types". • Two strategies are available for generic programming in Java. • The earliest was the use of inheritance. • A collection with no specified element type contains Objects as elements • so these elements can be objects of any class.

  39. Parametrization • We have now also seen a second strategy -- parametrization (with type variables), e.g. • ArrayList<String> • TreeMap<String, Integer> • To declare a generic class, a type variable is used for the parameter (cf. Syntax 17.1), e.g. • ArrayList<E> • TreeMap<K, V> • Recall that this variable must be instantiated with a class and not a nonclass type.

  40. Type variables • The big advantage of using type variables is type safety. • Errors that would be run-time errors with inheritance are compile-time errors in the parametrized case. • Code is also easier to read when desired element types are given explicitly.

  41. Using and defining generic classes • Using generic classes is not particularly difficult. • Defining generic classes, as opposed to generic methods, is fairly easy • the text's Pair class is a simple example • its LinkedList class is still straightforward • these examples are simple because they and their methods work with all types. • In general, use type variables as you would use parameters in a method definition.

  42. Constraining the type variable • In some cases, it makes sense to bind the type variable only to a limited range of types. • For example, you might want to limit a genericminimummethod toComparableclasses.

  43. Generic methods • The syntax for the simplest generic methods is only slightly more elaborate than in the nongeneric case. • A generic method that is to apply to all classes needs to have the type variable, inside angle brackets, before the return type. • Such a class is the ArrayUtil.printmethod of p. 729 of the text.

  44. How to constrain the type variable • If permissible types are to be constrained, the type variable has to be constrained as well. • To limit a generic minimum method to Comparable classes, make the type variable • <E extends Comparable> • rather than just <E>

  45. Limitations on generics in Java • It's worth knowing that Java erases type variables after compilation. • This helps explain some otherwise puzzling limitations on their use compilation • cf. Section 17.5 of the text • In particular, to interface with legacy code, raw types are needed • i.e., types without type variables

  46. More limitations • Another surprising limitation on genericity is described as Common Error 17.1, p 731. • Collection<S> is not a subclass of Collection<T> just because S is a subclass of T. • Dealing with this requires another way to constrain types • the wildcard types of Special Topic 17.1, p 731.

  47. Wildcards • Recall that the parameter type of the add method of the Collection<E> is just E. • so an object of any subclass of E may be added • But a Collection<E> parameter for addAll would not allow adding all of the elements of a collection of such instances. • the parameter is Collection<? extends E> • This parameter describes a collection whose elements may be of any subclass of E. • Eis a lower bound for the permitted types.

  48. Upper bounds • Upper bounds may be needed as well. • For example, consider the TreeSet<E> constructor that takes a Comparator object. • This constructor should be happy with a Comparator object that compares elements of any superclass of E. • The way to specify such a Comparator object is with the parameter type • Comparator<? super E>

  49. Unbounded wildcards • The use of a third type of wildcard, the unbounded wildcard, is illustrated by the removeAll method of Collection<E>. • here the argument can be any collection • its element type needn't be related to E • So the parameter type is Collection<?>. • Note that this method may throw a ClassCastException.

More Related