Java programming ideas - details Java holds objects (below)

1. Map collection

Since each element of the Map collection is composed of keys and values, it has the ability to map objects to objects.

  • containsKey() - Checks whether a key value is contained in the collection.
  • containsValue() - Check to see if a value is contained.
  • keySet() - get all keys
  • values() - get all values
  • get() - get the value corresponding to the specified key

Maps can be easily extended to multidimensional:

Map<Person,List<String>> map=new HashMap<Person,List<String>>();//Can store how many books each person owns
import java.util. *;

public class Box{	
    public static void main(String[] args){
	Map<String,List<String>> map=new HashMap<String,List<String>>();	
	map.put("Luck",Arrays.asList("A_Book","B_Book","C_Book"));
	map.put("Kate",Arrays.asList("D_Book","E_Book","F_Book"));
	map.put("Dawn",Arrays.asList("Q_Book","X_Book","Y_Book"));
	map.put("Marry",Arrays.asList("G_Book","H_Book","I_Book"));
	System.out.println("map: "+map);
	//Check if the set contains a certain key
	System.out.println("containsKey: "+map.containsKey("Luck"));
	//Check if the set contains a certain value
	System.out.println("containsValue: "+map.containsValue(22));
	// get all keys in the collection
	for(String people:map.keySet()){
            System.out.println("Name: "+people);
	}
	// get all the values ​​in the collection	
        for(List<String> list:map.values()){
	    System.out.println("AllBooks"+list);
	}
	//Get the value corresponding to the specified key	
        for(String people:map.keySet()){
	    System.out.println("Name: "+people);
	    System.out.println("---"+map.get(people));
	}		
    }
}


From our example, it can be found that the Map collection cannot use iterators directly , because iterators are designed for single-column collections. In actual use, you can use foreach to traverse, or convert the Map collection into a Set collection and then use an iterator to traverse.

eg2:

import java.util. *;

public class Box{	
	public static void main(String[] args){
		for(Map.Entry entry:System.getenv().entrySet()){
			System.out.println(entry.getKey()+"-----"+entry.getValue());
		}
	}
}

operation result:


     System.getenv() returns a Map collection that stores all environment variables of the computer. Map.entrySet() returns a Set<Map.Entry<K,V>> , Map.Entry is an interface in Map, its purpose is to represent a map item (with Key and Value in it), and Set< Map.Entry<K,V>> represents a Set of mapped items. There are corresponding getKey and getValue methods in Map.Entry, namely JavaBeans, which allow us to retrieve Key and Value from an item. Map also uses iterators through this method.

2. Queue (queue)

- A queue is a first-in, first-out (FIFO) container. That is , put in from one end of the container and take out from the other end, and the order of storage is consistent with the order of taking out . Queues are especially important in concurrent programming because they allow safe transfer of objects from one task to another.

      The LinkedList collection provides methods to support queues and implements the Queue interface, so LinkedList can be used as an implementation of Queue. In actual use, LinkedList is generally converted to Queue.

  • offer() - inserts an element to the end of the queue if allowed, or returns false;
  • peek() - returns the head of the queue without removing the element, or null when the pair column is empty;
  • element() - returns the head of the queue without removing the element, throws NoSuchElementException when the queue is empty;
  • poll() - remove the element and return the head of the queue, or null when the queue is empty;
  • remove() - Return to the head of the queue after removing the element, and throw NoSuchElementException when the queue is empty;

Note: The reason why we use up-casting when using LinkedList to implement the queue is to narrow the LinkedList to avoid some unnecessary functions.

Small example:

import java.util. *;

public class Box{	
	public static void main(String[] args){
		Queue<Character> queue=new LinkedList<Character>();	
		// store a set of characters in the queue
		for(char c:"hellojava!".toCharArray()){
			queue.offer(c);
		}
		System.out.print(queue);
		System.out.println();
		while(queue.peek()!=null){
			System.out.print(queue.peek()+"---");
			//System.out.print(queue.remove());
			System.out.print(queue.poll());
			System.out.println();
		}
		System.out.println();
		System.out.print(queue);
	}
}

operation result:


It can be seen from the running results that peek() returns the same element as remove() deletes each time, and it is first-in, first-out.

