(3-8-1) generic container: Generics - the basic concepts and principles

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/gaolh89/article/details/80954333

Generic content is divided into three parts to learn.
A introduces the basic concepts and principles of generics;.
II: focuses on the puzzling wildcard;
three: the introduction of generics some of the details and limitations.

Wherein the article is the first portion.


What is a generic?

Before we have always stressed the concept of data types, Java has eight basic types, you can define a class, the class is equivalent to custom data types, and can also have a combination of inheritance between classes. However, in Section 19, we introduced the interface, which refers, in fact, very often, we are not concerned with the type, but the ability for the programming interface and the ability to not only reuse code, you can also reduce coupling and improve flexibility sex.

The generic interface concept is further extended, "generic" literally means the broad range of types, classes, interfaces and methods can be applied to a very wide range of the code type, code and data types that they can no longer operate bound together, in the same sets of codes, may be used for a variety of data types, so that not only can reuse the code, reducing the coupling, can also improve the readability of the code and safety.

That might be more abstract, Next, we step by step illustrated by some examples. In Java, classes, interfaces, methods can be generic, let's look at a generic class.

(A) a simple generic class
we explain the basic concept of a generic class, the basic principles and benefits of generics through a simple example.

1. Basic Concepts

We direct look at the code:

public class Pair<T> {

    T first;
    T second;

    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public T getSecond() {
        return second;
    }
}

Pair is a generic class, the class distinction is reflected in common:
1) after more than a class name;
2) First and second type are T.

T What is it? T is the type parameter, that is, the generic type parameter, data type handling is not fixed, but can be passed as a parameter .

How to use this generic class type parameters and pass it to see the code?:

Pair<Integer> minmax = new Pair<Integer>(1,100);
Integer min = minmax.getFirst();
Integer max = minmax.getSecond();

Pair, here is the transfer of the actual type Integer parameters.

Pair class codes and the type of data processing is not bound, the particular type may be varied. The above is Integer, it can also be a String, such as:

Pair<String> kv = new Pair<String>("name","泛型");

Can have multiple types of parameters, Pair first and second classes may be of different types, among a plurality of types comma-delimited, Pair class defines the look improved:

public class Pair<U, V> {

    U first;
    V second;

    public Pair(U first, V second){
        this.first = first;
        this.second = second;
    }

    public U getFirst() {
        return first;
    }

    public V getSecond() {
        return second;
    }
}

It can be used like this:

Pair<String,Integer> pair = new Pair<String,Integer>("泛型",100);

I use the IDE is android Stduio (android IDE for programming, may be knocked JavaSe code) After the above code is knocked out, IDE carried out the following tips:

Write pictures described here

A simple translation of what is behind new Pair<String,Integer>("泛型",100);the data types can be used directly <> instead.

Yes it is:
<String,Integer>both appear in the statement variable, also appears in the back of the new, more complicated, from the beginning Java7 type of support behind the omitted parameters , can be used as follows:

Pair<String, Integer> pair = new Pair<>("泛型", 100);

2. The basic principle

Generic type argument in the end what is it? Why we must define the type parameters? Define the general category, the direct use Object not on line yet? For example, Pair class can be written as:

public class Pair {

    Object first;
    Object second;

    public Pair(Object first, Object second){
        this.first = first;
        this.second = second;
    }

    public Object getFirst() {
        return first;
    }

    public Object getSecond() {
        return second;
    }
}

Pair can use the code:

Pair minmax = new Pair(1,100);
Integer min = (Integer)minmax.getFirst();
Integer max = (Integer)minmax.getSecond();

Pair kv = new Pair("name","泛型");
String key = (String)kv.getFirst();
String value = (String)kv.getSecond();

This is possible. In fact, the principles of internal Java generics is the case.

We know, there is Java Java compiler and Java virtual machine, compiler converts Java source code for the .class file, the virtual machine to load and run the .class file. For a generic class, Java generic code compiler will convert ordinary non-generic code, like the above general Pair class code and the same code is used, the erase type parameter T, replaced Object, insert the necessary cast. When the actual implementation of the Java virtual machine, it is not known generic thing, we only know the general category and code.

Again, the Java generics are implemented by erasure, the type parameter T as the class definition is replaced with Object , the program is running, do not know the actual type of generic parameters, such as Pair, running only know Pair, do not know Integer, realize this is very important, it helps us understand a lot of restrictions Java generics.

