Friday, December 25, 2015

The Get and Put Principle

The Get and Put Principle

Previously we saw what subtyping and substitution is. Then we saw how to make wider calls using wildcards super and extends. Right now the confusion is when to use wildcard super or extends. It is too confusing to understand.

Let me give you some visual to understand it.

Yes, you might know this guy. How many packs does he has?

The correlation is that humans tends to learn or understand more if there is some visual information. How many packs he has? Let us see what that means.

PECS:
Producer Extends Consumer Super

Get Principle: when you want to get values out of Collection use super wildcard.
Put Principle: when you want to put values into the Collection use extends wildcard.

Now remember packs or PECS. This will come in handy while understanding the generics.

If you remember we saw this concept in previous post while understanding copy() method.

public static <T> void
      copy(List<? super T> dest, List<? extends T> src)

This method gets(? extends T) the value out from source list and puts(? super T) into the destination list.

While we discussed the Summation of Wrapper types we saw method signature like this
public static double summation(List<? extends Number> list)

For this we will be removing or getting values from list and processing those elements. For the summation method we can pass several different lists like

      List<Integer> intList = Arrays.asList(4, 5, 6, 4, 3);
      List<Long> longList = Arrays.asList(4l, 5l, 6l, 4l, 3l);
      List<Double> doubleList = Arrays.asList(4.5d, 6.4d, 3.00d);
      List<Number> numberList = Arrays.asList(7, 63.89d, 2.0f, 9l);

                The first three calls won’t be legal if extends was not used.

Now, whenever  you put values in structure use super wildcard. Below method sets new value for first n values.
public static <T> void
fill(List<? super Integer> list, int n) {
            for (int i = 0; i < n; i++) {
                  list.add(i);
            }
      }
                All below calls are legal because we have used super wildcard.

List<Integer> intList = new ArrayList<Integer>();
fill(intList, 3); intList.add(20);
assert intList.toString().equals("[0, 1, 2, 20]");

List<Number> numberList = new ArrayList<Number>();
fill(numberList, 3);
numberList.add(3.14d);
assert numberList.toString().equals("[0, 1, 2, 3.14]");

List<Object> objectList = new ArrayList<Object>();
      fill(objectList, 3);
      objectList.add("String here");
assert objectList.toString().equals("[0, 1, 2, String here]");

Now, if you want to do both get and put then you CANNOT use wildcards. You can use below syntax.

            public static <T> double sumFill(List<Number> list, int n){
           fill(list, n);
           return summation(list);
     }

Below code is legal to use.
List<Number> numberList = new ArrayList<Number>();
      double sum = sumFill(numberList, 10);
      System.out.println("Fill is " + numberList);
      System.out.println("Summation is " + sum);

             Output:
             Fill is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 Summation is 45.0

That's all on get and put principle. We will discuss it further in next post.

Sunday, December 20, 2015

Wildcards with super

Wildcards with super

In previous post we saw what subtyping and substitution is. We also saw what is wildcards with extends i.e. ? extends T.

This post is for wildcards with super i.e ? super T. In wildcard ? extends T you cannot insert value into the Collection because you will be inserting some other subtype of T. We can extend T class and write any other class which might break the functionality.

With wildcard ? super T we know what we have i.e. any type that is super class or supertype of T.

Let us use both the wildcards in one method and discuss restrictiveness and wider range of calls.

      public static <T> void
      copy(List<? super T> dest, List<? extends T> src) {
            int i = 0;
            for (T t : src) {
                  dest.set(i, t);
                  i++;
            }
      }

? super T      : means we will be able to insert elements into it.
? extends T  : means we will be able to remove elements from it.

For above copy(..) method there can be 4 different calls

Call 1: copy(List<T> dest, List< T> src)
Call 2: copy(List<T> dest, List<? extends T> src)
Call 3: copy(List<? super T> dest, List< T> src)
Call 4: copy(List<? super T> dest, List<? extends T> src)

Let us take 2 diffferent Lists as below for exaplanation of above different method signatures.
List<Object> objectList = Arrays.asList(1, 2, "meme");
List<Integer> intList = Arrays.asList(1, 2, 3);
copy(objectList, intList) 

For Call 1
copy(List<T> dest, List<T> src)
Too restrictive wildcards. The type should be same for source and destination. For two different types of Lists i.e. List<Object> and List<Integer> this call for copy will not work.

For Call 2
copy(List<T> dest, List<? extends T> src)
Somewhat restrictive wildcards. At runtime this will be interpreted as
(List<Object> dest, List<? extends Object> src)
First parameter i.e. List<Object> is too generic right. We can make this better.

