Java programming thought notes 11 - Chapter 11: holding objects

11 holding object

Usually, the program always creates new objects according to certain conditions known at runtime.

There is no need to define the number of objects to be created in advance. You can create any number of objects as needed.

Array must implement the specified number, so it is constrained.

Java provides container classes to solve this problem. The basic types are List, Set, Queue and Map. These are called Collection classes and are subclasses of the Collection class or Map class.

Set cannot save duplicate values. Map allows you to associate objects with other objects.

These containers do not need to be specified in advance.

11.1 generic and type safe containers

Before Java se 5, you can insert incorrect types like containers. For example, you can create an Arraylist, which can insert either Apple type or Orange type

Insert the object through the add() method and access the data through the get method.

(1) Do not use generics

Because generics are not used, warnings will be prompted, which can be suppressed by @ SuppressWarnings.

class Cat{ }
class Dog{ }

public class Test {
    @SuppressWarnings("unchecked")  //No warning
	public static void main(String[] args) {	
		ArrayList dogs = new ArrayList();
		dogs.add(new Cat());
		dogs.add(new Dog());	
	}
}

When no type is specified, the default is the Object class. Because all classes inherit Object

(2) Use generics

Using generics means that you cannot insert other types of data

class Cat{ }
class Dog{ }

public class Test {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {	
		ArrayList<Dog> dogs = new ArrayList<Dog>();
//		dogs.add(new Cat()); //  An error will be reported and cannot be inserted
		dogs.add(new Dog());	
        for (Dog dog : dogs) { //Traversal using enhanced for loops
			System.out.println(dog);
		}
	}
}

(3) With generics, you can insert its subclasses

class Dog{ }
class Hasiqi extends Dog{} //Siberian Husky
class Keji extends Dog{} //Koki


public class Test {
	public static void main(String[] args) {	
		ArrayList<Dog> dogs = new ArrayList<Dog>();
		dogs.add(new Hasiqi());
		dogs.add(new Keji());
		
	}
}

11.2 basic concepts

The purpose of Java containers is to "save objects" and divide them into two different categories

​ (1)Collection. Including List, Set, Queue and other interfaces.

List indicates that the data is in order, Set cannot have duplicate elements, and Queue determines the order according to rules

(2) Map, which is composed of a pile of key value pairs, is associated in the form of a dictionary.

List<Dog> dogs = new ArrayList<Dog>();
List<Dog> dogs = new LinkedList<Dog>();
// The List here is an interface, which can point to its subclasses.

import java.util.Collection;
Collection<String> c = new ArrayList<String>();
c.add("abc");

11.3 adding a set of elements

​ Arrays. The aslist () method accepts an array or a comma separated List of elements (variable parameters) and converts it into a List object

​ Collections. The addall () method accepts a Collection object or a variable parameter and adds it to the Collection

import java.util.*;

public class Test {
	public static void main(String[] args) {		
		List<Integer> list = Arrays.asList(1,2,3,4,5);	
		Integer[] ins = {5,6,7,8};
		List<Integer> list2 = Arrays.asList(ins);
		
		Collection<Integer> coll = new ArrayList<Integer>(
				Arrays.asList(1,2,3,4,5) );
		Collections.addAll(coll, 1,2,3,4,5);
		Collections.addAll(coll,ins);
	}
}

11.4 printing of containers

Use arrays Tostring() to print

public class Test {
	public static void main(String[] args) {		
		Collection coll = new ArrayList<Integer>();
		coll.add("zhangsan");
		coll.add("lisi");
		System.out.println(coll);
		
		Map map = new HashMap();
		map.put("name","zhangsan");
		map.put("age",18);
		System.out.println(map);
	}
}
// Output results
// [zhangsan, lisi]
// {name=zhangsan, age=18}

List: saves elements in a specific order

Set: cannot store duplicate elements

Queue: only one end can be inserted and the other end can be removed

ArrayList and LinkedList are both List types

HashSet, TreeSet, and LinkedHashSet are all Set types. HashSet uses hash table storage, and the query time is fast.

HashMap, TreeMap and LinkedHashMap are all Map types.

11.5 List

The List interface adds a large number of methods to the Collection.

ArrayList, random query elements are fast, but insertion and deletion are slow

LinkedList, random query elements are slow, but insertion and deletion are fast.

import java.util.*;
class Dog{} 
class Hasiqi extends Dog{}