Java Why should such a design it? Generics are supported only Java after 5, so the design is an option of last resort for compatibility.

3. Generic benefits

Since only the general category and Object is possible, and the generic eventually converted to general category, then why use generics it? Or, generics in the end what good is it?

There are two main benefits:

  • Better security
  • Better readability

    (Author note: The above two benefits are "Java programming logic," the title of my personal experience to appreciate the benefits of generics there are two:
    the use of generic packaging extract 1.
    2. forced many companies the background. Post is not responsible or poor service levels, different types of network requests data returned may be different. this time if you use specific data types or objects will report Json parsing error)

An important objective of language and programming is to eliminate as much as possible bug in the cradle, can eliminate the time to write the code, do not wait until the code is finished, when the program is running. Just use Object, when the code is wrong, the development environment and the compiler can not help us find the problem, look at the code:

Pair pair = new Pair("泛型",1);
Integer id = (Integer)pair.getFirst();
String name = (String)pair.getSecond();

See the problem yet? When writing code, not accidentally, get the type of error, however, when the code is compiled without any problems, but the runtime, the program throws a cast abnormal ClassCastException.

If you use generics, you can not make this mistake, if so write code:

Pair<String,Integer> pair = new Pair<>("泛型",1);
Integer id = pair.getFirst();
String name = pair.getSecond();

Development environment such as Eclipse, Android studio will prompt you to type error, even if there is no good development environment, compile time, Java compiler will prompt you. This is called type-safe, that is, through the use of generics, the development environment and compiler ensures that you will not be using the wrong type, set up a safety net and more for your program . The use of generics, also eliminates troublesome cast, coupled with explicit type information, readability will be better.

(B) containers

The most common use is as a generic class container class. The so-called container classes, simply put, is to hold and manage multiple classes of data. Is used to manage multiple data array, but the array has a number of limitations, for example, a fixed length, insert, delete operation efficiency is relatively low. Computer technology has a data structure called the curriculum devoted to various ways to manage data.

These data structures are implemented in Java, Java is mainly in a variety of containers, and even the introduction of Java generics is largely to better support Java container. Subsequent chapters we will discuss in detail the main Java container, in this section we first realize ourselves a very simple Java container, to explain some of the concepts of generics.

Let's implement a simple dynamic array container, called a dynamic array, the array is the length of a variable length, the underlying array, of course, is immutable, but we offer a class, the class user is concerned, if that is a length variable array, Java classes ArrayList container has a corresponding section we present a simplified version achieved. code show as below:

public class DynamicArray<E> {
    private static final int DEFAULT_CAPACITY = 10;

    private int size;
    private Object[] elementData;

    public DynamicArray() {
        this.elementData = new Object[DEFAULT_CAPACITY];
    }

    private void ensureCapacity(int minCapacity) {
        int oldCapacity = elementData.length;
        if(oldCapacity>=minCapacity){
            return;
        }
        int newCapacity = oldCapacity * 2;
        if (newCapacity < minCapacity)
            newCapacity = minCapacity;
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    public void add(E e) {
        ensureCapacity(size + 1);
        elementData[size++] = e;
    }

    public E get(int index) {
        return (E)elementData[index];
    }

    public int size() {
        return size;
    }

    public E set(int index, E element) {
        E oldValue = get(index);
        elementData[index] = element;
        return oldValue;
    }

}

DynamicArray is a dynamic array, and our internal code previously analyzed StringBuilder similar, according to the need to expand the array by ensureCapacity method. As a container class, which accommodates data type is passed over as a parameter, for example, storage Double type:

DynamicArray<Double> arr = new DynamicArray<>();
Random rnd = new Random();
int size = 1+rnd.nextInt(100);
for(int i=0; i<size; i++){
   arr.add(Math.random());
 }

Double d = arr.get(rnd.nextInt(size));

This is a simple type of container for a variety of data types, and type-safe. Later in this section and the following two will be extended to DynamicArray an example to explain the concept of generics.

Specific types can also be a generic class, for example, write:

DynamicArray<Pair<Integer,String>> arr = new DynamicArray<>()

arr represents a dynamic array, each element Pair<Integer,String>type.

(Iii) a generic method

In addition to generic classes, methods can be generic, and that a method is not generic, in which it is not a generic class does not matter.

We look at an example:

public static <T> int indexOf(T[] arr, T elm){
    for(int i=0; i<arr.length; i++){
        if(arr[i].equals(elm)){
            return i;
        }
    }
    return -1;
}

This method is a generic method, the type parameter is T, on the front of the return value, so it can call:

indexOf(new Integer[]{1,3,5}, 10);

The same can be invoked:

indexOf(new String[]{"hello","泛型","博客"}, "泛型");

indexOf represents an algorithm, looking for a certain element of a given array, this has nothing to do with the basic process of the algorithm specific data types, through a generic, it can be easily applied to a variety of data types, and the compiler type of security guarantee .

As with the generic class can have a plurality of types of parameters, a plurality of separated by commas, such as:

public static <U,V> Pair<U,V> makePair(U first, V second){
    Pair<U,V> pair = new Pair<>(first, second);
    return pair;
}

And generic classes, what the actual type generally do not need to specifically specify the type parameters when calling methods, such as call makePair:

makePair(1,"泛型");

U do not need to tell the compiler type is Integer, V type is String, Java compiler can automatically inferred.

(D) generic interface

The interface can also be generic, as we mentioned before Comparable and Comparator interfaces, see the source code using generics are seen written source code as follows:

public interface Comparable<T> {
    public int compareTo(T o);
}
public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
}

