Generics and Collections Flashcards
Declaring a class with generics
public class Crate { private T contents; public T emptyCrate() { return contents; } }
T can be used throughout the class and when the class is instantiated then the T’s become the class object type you specify
How to call a method that uses generics
Two ways
methodName(“a string”) //Detects automatically
ClassName.methodName(“a string”) //Explicitly
Raw Collections
Collections that do not use generics
What goes wrong in this code?
class Dragon {} class Unicorn { } public class LegacyDragons { public static void main(String[] args) { List unicorns = new ArrayList(); unicorns.add(new Unicorn()); printDragons(unicorns); } private static void printDragons(List dragons) { for (Dragon dragon: dragons) { System.out.println(dragon); } } }
The List unicorns doesn’t use generics, so when it adds a Unicorn, that’s fine but it sees it as an Object. So basically, it compiles because that’s technically legal to pass to printDragons, but the for loop then tries top cast the Unicorn element to Dragon, which causes a ClassCastException.
It will also give you a compiler warning, but still compile
What goes wrong with this code?
public class LegacyAutoboxing { public static void main(String[] args) { java.util.List numbers = new java.util.ArrayList(); numbers.add(5); int result = numbers.get(0); } }
When the number 5 is added to the List, it is added just as an Object since there isn’t a type specified by generics. So when you try to store that value in an int, it can’t be unboxed how an Integer usually would be able to.
Unbounded Wildcard
Specified with a ?
public static void printList(List> list)
This indicates that the List could be of anything.
The difference here between just specifying List without generics, is that when we don’t use generics it will treat the list passed in as List, which could allow the wrong types of elements to be added.
Upper-bounded Wildcard
Specified with a ? extends className
public static void printList(List extends Number> list)
This means the List can be of Number itself, or any class that is a subclass of Number
Lower-bounded Wildcards
Specified with a ? super className
public static void printList(List super String> list)
This means that the List can be of String itself, or any class that is a superclass of String
Mutability of Lists declared with wildcards
With unbounded or upper-bounded, the Lists are immutable, meaning you cannot add anything to them.
With lower-bounded, you can add anything that is the lower-bound specified or a subclass of that lower-bound
Collection
A group of objects contained in a single object
List
An ordered collection of elements that allows duplicate entries. Elements in a list can be accessed by an int index.
Set
A collection that does not allow duplicate entries
Queue
A collection that orders its elements in a specific order for processing. A typical queue processes its elements in a first-in, first-out order, but other orderings
are possible.
Map
A collection that maps keys to values, with no duplicate keys allowed. The elements in a map are key/value pairs.
add()
Inserts a new element into the Collection and returns whether it was
successful.
boolean add(E element)
remove()
Removes a single matching value in the Collection and returns whether it was successful.
boolean remove(Object object)
Removes the element at the specified index
void remove(int index)
clear()
Discards all elements in the Collection
void clear()
contains()
Checks if a certain value is in the Collection
boolean contains(Object object)
Benefit of ArrayList
You can look up any element in constant time.
Adding or removing an element is slower than accessing an element.
This makes an ArrayList a good choice when you are reading more often than writing
Benefit of LinkedList
You can access, add, and remove from the
beginning and end of the list in constant time.
The tradeoff is that dealing with an arbitrary
index (not necessarily first or last) takes linear time.
This makes a LinkedList a good choice when you’ll be using it as Queue.
What should you use instead of Stack?
ArrayDeque
List method used to add an element at a specific index
void add(int index, E element)
List method to grab a specific element in the list
E get(int index)
List method to replace the element at a specific index
E set(int index, E e)
List method to find the position in the List that matches a specified element
//For first match int indexOf(Object o)
//For the last match int lastIndexOf(Object o)
Both return -1 if there is no match found
Benefit of HashSet
Adding elements and checking if an element is in the set are done in constant time
The tradeoff is that you lose the order in which you added the elements, but this is the case with sets usually, so if you care that much then don’t use a set ya dummy.
Benefit of TreeSet
The set is always in sorted order.
The tradeoff is that adding and checking if an element is present are done in O(logn)
TreeSet method
E lower(E e)
Returns the greatest element in the set that is