public class Test {
	public static void main(String[] args) {		
		List<Dog> dogs = Arrays.asList(new Dog(),new Dog());
		
		Dog d = new Dog();
		dogs.add(d);//Add a dog data
		dogs.remove(d); //delete
		Dog hashqi = new Hasiqi();
		System.out.println(dogs.indexOf(hashqi)); //Check the subscript of husky
		
		dogs.get(1); //Get element
		dogs.add(1,new Dog()); //Add to the specified location
		List<Dog> sub = dogs.subList(1, 2);//Get substring
		dogs.containsAll(sub); //Are all included
	}
}

11.6 iterators

Why use iterators? If you start with List coding and later find that it needs to be applied to Set, you have to start coding again.

Using iterators does not have this problem.

Java's Iterable can only move in one direction. Use iterator() to get the iterator object, next() to get the next element, hashNext() to check if there is another one, and remove() to delete the element.

public class Test {
	public static void main(String[] args) {	
		
		List<Integer> list = new ArrayList<Integer>(
				Arrays.asList(1,2,3,4,5,6,7,8));
		Iterator<Integer> it = list.iterator();
		while(it.hasNext()) {
			Integer temp = it.next();
			System.out.println(temp);
		}	
	
	}
}

11.6.1 ListIterator

ListIterator is a subclass of a more powerful Iterator.

The Iterator can only move forward, but the ListIterator can move in both directions.

You can specify the starting position through listIterator(n)

public class Test {
	public static void main(String[] args) {	
		
		List<Integer> list = new ArrayList<Integer>(
				Arrays.asList(1,2,3,4,5,6,7,8));
		ListIterator<Integer> it = list.listIterator();
		while(it.hasNext()) {
			Integer t1 = it.next();
			System.out.println(t1);
		}
		
		while(it.hasPrevious()) {
			Integer t2 = it.previous();
			System.out.println(t2);
		}
	}
}

11.7 LinkedList

LinkedList is slow in query, but fast in insertion and deletion

LinkedList also adds stack, queue and double ended queue methods

getFirst() is exactly the same as element(). It returns the first element. If it is empty, an exception will be thrown

peek() returns the first element. If it is empty, it returns null

removeFirst() is exactly the same as remove(). Delete the first element and throw an exception if it is empty

poll() deletes the first element and returns null if it is empty

addFirst(), add() and addList(), insert an element at the end of the list

removeLast() deletes and returns the last element

11.8 Stack

Stack, first in, last out. FILO

push() stack

pop() out of stack

peek() returns the stack top element

empty()

11.9 Set

Save non repeating elements

Set has exactly the same interface as Collection and has no additional functions.

public class Test {
	public static void main(String[] args) {	
		
		Set<String> set1 = new HashSet<String>();
		Collections.addAll(set1,"2","3");
		set1.add("4");
		System.out.println(set1);
	}
}

11.10 Map

Count the number of occurrences of the number

import java.util.*;
public class Test {
	public static void main(String[] args) {		
		Random rand = new Random(5);	
		Map<Integer,Integer> map = new HashMap<Integer, Integer>();
			
		for(int i=0;i<1000;i++) {
			int t = rand.nextInt(66);//Generate random numbers from 0 to 66
			
			Integer f = map.get(t);
			if (f == null) {
				f = 0;
			}else {
				f += 1;
			}
			map.put(t,f);			
		}
		
		System.out.println(map);
	}
}

11.11 Queue

A queue is a first in first out (FIFO) container that puts things from one section and takes them out from the other end.

LinkedList supports queue behavior and implements the queue interface.

Queue<Integer> queue = new LinkedList<Integer>();

The offer() method inserts the end of the list

The poll() and remove() methods remove the list header

The peek() and element() methods return the queue header

11.11.1 PriorityQueue

Priority queue, which gives priority to pop up the most needed elements.

When an object is inserted using the offer() method, it is sorted in the queue.

You can modify this order through your own Comparator.

import java.util.*;
public class Test {
	public static void main(String[] args) {	
		PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
		for(int i =10;i>0;i--) {
			pq.offer(i);
		}
		
		while(pq.peek() != null) {	
			Integer temp = pq.remove();
			System.out.println(temp);	
		}
		
	}
}
// Output results
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10

11.12 Collection and Iterator

Collection describes the root interface common to all sequence containers.

​ java.util.AbstractCollection provides the default implementation of Collection (non abstract methods in abstract classes) and can create subtypes of AbstractCollection.

import java.util.*;
class Seq extends AbstractCollection<Integer>{

	private Integer[] int_list = {1,2,3,4,5};
	