As before, T is the parameter type. When implementing the interface, you should specify a particular type, such as, for Integer class, the following source code:

public final class Integer extends Number implements Comparable<Integer>{
    public int compareTo(Integer anotherInteger) {
        return compare(this.value, anotherInteger.value);
    }
    //...
}

By implements Comparable<Integer>, Integer implements Comparable interface, specifies the parameters for the actual type Integer, Integer representing only be compared to an Integer object.

An example of the look Comparator, String class internal interface is implemented as a Comparator (Source below):

private static class CaseInsensitiveComparator
            implements Comparator<String>, java.io.Serializable {

         //....

        public int compare(String s1, String s2) {
          //....
        }
}

Here, specify the actual type parameter to a String.

Limit (five) type parameters

Before the presentation, whether it is a generic class, generic interface or generic method, on the type of parameters, we know little about, can only think of it as Object, but on a limited Java support this parameter community, that is, said parameter must be given upper bound type (or subtype), this is represented by defining extends keyword.

This upper bound can be a specific class or a specific interface, can also be other types of parameters, we look at their application one by one.

1. The upper limit of a specific type

For example, the above Pair class, a subclass can be defined NumberPair, two types of parameters must be defined to Number, the following code:

public class NumberPair<U extends Number, V extends Number> extends Pair<U, V> {

    public NumberPair(U first, V second) {
        super(first, second);
    }

    public double sum(){
        return getFirst().doubleValue()
                +getSecond().doubleValue();
    }
} 

After defining the type, the type of method to be used, for example, for NumberPair type, first and second variables can be treated as a Number, such as can define a sum () sum method, the code of the above has been posted .

You can then use this in place you need to call:

NumberPair<Integer, Double> pair = new NumberPair<>(10, 12.34);
double sum = pair.sum();

After defining the type, if you use the wrong type, the compiler will prompt.

After a specified boundary, when type erasure will not be converted to the Object, but will be converted to its boundary type, which is easy to understand.

2. The upper limit of an interface
3. The upper limit for other types of parameters

(F) Summary

Generic computer program is an important way of thinking, it will be data structures and algorithms and separated data types, such that the same set of data structures and algorithms, can be applied to various types of data, but also to guarantee type safety, improve readability. In Java, generics are widely used in a variety of containers, a deep understanding of the foundation is to understand the generic container.

This section describes the basic concept of generic, including generic class, generic method and generic interface, on the type of parameters, we introduced the various limits set defining a particular class, a particular port, or other types of parameters . The most common use generic class is a container class, we implemented a simple container class DynamicArray, to explain the concept of generics.

In Java, the generics are implemented by type erasure, it is the concept of Java compiler, Java virtual machine is running on a generic basic ignorant to understand this is very important, it helps us many understand the limitations of Java generics.

About generics, Java has the concept of a wildcard syntax is very puzzling and confusing, the next part, we are trying to analyze it be clear.

Guess you like

Origin blog.csdn.net/gaolh89/article/details/80954333