For call 3
copy(List<? super T> dest, List<T> src)
Somewhat restrictive wildcards. At runtime this will be interpreted as
List<? super Integer> dest, List<Integer> src

Second parameter List<Integer> is too generic right. We can make this better.

For call 4
copy(List<? super T> dest, List<? extends T> src)
This wildcards permits the widest range for this usecase. At runtime it will be
(List<? super Integer> dest, List<? extends Integer> src)
dest i.e. destination is ? super Integer and we have List<Object> for it.
src i.e. source is ? extends Integer and we have List<Integer> for it.


So we not know that wildcards provide us the best way for the wide range of calls.

But there is still one thing. We say <? extends T> and <? super T> but when to use them? Isn’t it confusing? Well don’t you worry. There is very simple way to understand it. In next post we will see that.

Saturday, December 19, 2015

WildCards with extends

WildCards with extends

In previous post we saw what subtyping and substitution is.

We were also stuck at a problem where we want to insert elements of List<Integer>, List<Float> and List<Double> into List<Number>.

We came up with two different solutions.
One was to manually copy all the elements into the List<Number>. This solution works but it is too much of work.
      List<Number> numbers = new ArrayList<Number>();
      List<Integer> integers = Arrays.asList(1, 2, 3);
      List<Float> floats = Arrays.asList(4.3f, 2.65f);
      List<Double> doubles = Arrays.asList(4.00d, 53.27d);
           
      for(Integer i: integers){
            numbers.add(i);
}
      for(Float f: floats){
            numbers.add(f);
      }
      for(Double d: doubles){
            numbers.add(d);
      }

      assert numbers.toString().equals("[1, 2, 3, 4.3, 2.65, 4.0, 53.27]");

Then we thought of a different way which would not work. It gives compile time error “The method add(Number) in the type List<Number> is not applicable for the arguments (E)”.

public static <E> void addAll(List<Number> numbers, List<E> list){
            for (E e : list) {
                  numbers.add(e);
            }
      }

Now let see how the method addAll(..) of Collection<E> interface looks like.

public interface Collection<E> extends Iterable<E> {
boolean addAll(Collection<? extends E> c);
//other Collection<E> interface methods
}

Look at the signature of addAll method Collection<? extends E>. What is this thing?

? extends E means that sometype extends type E. And we have our solution. And how is that?

Well we want to insert elements of List<Integer>, List<Float> and List<Double> to List<Number>. List<E> is subtype of Collection<E> and Integer, Float and Double is subtype of Number.

Here E element is Number class. So it effectively means Collection<? extends Number>.
Integer extends Number and so does Float and Double. Hence we can directly use addAll(..) method of Collection<E> interface.

addAll(Collection<? extends E> c) has its concrete implementation in ArrayList class. So our solution to problem is:
      List<Number> numbers = new ArrayList<Number>();
      List<Integer> integers = Arrays.asList(1, 2, 3);
      List<Float> floats = Arrays.asList(4.3f, 2.65f);
      List<Double> doubles = Arrays.asList(4.00d, 53.27d);
           
      numbers.addAll(integers);
      numbers.addAll(floats);
      numbers.addAll(doubles);
      assert numbers.toString().equals("[1, 2, 3, 4.3, 2.65, 4.0, 53.27]");

Excellent Solution right. So this was the use of wildcard <? extends E>.

Let us try to extend this concept.
In previous post we saw below won’t work. It will give compiler time error Type mismatch: cannot convert from List<Integer> to List<Number>”

List<Integer> integers = Arrays.asList(4, 33, 2, 7);
      List<Number> numbers = integers; //compile time error
     
Let us use wildcard for this.

      List<? extends Number> numbers = integers; ;//works like a charm.
                numbers.add(3); //compile time error.

