16 February 2022

Type Bounds and Wildcards

Suppose you want to be able to assume a type parameter is a subtype of a given type. How do you do this?


<T extends Comparable<T>>

restricts the type specified as being a subtype of Comaprable, which means it implements the Comparable<T> interface. Here is a class with a static method that takes advantage of this.


import java.util.List;
import java.util.ArrayList;
public class Order
{
    public static <T extends Comparable<T>> boolean isInOrder(List<T> list)
    {
        int n = list.size();
        for(int k = 0; k < n - 1; k++)
        {
            if( list.get(k).compareTo(list.get(k+1)) > 0)
            {
                return false;
            }
        }
        return true;
    }
    public static void main(String[] args)
    {
        List<String> st = new ArrayList<>();
        st.addAll(List.of("a", "c", "b"));
        //yields a false
        System.out.println("isInOrder(st) = " + isInOrder(st));
        st.clear();
        //yields a true
        st.addAll(List.of("a", "b", "c"));
        System.out.println("isInOrder(st) = " + isInOrder(st));
    }
}

Function-Like Objects and Streams

forEach This is a default method of the Iteratable<T> interface.

. Because our stacks implement this interface, they automatically get this method.

What is Consumer< ? super Tt? Dang. Type bounds again. Let's break it down. Firstly, Consumer<T> is a generic functional interface. It's one specified method is void accept(T t)

So it peforms some action on an object of type T that does not have any return value.