- PriorityQueue (priority queue)

       Declare that the next popup element is the most needed element, i.e. the element with the highest priority. Once the priority factor is added, the order of processing will be independent of arrival time. Therefore, when calling the peek(), poll(), and remove() methods in PriorityQueue, the elements obtained are the elements with the highest priority in the list. PriorityQueue can be easily used with Integer, String, Character, because these classes have built-in natural ordering, if we want to use our own class in PriorityQueue, we need to build additional functions to generate natural ordering, or we must provide our own Comparator .

import java.util. *;

public class Box{	
	public static void main(String[] args){
		String str="  Hello java and j2ee!";
		List<String> list=Arrays.asList(str.split(""));
		//store in natural order
		PriorityQueue<String> queue1=new PriorityQueue<String>(list);
        System.out.print(queue1);	
		System.out.println();		
		//store in reverse order of natural sorting
		PriorityQueue<String> queue=new PriorityQueue<String>(list.size(),Collections.reverseOrder());	
		queue.addAll(list);
		System.out.print(queue);
	}
}

3. Iterator

      Iterator (a design pattern) - is an object that can traverse and select objects in a sequence, and is called a lightweight object because there is little cost to create it. The iterator can separate the operation of traversing the sequence from the underlying structure of the sequence, so it can unify the access method to the container .

*Iterator iterator is provided in Java -

  • Use the Iterator() method to ask the container to return an Iterator. The Iterator will be ready to return the first element of the sequence.
  • Use next() to get the next element in the sequence.
  • Use hasNext() to check if there are more elements in the sequence.
  • Using remove() will remove the last element returned by the iterator.
 
 
import java.util. *;
public class Box{
	
	public static void main(String[] args){
		Set<String> t_box=new TreeSet<String>();	
		Collections.addAll(t_box,"B,A,C,E,D,F".split(","));
		//create an iterator
		Iterator it=t_box.iterator();
		while(it.hasNext()){
		    //If the remove method of the iterator is placed before the next() method, an error will be reported	
		    //it.remove();
		    System.out.print(it.next()+" ");
		    it.remove();
		    break;
		}
		System.out.println();
		//The for loop can also be used to traverse the collection
		for(String t:t_box){
		    System.out.print(t+" ");
		    //But deletion cannot be performed during traversal, because the size of t_box.size() will change every time an element is deleted	
		    //t_box.remove(t);
		}
	}
}

operation result:


It can be seen from the running result that the iterator can delete the elements in the collection while traversing, and delete the last value returned by the iterator. However, when using the delete function of the iterator, you need to pay attention to two points: first, it should be used after the .next() method; second, the remove() method cannot be used multiple times in a row . The reason why iterators can delete elements during traversal is that they maintain a flag during deletion to record whether they are currently in a deleteable state.

*ListIterator iterator is provided in Java -

     Is a more powerful Iterator subtype, but it can only be used for various List class accesses. One thing to note is that an Iterator can only move forward, while a ListIterator can move in both directions . It can yield the indices of the previous and next elements relative to the current position pointed to by the iterator in the list, and can use the set() method to replace the best element it has visited.

Two ways to create:

  1. Calling the ListIterator() method produces an iterator pointing to the beginning of the List.
  2. Calling the ListIterator(index) method produces an iterator pointing to the position of the element at index index in the List.
import java.util. *;
public class Box{	
	public static void main(String[] args){
		List<String> list=new ArrayList<String>();	
		Collections.addAll(list,"A,B,C,D,E,F".split(","));
		//Create an iterator that traverses all elements of the list
		ListIterator it = list.listIterator ();
		while(it.hasNext()){
		    System.out.print(it.next()+" ");
		}
		System.out.println();
		//Create a list element that traverses the following table starting from 3
		ListIterator it_index=list.listIterator(3);
		while(it_index.hasNext()){
		    System.out.print(it_index.next()+" ");
		    it_index.set("1");//Replace the traversed element with 1
		}
		System.out.println();
		
		ListIterator it2 = list.listIterator ();
		while(it2.hasNext()){
		    System.out.print(it2.next()+" ");
		}
	}
}

operation result:


It can be seen from the result that using the set() method of the iterator, the traversed elements can be replaced with the specified value.