The above line of code works well. But if you try to add element into it then it will fail. The error is The method add(int, capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (int)

What does this mean? This means that you will be inserting some other subtype of Number. We can extend Number class and write any other class which might break the functionality.

So you can only get elements out if using <? extends E> wildcard. If you want to put elements into Collection the use <? super E>. We will see this new wildcard type in next post.


Subtyping and Substitution

Subtyping and Substitution

In previous posts we saw few different things. First was What JavaGenerics is and why were they needed. Next we discussed about the cast-iron guarantee. Cast iron guarantee means that the implicit cast added by generics will never fail. In third post we saw how to write Generic methods and Varargs. We will discuss about the generics methods in more detail in upcoming posts.

In this post we will see what the Subtyping and Substitution principle is.

What is Subtyping?
Subtyping is one of the most important feature of Object-Oriented Programming. In Java a type is Subtype of some other type if they are related by extends or implements.

For example:

ArrayList<E>
is subtype of
List<E>
List<E>
is subtype of
Collection<E>
StringBuilder
is subtype of
AbstractStringBuilder
StringBuffer
is subtype of
AbstractStringBuilder
Integer
is subtype of
Number
Long
is subtype of
Number
Double
is subtype of
Number

Above are some examples of subtypes. Now one of important thing is that subtyping is transitive. Meaning if one type extends second type, second type extends third type then first type extends third type. In Collections framework ArrayList<E> class is subtype of List<E> and List<E> is subtype of Collection<E> so transitively we can say that ArrayList<E> is subtype of Collection<E>.


Now let us see What Substitution Principle is?
                Substitution means that we can assign the subtype value to the variable.
                Example 1:
                List<String> list = new ArrayList<String>();
      
                We are assigning ArrayList(subtype of List) to List.

                Example 2:
                Number[] numbers = { 1, 2, 5.3f, 5.127623d };
               
   Above the array of class Number. This class is extended by various classes such as     Integer, Float, Double, Long, etc. In the array there are values of different types.

 Number[0] is 1 of type Integer.
 Number[1] is 2 of type Integer.
 Number[2] is 5.3f of type Float.
 Number[3] is 5.127623d of type Double.

              Remember all the above are Wrapper class of primitive types int, float, double.

 Let us venture a bit from here.

  
The List interface has add method.

public interface List<E> extends Collection<E> {

boolean add(E e);
//other List<E> methods
}

So let us first declare the List<Number> and add some elements to it.
      List<Number> numbers = new ArrayList<Number>();
      numbers.add(2);
      numbers.add(3.14d);
      numbers.add(22.7f);
      assert numbers.toString().equals("[2, 3.14, 22.7]"); //works fine.

The above piece of code will work fine. We inserted Integer at index 0, Double at index 1, Float at position 2. Thanks to Autoboxing that we didn’t had to write something like this numbers.add(new Integer(2));. Now we just inserted few of subtypes of Number class and we used substitution principle.

But then if Integer is subclass of Number class then below should be true, right?

      List<Integer> integers = Arrays.asList(4,33,2,7);
      List<Number> numbers = integers;

No it is not right. It results in compile time error “Type mismatch: cannot convert from List<Integer> to List<Number>”. So one thing is clear that even Integer extends Number or Integer is subtype of Number, List<Integer> is not subtype of List<Number>.

Why it is like this? One important thing to note is List<Integer> is subtype of Collection<Integer>.

We saw in Number[] example by assigning Integer[] to Number[] and it worked happily. The treatment of arrays and Collection differs and this is a good thing. Why? We will see that later as we need to know some important concepts first.

Let’s say we have List<Integer>, List<Double> & List<Float> and we need to insert all elements in List<Number>.

We do something bad like this which will work.
      List<Number> numbers = new ArrayList<Number>();
      List<Integer> integers = Arrays.asList(1, 2, 3);
      List<Float> floats = Arrays.asList(4.3f, 2.65f);
      List<Double> doubles = Arrays.asList(4.00d, 53.27d);
           
      for(Integer i: integers){
            numbers.add(i);
}
      for(Float f: floats){
            numbers.add(f);
      }
      for(Double d: doubles){
            numbers.add(d);
      }

      assert numbers.toString().equals("[1, 2, 3, 4.3, 2.65, 4.0, 53.27]");


You would think that this is horrible way to code there has to be a better way. One wrong way we can come up with is you would extract a method of generic type which will not work.
public static <E> void addAll(List<Number> numbers, List<E> list){
            for (E e : list) {
                  numbers.add(e);
            }
      }

It gives compile time error “The method add(Number) in the type List<Number> is not applicable for the arguments (E)”.

And now we are stuck. First we thought that subtyping is good but now it is becoming horrible. Thankfully there is a solution to this problem. And the solution is related to subtyping called WILDCARDS. It is used extensively in Java and it has its own powers. In next post we will see wildcards how and when to use them.

Wednesday, December 9, 2015

Java ArrayList Class Quick Reference Guide

Java ArrayList<E> Class Quick Reference Guide

What is ArrayList<E> class?

ArrayList<E> class implements List<E> interface. ArrayList<E> class is an ordered collection or a collection that maintains an insertion order. Hence we can have control of the values based on index. ArrayList<E> uses array data structure to store elements.



Constructor

Description
public ArrayList()
This constructor creates an empty list with capacity of 10.

public ArrayList(int initialCapacity)
This constructor is used to create an empty list with specified initial capacity.

public 
ArrayList(Collection<? extends E> c)
This constructor is used to construct an ArrayList from the Collection. Collection does not guarantee the order in which elements will be returned.


Method
Description


int size()
Returns the size of the ArrayList.

boolean isEmpty()
Returns true if the size (of ArrayList) == 0
Else it returns false.

boolean contains(Object o)
Returns true if this ArrayList contains Object o such that
o == null ? e == null : o.equals(e)

Iterator<E> iterator()
Returns the iterator that will step over or iterate over the elements of ArrayList. It does guarantee the proper sequence.

Object[] toArray()
Returns the Object[] of the elements of Collection. This method returns the deep copy meaning all the elements of ArrayList are copied to Object[] and Object[] does not maintain any references to Collection.

<T> T[] toArray(T[] a)
Returns an array containing elements of ArrayList. The returned array is of type runtime type of array to contain elements.


boolean add(E e)
This method adds the element to the end of the ArrayList or this method append the element to the ArrayList.

boolean remove(Object o)
This method removes the first occurrence of Object o from the ArrayList. This method removes single element from ArrayList such that
o == null ? e == null : o.equals(e). Returns true if the element is removed from ArrayList else returns false.

boolean
containsAll(Collection<?> c)
This method returns true if this ArrayList contains all the elements specified in Collection<?> c passed as parameter.

boolean
addAll(Collection<? extends E> c)
addAll method is used to add all or append all the elements of Collection<? extends E> c to this ArrayList. It returns true if specified List is changed because of this call.

boolean
addAll(int index, 
           Collection<? extends E>) c
This overloaded version of addAll method is used to insert the Collection into the specified index of this ArrayList.

boolean
removeAll(Collection<?> c)
removeAll method is used to remove all the elements from ArrayList that are specified in Collection<?> c. Returns true if this ArrayList is changed because of this call.

default void
replaceAll(UnaryOperator<E> operator)
replaceAll method replaces each element in ArrayList with the result of applying operator. This method is added in Java 8.

boolean
retainAll(Collection<?> c)
retainAll method retains or holds elements that are in this List specified by Collection<?> c in parameter. Returns true if the Collection is changed as a result of this call.

default void
sort(Comparator<? super E>) c
Sorts the ArrayList according to the order provided by the Comparator.


void clear()
clear method is used to clear the ArrayList or remove all the elements from this Collection.

boolean equals(Object o)
equals method compares this ArrayList with Object o specified in parameter for equality. Returns true if Object o is equal to this Collection.

int hashCode()
Returns the hash code for this ArrayList. Remember arrList1.equals(arrList2) implies that
arrList1.hashCode() == arrList2.hashCode().

E get(int index)
get method returns the element which is at that index.

E set(int index, E element)
set method is used to set the element E at the index specified in parameter.

void add(int index, E element)
This overloaded version of add method is used to insert the element E at index provided in parameter.

E remove(int index)
This method is used to remove element from the index.

int indexOf(Object o)
indexOf method is used to search for the required Object in the ArrayList. If found it returns the index of the Object. Search is done as
o == null ? e == null : o.equals(e). This method scans the ArrayList from beginning. If element is not found it returns -1.

int lastIndexOf(Object o)
Returns the last index of the Object o in the List. lastIndexOf method works same as indexOf but it searches for the Object from end of the List.

ListIterator<E> listIterator()
It returns a list iterator that provides you several operations like hasNext(), next(), hasPrevious(), previous(), nextIndex(), previousIndex(), remove(), set(E) and add(E). We can traverse bi-directional through this iterator.

ListIterator<E> listIterator(int index)
This method returns the ListIterator beginning from the index specified in the parameter.

List<E>
subList(int fromIndex, int toIndex)
subList method returns a sub list from fromIndex and toIndex exclusive.

void trimToSize()
This method is used to trim the capacity of this ArrayList to the list’s current size. This method can be used to reduce the storage required by ArrayList.

void ensureCapacity(int minCapacity)
ensureCapacity method is used to make sure that ArrayList can hold atleast number of elements specified as Minimum capacity

Object clone()
Clone method is used to return the clone of this ArrayList instance. The clone copy is shallow copy means the elements itself are not copied.

void
forEach(Consumer<? super E> action)
This method accepts the instance of Consumer interface. It performs a given action on each element of the ArrayList.

boolean
removeIf(Predicate<? super E> filter)

This method accepts instance of Predicate interface. It removes all the elements of this ArrayList that satisfy the given condition in Predicate.

Spliterator<E> spliterator()
Creates a spliterator over the elements in this Collection.

default
void sort(Comparator<? super E> c)
This method accepts the instance of Comparator interface. It sorts the ArrayList.

                                                                     

Ads Inside Post