generic paradigm
Introduction of generics
When we write the following code, we find that there are some small problems, because we store the data of String type and Integer type at the same time, but we convert it into String type, and an error will be reported when running. On the contrary, when the array stores data, it can only store one type of data, which is also an advantage of the array, Is there such an approach in the collection to specify the data type of the element when it is created, so that we can directly report errors during compilation when inserting data or downward transformation. In the collection, this design is called generics.
public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("hello"); list.add("world"); list.add(100); Iterator iterator = list.iterator(); while (iterator.hasNext()){ Object next = iterator.next(); String next1 = (String) next; System.out.println(next1); } }
Introduction to generics
Generics: a type that defers type - specific work until the creation of an object or the invocation of a method. Parameterized type, which is passed as a parameter
Format:
< data type >
Note: the data type here can only be reference type
Benefits of generics
Advance the run-time problem to compile time
Casts are avoided
Optimize the program and eliminate the yellow warning line
Examples and applications of generics
Examples of generic storage of String type data
public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); list.add("hello"); list.add("world"); // list.add(100); Directly reported an error Iterator<String> iterator = list.iterator(); while (iterator.hasNext()){ String r = iterator.next(); System.out.println(r); } } } //hello //world
Generic class
Generic classes: define generics on classes
This only represents a parameter type. The parameter type is a variable. Since it is a variable, it meets our variable naming rules and can be any name that conforms to the identifier
public class GenericTool<T> { private T obj; public T getObj(){ return obj; } public void setObj(T obj){ this.obj = obj; } } public static void main(String[] args) { GenericTool genericTool = new GenericTool(); genericTool.setObj(new String("zhangsan")); Object obj = genericTool.getObj(); String obj1 = (String) obj; System.out.println(obj1); genericTool.setObj(new String("lisi")); Object obj2 = genericTool.getObj(); String obj21 = (String) obj2; System.out.println(obj21); GenericTool<String> stringGenericTool = new GenericTool<String>(); stringGenericTool.setObj("wangwu"); String obj3 = stringGenericTool.getObj(); System.out.println(obj3); } } //zhangsan //lisi //wangwu
Enhanced for loop
What is an enhanced for loop
JDK1. After 5, some new contents appeared:
Automatic packing and unpacking
generic paradigm
Enhanced for loop
Enhanced for loop: it is a kind of for loop, which simplifies the traversal of arrays and Collection collections
For (element data type variable: array or Collection){
Just use a variable, which is an element
}
Benefits: simplifies traversal of arrays and Collection collections
Enhanced for loop example
Note: enhanced for can be used multiple times. The iterator can only be used once, and the life cycle ends (because the iterator only traverses once, and the pointer ends at the end)
public static void main(String[] args) { //Define an array int []arr = new int[]{1,2,3,4,5,6}; for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); } //Enhanced for loop improvement //If Java can be replaced with enhanced for loop, use enhanced for loop to reduce the yellow warning line for(int i:arr){ System.out.println(i); } //Define a collection object ArrayList<String> strings = new ArrayList<>(); strings.add("hello"); strings.add("world"); strings.add("java"); for(String s:strings){ System.out.println(s); } //This step is only an improvement and judgment compared with the previous step List<String> list1 = null; if(!(list1 == null)){ for (String s1:list1) { System.out.println(s1); } } //In fact, the enhanced for loop is used to replace the iterator //How to verify that it is used to replace iterators //I encountered a concurrent modification exception while looking at the iterator //ConcurrentModificationException for(String s:strings){ if("java".equals(s)){ strings.add("spark"); } } }
Static import
What is static import
import static package name... Class name Method name; (can be imported directly to the level of the method)
be careful
Method must be static
If there are other methods in this class with the same name as the statically imported methods, the methods of this class are preferred
If some methods have the same name when importing, what should I do? It's best to add a prefix. It's required. This doesn't make much sense. You can understand it
public static void main(String[] args) { System.out.println(Math.abs(-100)); System.out.println(Math.pow(2,3)); System.out.println(Math.max(100,200)); //Is there any way to write the method name directly without writing the class name //Import at the beginning: import static Java lang.Math. abs; System.out.println(abs(-900)); FunDemo.show("hello"); com.bigdata.shujia19.FunDemo.show(12.34); } } //100 //8.0 //200 //900 //hello //12.34
Variable parameters
What are variable parameters and the points for attention of variable parameters
- Variable parameters: when defining a method, the method can have multiple parameters
- Modifier return value type method name (data type... Variable name) {}
- Note: the variable here is actually an array of multiple parameters and gives it a name. This variable is the array name
Example of variable parameter code:
public static void main(String[] args) { //Sum of two data int a = 10; int b = 20; int result1 = sum(a,b); System.out.println(result1); //Sum of three data int c = 30; int result2 = sum1(a,b,c); System.out.println(result2); //Write a summation requirement, but I don't know how many data requirements and, but the requirements are //When you call a method, you must find out //What to do? In order to solve this problem, Java provides a technology: variable parameters int res4 = sum(a,b,c,40,50,20,304,70); System.out.println(res4); } public static int sum(int a,int b){ return a+b; } public static int sum1(int a,int b,int c){ return a+b+c; } public static int sum(int...arr){ int sum = 0; for(int i:arr){ sum += i; } return sum; } } //30 //60 //544
Set interface
Introduction of Set interface
There are List and Set interfaces under the Collection interface
List elements are in order (the storage order is consistent with the extraction order and can be repeated)
Set is out of order (the storage order and retrieval order are inconsistent, and the elements are not unique)
HashSet: the bottom layer is the hash table. The thread is unsafe and efficient. Sometimes, the order given is just good and the order of storage is consistent, but this does not mean order. You can try more. The elements are unique and out of order
public static void main(String[] args) { HashSet<String> hashSet = new HashSet<>(); //Creates a string object and adds it to the collection hashSet.add("hello"); hashSet.add("world"); hashSet.add("java"); hashSet.add("hello"); hashSet.add("world"); for(String s:hashSet){ System.out.println(s); } } } //world //java //hello
HashSet class
HashSet class overview
- The iterative order of set is not guaranteed
- In particular, there is no guarantee that the sequence will remain unchanged
public static void main(String[] args) { //In the process of string storage, we found that the data stored in HashSet is indeed unordered and unique /* But why store only one string with the same content when storing a string Let's see the source code Looking at the source code, we find that we first look at whether the HashCode() value is the same If so, continue to judge the equals() method If the returned content is true, it means that the element content is the same. If it is repeated, it will not be added If the returned content is false, it indicates that the element content is not repeated and is added to the collection If they are different, they are added directly to the collection If these two methods are not overridden in a class, the method in the parent class Object is called Why can String objects be de duplicated? Explain that the HashCode() and equasl() methods are overridden in the String class So you can remove the contents of the same string and leave only one */ HashSet<String> hashSet = new HashSet<String>(); //Add string to collection hashSet.add("hello"); hashSet.add("world"); hashSet.add("java"); hashSet.add("hello"); hashSet.add("world"); //Enhanced for loop traversal collection for(String s:hashSet){ System.out.println(s); } }
How does HashSet ensure the uniqueness of elements
- The underlying data structure is a hash table (elements are arrays of linked lists)
- Hash tables depend on hash value storage
- Two methods for adding function underlying dependencies
- int hashCode()
- boolean equals(Object obj)
public static void main(String[] args) { /* Define a HashSet collection to store custom objects and ensure the uniqueness of elements Requirement: if the values of the member variables of two objects are the same, it indicates that they are the same element We finished the program according to the requirements, but we didn't remove the duplication, so it didn't meet our requirements And because we know that the bottom layer of HashSet depends on HashCode() and equals() methods Because there is no override in the student class, the method in the Object is compared, and the address value is compared by default, Each student is new, so the address values are different, so they are inserted Now we need to rewrite the HashCode() and equals() methods. We don't need to write them ourselves. We can generate them automatically */ HashSet<Student> list = new HashSet<Student>(); Student s1 = new Student("zhangsan", 21); Student s2 = new Student("lisi", 22); Student s3 = new Student("wangwu", 23); list.add(s1); list.add(s2); list.add(s3); for(Student s:list){ System.out.println(s.getName()+"---"+s.getAge()); } } } //wangwu---23 //zhangsan---21 //lisi---22
Source code of add method in HashSet
public interface Collection<E> extends Iterable<E>{ ... } public interface Set<E> extends Collection<E>{ ... } public class HashSet<E> implements Set<E>{ //Supported by hash tables (actually HashMap instances) private transient HashMap<E,Object> map; public boolean add(E e) { return map.put(e, PRESENT)==null; } static final int hash(Object key) { //key -- e -- element to insert int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); } public V put(K key, V value) { //key -- e -- element to insert return putVal(hash(key), key, value, false, true); } //add() method in HashSet. Finally, we found that we called putVal() method in HashMap //The value of hash is related to the HashCode() method of the element final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { //The hash table stores an array of nodes Node<K,V>[] tab; Node<K,V> p; int n, i; //Judge whether the hash table is initialized. If not, initialize it if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; //Calculate the storage location according to the hash value of the element object. If the location of the element is null, it means that the location does not exist //Element, create a new node and store the element //Through the source code, we find that the add() method of HashSet must be related to the HashCode() method if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k; /* The stored element is compared with the hash value of the previous element If the hash values are different, continue down to add elements to the collection If the hash values are the same, the equals() method of the object is called for comparison If false is returned, the execution continues down and the element is added to the collection If true is returned, it means that the content of the element is the same. If it is repeated, it will not be stored */ if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; } }
LinkedHashSet
- LinkedHashSet: the bottom layer consists of hash table and linked list
- The hash table guarantees the uniqueness of elements
- The linked list ensures the order and order of elements (the order of storage and extraction is the same)
public static void main(String[] args) { LinkedHashSet<String> strings = new LinkedHashSet<String>(); strings.add("hello"); strings.add("world"); strings.add("java"); for(String s:strings){ System.out.println(s); } } } //hello //world //java
Thanks for watching, I'm cool Tao!!!