	@Override
	public Iterator<Integer> iterator() {
		return new Iterator<Integer>() { //Anonymous inner class, implementing interlator < integer > 
			private int index = 0;
			@Override
			public Integer next() { //Next data
				return int_list[index++];
			}
			
			@Override
			public boolean hasNext() { // Determine whether there is next data
				return index < int_list.length;
			}
		};
	}

	@Override
	public int size() {
		return int_list.length;
	}
	
}


public class Test {
	public static void main(String[] args) {	
		Collection seq = new Seq();
		Iterator<Integer> it = seq.iterator();
		while(it.hasNext()) {
			Integer temp = it.next();
			System.out.println(temp);
		}
	}
}

11.13 Foreach and iterators

(1) Foreach can be applied to any Collection object

import java.util.*;
public class Test {
	public static void main(String[] args) {	
		Collection<String> cs = new ArrayList<String>();
		Collections.addAll(cs, "long time no see".split(" "));//Add data
		for (String str : cs) {//Enhanced for loop
			System.out.println(str);
		}
		
	}
}

(2) After inheriting Iterable, you can use Foreach to enhance the for loop

import java.util.*;
class Hello implements Iterable<String>{
	private String[] str_list = {"a","b","c"};
	
	public Iterator<String> iterator(){
		return new Iterator<String>() {
			private int index =0;
			
			@Override
			public boolean hasNext() {
				return index < str_list.length;
			}

			@Override
			public String next() {
				return str_list[index++];
			}	
		};
		
	}
}

public class Test {
	public static void main(String[] args) {			
		for (String str : new Hello()) {
			System.out.println(str);
		}
		
	}
}

(3) Cyclic map data

public class Test {
	public static void main(String[] args) {			
		Map<String, String> map = new HashMap<String, String>();
		map.put("name", "zhangsan");
		map.put("age","18");
		
		for (Entry entry : map.entrySet()) {// entry is a key value pair, which traverses all key value pairs
			System.out.println(entry.getKey()+":"+entry.getValue());
		}
		
	}
}

11.13.1 adapter method usage

If you want to add a backward method to the Iterator, you can use the adapter method.

The adapter design pattern adds a forward iterative foreach loop on the original basis through inheritance.

import java.util.*;
class NewArray<T> extends ArrayList<T>{
	
	public NewArray(Collection<T> c){//Construction method
		super(c);
	}
	public Iterable<T> reversed(){
		return new Iterable<T>() { //Returns an anonymous inner class that implements Iterable
			@Override
			public Iterator<T> iterator() { //Implement the iterator method
				return new Iterator<T>() { //Return anonymous inner class
					int index = size()-1;

					@Override
					public boolean hasNext() {
						return index>-1;
					}
					
					@Override
					public T next() {
						// TODO Auto-generated method stub
						return get(index--);
					}
					
				};
			} // public Iterator<T> iterator()
			
		};	// return new Iterable<T>()
	}//Iterable<T> reversed()
}

public class Test {
	public static void main(String[] args) {			
		Collection<String> cs = new ArrayList<String>();
		Collections.addAll(cs, "a b c d e".split(" "));
		
		NewArray<String> n_list = new NewArray(cs);
		
		for (String str : n_list) {
			System.out.println(str);
		}
		for (String str : n_list.reversed()) {
			System.out.println(str);
		}
		
	}
}

11.14 summary

(1) the capacity of the array is determined in advance, but the container does not need to be determined in advance

(2) Collection saves a single element and Map saves key value pairs.

(3) array and List are ordered containers, and List can automatically expand capacity

(4) for random access, use ArrayList. If you often insert and delete in the middle of the table, use LinkedList

(5) LinkedList provides the behavior of implementing Queue and stack

(6) HashMap can quickly access data. TreeMap maintains the sorting status of key s, and LinkedHashMap maintains the insertion order of elements

(7) Set does not allow duplicate elements. HashSet has fast query speed, TreeSet maintains sorting status, and LinkedHashSet maintains insertion order

(8) do not use outdated Vector, Hashtable and Stack

The relationship is

  1. Collection (Interface)
    1. List (Interface)
      1. LinkedList
      2. ArrayList
    2. Set (Interface)
      1. LinkedList
      2. HashSet
        1. LinkedHashSet
      3. TreeSet
    3. Queue (Interface)
      1. LinkedList
      2. PriorityQueue
  2. Map (Interface)
    1. HashMap
      1. LinkedHashMap
    2. TreeMap

Collection can generate iterators

List can generate ListIterator

Keywords: Java queue

Added by dreglo on Fri, 14 Jan 2022 22:33:02 +0200