Description:

In this course, you'll explore how wildcards and type capture work, as well as how type erasure manifests itself in compiled bytecode. You'll start by examining how the wildcard operator, represented in syntax by the ? character, can be used in situations where you don't know up-front what type argument to specify for a particular type parameter. Next, you'll learn the three types of wildcard type parameters. Unbounded wildcards, where you know nothing at all about the type; upper bounded wildcards, which define type parameters that must inherit from a specific base class or interface; and finally lower bounded wildcards, which can be used to specify constraints in the other direction - namely that the type must be a super-class of a specified type. Next, you'll see that capture errors occur when Java is unable to infer the correct type to pencil in as the type argument for a given type parameter. Finally, you'll examine bytecode to see that whenever you create a class or method with a type parameter, Java creates just one single copy of such code, and pencils in a type parameter of java.lang.Object. It also adds various type checks to ensure that the code is used correctly. This is known as type erasure and forms the basis of the great performance of Java generics.

Target Audience:

Duration: 01:30

Description:

In this course, you'll learn how type parameters can be used to combine type safety and code re-use. You'll see how type parameters can be specified for either for classes or for individual methods of classes. You'll learn that while instantiating objects of those classes, or while invoking those methods, you can pencil in type arguments in place of those type parameters. You'll cover defining type parameters, using classes and methods with type parameters, as well as conventions and rules that apply to such parameters. You'll then explore the raw type that lies beneath any class or method with a type parameter. Java creates just one single copy of such code, and pencils in a type parameter of java.lang.Object. Java also adds various type checks to ensure that the code is used correctly - this is known as type erasure, and forms the basis of the great performance of Java generics. Finally, you'll move on to the use of constraints on type parameters and see how these are achieved using Bounded Type Parameters. Using bounds, it is possible to exercise fine-grained control over the ensure that the type argument - for instance to specify that it must be a numeric type.

Target Audience:

Duration: 01:34

Description:

In this course, you'll learn about two advanced built-in annotations, @SafeVarargs and @FunctionalInterface, before moving on to defining and using your own custom annotations. You'll begin with @SafeVarargs and see that it is purely indicative and does not imply any added compiler checks, so it is important to not be lulled into a false sense of security about methods that have been decorated with this annotation. Next, you'll move to another built-in annotation, @FunctionalInterface. This is used to decorate interfaces that contain exactly one abstract method. Finally, you'll learn how to define and use custom annotations. This will involve a detailed study of target and retention policies. The retention policy determines whether the annotation will be preserved only in source code, into compiled bytecode, or all the way to runtime. Finally, you'll see how the target policy governs what code elements - fields, methods, constructors, type parameters, and classes - can be decorated with an annotation.

Target Audience:

Duration: 01:31

Description:

In this course, you'll learn how annotations are defined and used in Java. You'll explore three popular built-in annotations, the @Override, @Deprecated, and @SuppressWarnings built-in annotations. Next, you'll examine how the @Override annotation is a valuable aid in detecting and fixing typos in the names of overridden methods, and crucially, helps to detect such issues at compile-time rather than at run-time. Then you'll explore the @Deprecated annotation and see how if you mark a class, method, or variable with the @Deprecated annotation, Java will issue an appropriate warning when you reference that element. You'll also learn about the @SuppressWarnings annotation, which does exactly what its name suggests, and for that reason ought to be used only with extreme caution, if at all. The @SuppressWarnings annotation allows the selective suppression of different types of warnings. You can also entirely eliminate all compiler warnings using @SuppressWarnings annotation with the "all" input argument, but this is quite dangerous and is an especially egregious programming practice.

Target Audience:

Duration: 01:24

Description:

In this course, you'll learn about how the Stream APIs provide ways to work with collections as streams of objects. You'll examine how operations such as filter, map, and foreach can be applied to collections by treating them as streams of data elements. Next, you'll learn how to use both anonymous inner class objects and lambda functions with streams, how to define predicates, and how to chain multiple stream operators together into a single pipeline that ends with a terminal operator returning a result. Next, you'll discover the differences between terminal and non-terminal operations, as well as between two different types of terminal operations - reduce and collect operations. Finally, you'll see how collect operations can be used to perform extremely complex operations on collections with minimal code.

Target Audience:

Duration: 01:12

Description:

In this course, you'll explore the Map interface and the different Map implementations available in Java. You'll learn how the Map is not a collection at all, but how it can be used to associate keys and values, and obtain collection objects that represent those keys and values. You'll see how no duplicates are allowed in keys, which effectively constitute a Set. You'll explore three implementations of the Map interface - HashMap, LinkedHashMap, and TreeMap. Next, you'll learn the finer points of how these map implementations check for duplicates. Finally, you'll examine the correct implementations of the .equals, .hashCode, and .compareTo methods in objects that are to be stored in maps.

Target Audience:

Duration: 00:49

Description:

In this course, you'll explore the Set interface and the different Set collections available in Java. You'll learn how the Java Set interface extends Collection, and how it is used to define unordered collections in which duplicates are not allowed. You'll discover common set operations such as union, difference, intersection, and equality, as well as how these are influenced heavily by the implementation of .equals and .hashCode in the objects contained within the set. You'll cover four implementations of the Set interface - HashSet, LinkedHashSet, EnumSet, and TreeSet. Finally, you'll learn the correct implementations of the .hashCode, .equals, and .compareTo methods of user-defined objects that are to be stored in Sets.

Target Audience:

Duration: 01:23

Description:

In this course, you'll explore the different types of lists available in the Java Collections framework and important algorithmic operations on lists. You'll examine the LinkedList, Vector, and ArrayList classes, and how they all implement the List, Collection, and Iterable Interfaces. You'll see how Vectors are similar to ArrayLists, but are thread-safe and so best-suited for concurrent access and multi-threaded applications. Next, you'll learn how LinkedLists are faster than ArrayLists for list addition and deletion operations, but slower for random access. You'll then explore how to create custom Comparator objects and implement the Comparable interface. Finally, you'll learn how to use different list algorithms, such as sorting, shuffling, copying, and you'll examine the semantics of list equality.

Target Audience:

Duration: 00:57

Description:

In this course, you'll focus on ArrayLists, which are a specific instantiation of the List interface. You'll learn about the List, Collection, and Iterable interfaces, and how the different list implementations such as ArrayList, Vector, and LinkedList, implement these interfaces. You'll then explore different iteration operations over lists and the ListIterator object. You'll see how to avoid ConcurrentModification exceptions, which can occur if code attempts to simultaneously iterate over a list and modify that list’s contents. Next, you'll learn how to perform range-view operations on lists. Finally, you'll examine the shallow-copy nature of range-views, and how, when you modify an element in a range-view, the elements in the underlying list are being modified as well.

Target Audience:

Duration: 01:08

Description:

In this course, you'll be introduced to Java collections and explore the details of how the Lists part of the Collections framework works. You'll start by learning how arrays are a rudimentary form of containers with some similarities to ArrayLists. Next, you'll explore the limitations of arrays, namely their fixed length and limited API support. You'll then move on to ArrayLists and explore how ArrayLists mitigate the weaknesses of arrays while still retaining their advantages. You'll learn how to instantiate an ArrayList and iterate over it using while loops, ordinary for-loops, and enhanced for-loops. Finally, you'll examine how to access and modify specific elements in an ArrayList.

Target Audience:

Duration: 01:09