Stacks and queues. Understand the semantics of each.
Linked lists. Understand how they can be used to implement a stack or a queue, how to calculate the memory used by a linked list (using the 64-bit memory model) for N items in a queue, and how to show that queue and stack operations complete in constant time.
Resizing arrays. Understand how they can be used to implement a stack or a queue. Understand why the worst case memory usage and running times are different than the best case.
Amortized analysis. The idea is simpler that it might seem at first. If we say that X-operations take amortized f(M) Y-operations, this means that if we start with an empty data structure, the average cost for any sequence of M X-operations is f(M) Y-operations.
For example, for a resizing array stack, we say that push and pop operations take amortized constant time. This means that if we start with an empty stack, any sequence of pushes or pops take on average a constant number of array accesses per push or pop. In this example X is { push, pop }, Y is array accesses, and f(M) is just 1.
Generics. Understand that these provide the ability to parameterize data types. Understand why this approach is superior to other approaches (writing separate classes, using the Object type and doing runtime casting).
Compile time vs. run time errors. Understand why the former are preferred.
Iterators. Understand what it means for a class to implement the Iterable interface. Understand what a class must do to implement the java.util.Iterator interface. Understand how the foreach loop (enhanced for loop) works. Understand how to convert code using a foreach loop into equivalent longhand code.
Loitering. Understand how to avoid loitering in Java.