*Foreach and iterators --

       The reason why Foreach can have the same effect as iterators when traversing a collection is because Java SE5 introduces a new interface called Iterable, which contains an iterator() method that produces an Iterator, and the Iterable interface is used by foreach to move through the sequence (that is, the underlying foreach is actually an iterator). Therefore, being able to work with foreach has become a feature of all Collection objects .

*Adapter method idiom -

      If you want to use two methods of forward and backward iteration to traverse a list, if you directly inherit and override the iterator() method, you can only replace the existing method, but cannot fulfill the requirement. At this point the idiom of using the adapter method (an idea of ​​a design pattern) can do the trick.

      You can't use overrides here, but add a method that produces an Iterable object that can be used in a foreach statement. This way we can have multiple ways to use foreach:

import java.util. *;

public class Box{	
	public static void main(String[] args){
		List<Integer> list=new ArrayList<Integer>();
		Integer[] a={1,2,3,4,5};
		list=Arrays.asList(a);
		ReversedList<Integer> rl=new ReversedList<Integer>(list);
		for(Integer i:rl){
			System.out.print(i);
		}
		System.out.println();
		for(Integer i:rl.reversed()){
			System.out.print(i);
		}
	}
}
class ReversedList<T> extends ArrayList<T>{
	public ReversedList(Collection<T> c){super(c);}
	public Iterable<T> reversed(){
		return new Iterable<T>(){
			public Iterator<T> iterator(){
				return new Iterator<T>(){
					int current=size()-1;
					public boolean hasNext(){return current>-1;}
					public T next(){return get(current--);}
					public void remove(){throw new UnsupportedOperationException();}
				};
			}
			
		};
	}
	
}

operation result:


- What is the adapter mode:

       Convert one interface to another interface that the client wants. The Adapter pattern enables classes to work together that would otherwise not work together due to incompatible interfaces . My understanding is that there are some interfaces where we only need some of the methods (maybe only one), and some classes that we have no inheritance relationship with but need one or more of them. At this time, we don't need to implement all the methods in the interface. There is no need to inherit a class (maybe you have inherited another class at this time), if we want to achieve our requirements, we can create a new interface through the adapter, the methods in the interface are those we need, and then create a class to implement This interface performs method deployment.

Summarize:

  • Arrays associate numbers and objects . Save type-specific objects, query objects do not need to do type conversion on the results. It can hold multi-dimensional basic types of data. But once generated, its capacity cannot be changed .
  • Collection holds a single element, while Map stores data of type key-value pairs. Generics determine the data type that should be stored, and no type conversion is required when getting elements from the container. Such containers can automatically change the size of the space for storing data . Cannot hold primitive types , but the automatic unboxing mechanism in Java can make up for this shortcoming.
  • The List collection also establishes the association between the numerical index and the object , so both the array and the List collection are sorted containers, but the List can automatically expand the capacity , but the array cannot. The List collection contains two implementation classes, ArrayList and LinkedList. The former is suitable for a large number of random accesses, while the latter is more suitable for operations with a large number of elements inserted or deleted .
  • Map is a design that associates objects with objects . HashMap is designed for fast access ; TreeMap keeps "keys" always in sorted state , so it is not as fast as HashMap; LinkedHashMap maintains the order in which elements are inserted, but also provides fast access through hashing .
  • Set collections cannot accept duplicate elements (relying on equals()), HashSet provides fast query speed, and TreeSet keeps elements in a sorted state. LinkedHashSet maintains the order in which elements were inserted.
  • Vector, Hashtable, and Stack have been eliminated, so try not to use them in actual development.
  • Generating an Iterator is the least-coupled way to wire the queue and consuming queue methods together, and it imposes far fewer constraints on the sequence class than implementing a Collection.


- The dotted line frame represents the interface

- The solid line box represents the implementation class

——The black thick line box represents the commonly used container

- The hollow arrow indicates the implementation of the interface

- Solid arrows indicate objects that can be implemented to point to the class

From this picture, we can see the relationship between the various containers very well, we need to remember him.

----------------------------------------------------------------------

The use of containers is crucial in actual development, where we need to be proficient in using various collections and iterators. On the other hand, from the last example, we will find the importance of inner classes in development. Design patterns also require us to spend a lot of effort to learn and deeply understand the ideas of design patterns.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325944831&siteId=291194637