Know Why Never do.

Know the basic programming rules before you know when to break them

[TOC]

Create and destroy objects

The static factory method replaces the constructor

The static factory delivers the readability of the code and frees the caller from having to choose which parameter constructor

Static factories avoid creating too many duplicate objects

Static factories can return children of objects that you have customized (such as private, more flexible).

public class Service{
    private Service(a){};//Prevents instantiation
    private static final Map<String,Provider> providers =
        new ConcurrentHashMap<String,Provider>();
    //Provider registraion API
    public static void registerDefaultProvider(Provider p){
        registerProvider(name,p);
    }
    public static void registerProvider(String name,Provider p){
        providers.put(name,p);
    }
    //Provider unregistration API
    public static void unreginsterProviders(a){
        providers.remove();// All parameters are cleared
    }
    public static void unreginsterSelectProvider(String name){
        providers.remove(name);// Remove a certain
    }
    //Service asscess API
    public static Service newInstance(a){
        return newInstance(DEFAULT_PROVIDER_NAME);
    }
    public static Service new Instance(String name){
        Provider p = providers.get(name);
        if(p==null) throw Exception;
        returnp.newService(); }}Copy the code

Static factories are more concise when parameterizing type instances

Map<String,List<String>> m = newHashMap<String,List<String>(); ==> combine generic Map<String,List<String> m = hashmap.newinstance ();public static <K,V> HashMap<K,V> newInstance(a){
    return new HashMap<K,V>;
}
Copy the code

Examples of common static factory methods

ValueOf -- Returns an instance with the same value as its parameters, Type conversion method of -- valueOf short getInstance -- unique instance newInstance -- returns different instances getType -- returns object type newType -- returns different object typesCopy the code

moreThe constructor parameter is considered

Create instance selection with parameters advantages disadvantages
Overlapping constructor Suitable for <=3 parameter determination, such as custom view, low overhead Too many parameters cause poor readability, confusion, and errors
The JavaBean pattern Good readability, multi – parameter is not prone to error Inconsistent states occur, the immutable principle of illegal classes, threads are not safe
Builder pattern Suitable for >3, readable, flexible, parameter constrained, extensible Extra overhead, duplicate code
// Use the overlap constructor
mNativeAdLoader = new NativeAdLoader(mContext,unitId,"ab:123", timeout time);// Define the overlap constructor
public class NativeAdLoader{
    public NativeAdLoader(Context context,String unitId){
		this(context,unitId,"");
    }
    public NativeAdLoader(Context context,String UnitId,String stragegy){
    	this(context,unitId,stragegy,0)}public NativeAdLoader(Context context,String unitId,String stragegy,long timeout){
    	this.context = context;
    	this.unitId = unitId;
    	this.stragegy = stragegy;
    	this.timeout = timeout; }}Copy the code
/ / using the JavaBean
mNativeAdLoader = new NativeAdLoader();
mNativeAdLoader.setContext(mContext);
mNativeAdLoader.setUnitId(unitId);
mNativeAdLoader.setStrategy("ab123"); MNatvieAdLoader. SetTimeout (timeout);/ / define javabeans
public class NativeAdLoader{
	public NativeAdLoader(a){}
    public void setContext(Context context){
    	this.mContext = context;
    }
    public void setUnitId(String unitId){
    	this.unitId = unitId;
    }
    public void setStrategy(String strategy){
    	this.strategy = strategy;
    }
    public void setTimeout(long timeout){
    	this.timeout = timeout; }}Copy the code
// Use the keybuilder
mNativeAdLoader = new NativeAdLoader.Builder(mContext,"unitId")
    .forNativeAdSourcesByStrategy("ab:123", timeout).build();// Define the builder
public class NativeAdLoader{
    
    public static class Builder{
        // Necessary parameters
        protected Context mContext;
        private String mUnitId;
        // This parameter is optional
        private String mStrategy;
        private long mTimeout
        
        public Builder(Context context,String unitId){
            this.mContext = context;
            this.mUnitId = unitId;
        }
        
        public Builder forNativeAdSourcesByStrategy(String strategy,long timeout){
            this.mStrategy = strategy;
            this.mTimeout = timeout;
            return this;
        }
        
        public NativeAdLoader build(a){
            return new NativeAdLoader(this)}}public NativeAdLoader(Builder builder){
        this.context = builder.context;
        this.unitID = builder.unitID;
        this.strategy = builder.strategy;
        this.timout = builder.timeout; }}Copy the code

Enhance the Singleton attribute

Routine standard singletons

//Singleton with static factory
public class AdsManager{
    //private(not directly referenced) + static (convenient for static methods) + final (final object) + classload-time instantiation
    private static final AdsManager INSTANCE = new AdsManager();
    private AdsManager(a){};/ / privatization
    public static AdsManager getInstance(a){//getInstance indicates the singleton of the object
       	return INSTANCE;
    }
    //Remainder ommitted
}
Copy the code

Solve multi-threaded unsafe issues (lazy loading)

public class AdsManager{
    private static transient AdsManager mInstance;/ / the instantaneous
    private AdsManager(a){};
    public static AdsManager getInstance(a){
        if(mInstance == null){
            synchronize(AdsManager.class){
                if(mInstance ==null){
                    mInstance = newAdsManager(); }}}returnmInstance; }}Copy the code

Perfect enumeration writing (Java 1.5)

public enum AdsManager{
	INSTANCE;
}
// Compact readable, prevents multiple instantiations, provides serialization mechanism, cannot reflect attacks
Copy the code

Private constructors enforce non-instantiation capabilities

// Utility classes or classes that do not want to be instantiated
public class UtilsClass{
    // Privatize the default constructor and throw exceptions directly
    private void UtilsClass(a){
        throw new AssertionError();
    }
    //Remainder omitted
}
Copy the code

Avoid creating unnecessary objects

Avoid creating the same object more than once

String s = new String("123"); ==> String s = "123";
Date,Calendar, and TimeZone are created only once
Class Person{
    private final Date birthDate;
    
    private static final Date BOOM_START;
    private static final Date BOOM_END;
    // static block writing, class loading is performed only once
    static {
        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(...) ; BOOM_START = gmtCal.getTime(); getCal.set(...) ; BOOM_END = gmtCal.geTime(); }// Disadvantages If this method is not used, the above objects will still be created
    public boolean isBabyBoomer(a){
        return birthDate.compareTo(BOOM_START)>=0&&
               birthDate.compareTo(BOOM_END)<0; }}Copy the code

Avoid unconscious automatic boxing in favor of primitive data types

public static void main(String[] args){
    Long sum = 0L;// Pay special attention to avoid using packing boxes
    for(long i=0; i<Integer.MAX_VALUE; i++){ sum += i; } System.out.println(sum); }Copy the code

Reuse or create additional objects. Consider security, style, performance, clarity, simplicity, functionality, not generalities

Remove references to expired objects

A common source of memory leaks – expired objects

// stack implementation class
public class Stack {
    private Object[] elements;
    private int size=0;
    private static final int DEFAULT_INITIAL_CAPACITY=16;
    
    public Stack(a){
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }
    public void push(Object e){
        ensureCapacity();
        elements[size++] = e;
    }
    public Object pop(a){
        if(size==0)
            throw new EmptyStackException();
        Object result = elements[--size];
        elements[size] = null;//eliminate obsolete reference
        return result;
    }
    private void ensureCapacity(a){
        if(elements.length == size){
            elements = Arrays.copyOf(elements,2*size+1); }}}// What is an expired reference, active part, inactive part?
// Garbage collection automatically reclaims the inactive part of memory, and all the programmer has to do is tell the garbage about the expired reference object, which is the inactive part.
Copy the code

A common source of memory leaks – caches

1.WeakHashMap represents weak reference cache (when the cache item is automatically deleted when it expires and the life cycle of the cache item is determined by the external object of the key)

2. It is not easy to determine the life cycle of the cache, the cache over time becomes more and more value, to clear the Timer or ScheduledThreadPoolExecutor regularly

3. Clear cache when adding a new entry, LinkedHashMap. RemoveEldestEntry

4. Use java.lang. Ref??

A common source of memory leaks – listeners or other callbacks

1. No explicit deregistration

2. Not sure when to cancel, only the callback weak reference is saved, which is usually kept as the key in WeakHashMap

Ensure that the termination method is executed

/ / IO streams, connection, DB, etc
try{
    //do something
}catch(Exception){
    
}finally{//must do
    .close
        .cancel
        	.terminate();
}
Copy the code

Methods that are common to all objects

Follow the general convention when overriding equals

Equivalence relation

Reflexive x! =null&&x.equals(x) ==>trueSymmetric X! =null&&y! =null && x.exals (y) ==> Y.exals (x) Transitive x,y,z! =null && X. quals(y)&& Y. quals(z) ==> X. quals(z) Consistent (consistent) X,y! =null &&x, y not change ==>x. ecals (y) alwaystrue/falseNon-null (nevernull) x! =null && x.equals(null) ==>false
Copy the code

Principles (Omitted)

High-quality Equals tips

  1. == instead of equals, it’s time to cut costs

  2. Use the instanceof operation to check the type

  3. Parameter conversion types (instanceof tests by default)

  4. Write it like this (compare the one most likely to be different first)

    Double.compare Arrays.equals
    field == null? o.field == null: field.equals(o.field); If the field and o.f ield is of the same object references, faster field = = o.f ield | | (field! =null&&field.equals(o.field))
    Copy the code
  5. So you write your equals method and ask yourself if it’s symmetric, transitive, consistent

  6. Overwriting equals always overwrites hashCode

  7. Do not replace the Object declared by Equals with another type

    // Object. Equals is not overridden
    public boolean equals(MyCleass o){... } Override annotation benefits will tell you, make you upCopy the code

Always overwrite hashCode when overwriting equals

Why does it have to be this way?

1. This does not violate the general convention of Object.hashcode. (If the equals methods of two objects are equal, then calling either hashCode method of the two objects must produce the same integer result.)

2. Otherwise, this class will not work with hash-based collections, such as HashMap, HashSet, and HashTable

class PhoneNumber{
    private final short areaCode;
    private final short prefix;
    private final short lineNumber;
    public PhoneNumber(...).{
        //igore construct
    }
    
    @Override public boolean equals(Object O){
        //igore equals
    }
    
    //Broken - NO HashCode Method
}

Map<PhoneNumber,String> m = new HashMap<PhoneNumber,String>();
m.put(new PhoneNumber(123.456.789),"lizhaoxiong");
==>m.get(new PhoneNumber(110.456.789)) will be returnednull ***
==>m.get(new PhoneNumber(123.456.789)) will be returned"lizhaoixong"? Is the hashCode value of an object the same if the attribute value of the object changes? testCopy the code

The solution

@Override
public int hashCode(a){
    int result = 17;
    result = 31*result + areaCode;
    result = 31*result + prefix;
    result = 31*result + lineNumber; resutl result; } Look for oneintThe number; Different domain conversionint:
boolean(f?1:0) |byte.short.int (int)f |(int)(f^(f>>>32)) | Float. FloatToIntBits (f) | Double. DoubleToLongBits (f) + Float. FloatToIntBits (f) | | object, recursive calls the equals and hashCode. | array of Arrays. HashCode, recursive each element hashCode arrangement formula: result =31*result+c;
    

1.Why?31? Shift and subtraction instead of multiplication, JVM optimizes performance (31*i = (i<<5) - I)2Direct result.intWhat are the disadvantages of a constant value? Linear time, square time? Degraded hash ==> linked list3. How to use lazy initialization?if(the result =0) before calculation, the above code4What is a hash function?5What exact values do the hashCode methods of.string, Integer, and Date return? The downside?Copy the code

alwaysTo override the toString

Why do you have to do that?

1. It’s not mandatory, but it’s the norm.

2. If not overridden, try comparing the next class name @hexadecimal hash VS custom (concise, informative, easy to read)

3. ToString should return information of interest or diagnostics

4. ToString either returns uniform normalized formatting information or you annotate it well

Cover Clone carefully

Provides a way to create objects without calling the constructor

The exact meaning of copy depends on the class of the object

To understand this, a topic must be formed, which is of little significance at present

Consider implementing the Comparable interface

The difference between compareTo and equals?

1.compareTo is not declared in Object

2.compareTo is the only method that implements the Comparable object Array Array.sort(a)

The comparison returns an int

3. Raise ClassCastException if the comparison object type is different and equals returns false

4.Comparable The interface of the parable is parameterized. The Comparable method is a static type and does not require type conversion or type check. If the parameter is null, the comparable method cannot be compiled

Comparison of fields in 5.CompareTo method is sequential comparison rather than isotropic comparison.

When to use this interface? Collection (imp)

Since all value classes in the Java platform implement this interface, you should definitely consider implementing this interface when writing a value class that requires obvious internal ordering relationships, such as letters, values, times, etc

public interface Comparable<T>{
	int compareTo(T t);
}
Copy the code

Custom Comparators are used specifically for your custom sorts

Int comparison > < =, float and double Double.compare/Float.com pare said

Multiple key fields are compared, starting from the most critical and progressing to all important fields. The result is returned at the end of the non-zero result

public int compareTo(People p){
    if(inner < p.inner) return -1;
    if(inner > p.inner) return 1;
    if(out < p.out) return -1;
    if(out > p.out) return 1; .return 0;
}

// Make sure the difference is not greater than interger. MAX_VALUE 2^ 31-1
public int compareTo(People p){
    int diffInner = inner -p.inner; 
    if(diffInner! =0) return diffInner;
    
    int diffOut = out - p.out;
    if(diffOut! =0) return diffOut;
    return 0;
}
Copy the code

Classes and interfaces

Class and member accessibility is minimized

Reduce accessibility as much as possible

Use access methods in public classes for non-public cities

Android and Java public class member variable writing is the pursuit of brevity or security

class Point {
    public int x;
    public int y;
}

VS

class Point {
	private int x;
	private int y;
	
    public Point (int x,int y){
    	this.x = x;
    	this.y = y;
    }
	
    public void setX(int x){
    	this.x = x;
    }
    public void setY(int y){
    	this.y = y;
    }
    
    public int getX(a){return this.x}
    public int getY(a){return this.y}
}


// Build time constraints
public Point (int x, int y){
    if(x<0&&y<0) {throw new IllegalArgumentException("x,y" + x + y)
    }
    this.x = x;
    this.y = y;
}


Copy the code

Minimization of variability

How do I make a class immutable? (See String, BigInteger source code)

  • Do not provide any methods to modify the state of an object

  • Ensure that classes are not extended, such as declaring final classes and private constructors (valueof)

  • Declare fields to be final

  • Declaration fields are all private

  • Operating on an operand using a function does not modify it

    public Complex add(Complex c){
        return new Complex(x+c*x,y+c*y)
    }
    Copy the code

Why use immutable classes?

  • Compared with the complex space and uncertainty of mutable classes, immutable is stable and reliable

  • Immutable objects are thread-safe in nature and do not require synchronization

    // In order to encourage more use, it should be written in this way
    public static final Complex ZERO = new Complex(0.0);
    public static final Complex ONE = new Complex(1.0); ==> Further singleton to increase memory usageCopy the code
    
    Copy the code
  • Objects can be freely shared (excluding copy constructors)

  • Internal information sharing

  • Building blocks

  • Keep mutable classes to a minimum (e.g., TimerTask states only execute and cancel)

  • The only downside: Creating such objects can be expensive, and mutable companion classes are used to improve performance

    The mutable companion class of String is StringBuilder and the obsolete StringBuffer BigInteger is BitSetCopy the code

Composition over Inheritance

According to?

  • Inheritance across package boundaries is very dangerous and fragile
  • Integration breaks encapsulation. Subclasses take over the implementation details of the superclass, and subclasses break when the superclass changes

Compound/forward?

Want to add a function to an existing class/characteristics, add a private field in the new class, it refers to an instance of a class, existing the existing class become a component of the new class, such a design is called composite (composition) of a new class each method can be called contained an existing class instance of the corresponding methods, and returns the result of it, On the basis of forwarding, the result is returned with custom processing, which is called wrapper.Copy the code

​“`java Class A { public void methodA(){}; public void methodB(){}; }

Class BWrapper { private A a; public BWrapper(A a){this.a=a};

public void wrapA(){
    a.methodA();
}
public void wrapB(){
    a.methodB();
}
public void wrapC(){
    a.methodA();
    a.methodB();
}
Copy the code

}

The wrapper class is not suitable for the callback framework (SELF problem). Ask yourself before using inheritance, both is-aIs the relationship between? Is every B really also an A? You shouldn't extend A if you're not sure. So let B contain A private instance of A and expose the smaller, simpler API, where A is not essentially A part of B, but an implementation detail of it. (Java violates this principle, Stack is not a vector, property list is not a Hashtable)#### either document design for inheritance or disallow inheritanceWhy is it worth more to write base classes than to write implementations? Good API documentation describes what a given method <u> does </u>, not how <u> does it </u> what to look out for and what to do with such a method, Classes must provide appropriate hooks in some form. After writing an inheritable base class, you must subclass it for testing. Constructors must never call methods that can be overridden. Declare the class final 2. Privatize the constructor or package level private and add public static factories instead of the constructor (singleton) 3. Use the wrapper class pattern instead of inheritance to achieve more#### interfaces are superior to abstract classes** Differences ** - Abstract classes can include implementations, interfaces are not allowed - Abstract classes rely on inheritance to subclass, which loses flexibility due to Java's single inheritance principle - Interfaces are flexible, extensible, and non-hierarchical. Master with inheritance, multi-purpose interface good ** packaging class design pattern reflects the point ** ** multi-interface simulation multiple inheritance ** ** skeleton implementation ** (first design public interface, may be abstract base class simple public implementation, concrete subclass implementation) = simple implementation + abstract class ** Public interface design remember ** : Test the interface as much as possible, otherwise it will be hard to change once it goes liveThe #### interface is only used to define types** Constant interface patterns ** Implementation details leak apis, possibly late worthless, polluting code (ObjectStreamConstants) ** Need for fixed constants ** 1. Enumeration types 2. Non-instantiable utility classes (lots of reference class names) 3. Static importsThe #### class hierarchy is superior to the tag class

The #### function object represents the policyFunction pointer strategy Mode element sorting strategy: By passing different comparator functions, we can obtain a variety of permutation function objects: Java does not provide Pointers to functions, but uses object references to do the same thing. Methods on objects are operations on other objects, and a class exports a method whose instance is actually a pointer to that method. Such instances are called function objects.#### static member classes are preferred** There are four types of nested classes: ** ** static member classes (non-inner classes) ** : Characteristics - understood as just the statement to the ordinary class in a class to access the peripheral members of the class, declare a private or internal usage scenarios for peripheral class - public helper classes, like the enumeration, like a Calculator. The Operation. The MINUS * * class non-static member (internal) * * : Features - Each instance contains an extra reference to a peripheral object, non-static member classes rely heavily on the peripheral class, and cannot be distributed from non-static to static scenarios - Iterator, Entry of HashMap ** Anonymous classes (inner classes) ** : Features - No name, not a peripheral class member, instantiated when declared, not Instanceof, not extensible, must be short scene - dynamically create function objects, Anonymous comparators for Sort methods, create procedure objects Runnable, Thread, TimeTask, static engineering internal ** Local classes (inner classes) ** : Features -- use rare scenarios -- anywhere local variables can be declared What is the difference between a static inner class and a non-static inner class?# # generics

#### Do not use native types in new codeWhat generics do - they tell you at compile time if you want to insert an object of the wrong type, not at run-time. Generic definitions - a class or interface that declares multiple type parameters, as java1.5 began to support, such as List<String>. Private Final Collection Students = // Private Final Collection Students = // Private Final Collection Students = // Private Final Collection Students =... ; students.add(new Teather());for(Iterator i = students.iterator; i.hasNext();) { Student s = (Student) i.next(); Throws ClassCastException // Private final Collection<Student> Students =... ; students.add(new Teather()); // Advance Error //for- each andfor
for(Student s: students){}
for(Iterator<Student> i = students.iterator(); i.hasNext();) { Student s = i.next(); //No cast necessary }Copy the code

Difference between generics and native – generics checking

Generic subclassing – List is a subtype of the primitive List, not a subtype of the parameterized List

List<String> strings = new ArrayList<String>();
unsafeAdd(strings, new Integer(44));
String s = strings.get(0);
// The compiler passed, but received a warning
private static void unsafeAdd(List list, Object o){
    list.add(o);
}
List
      
        is not a subclass of List
       
      
private static void unsafeAdd(List<Object> list,Object o){
    list.add(o);
}
Copy the code

Unrestricted wildcard type – Set<? > uncertain and unconcerned about the actual parameter type

Unrestricted wildcard type Set<? What is the difference between > and primitive Set?

Safe! Not everything can be inserted into Set<? >, requires the declaration Extends?

When to use native (generic information can be erased at run time) – 1. Class literals 2. And instanceof

static voidNewElements (Set s1,Set s2) {for(Object o1 : s1){
        if(s2.contains(o1)){... }}}/ / complains
static void newElements(Set
        s1,Set
        s2){
    for(Object o1 : s1){
        if(s2.contains(o1)){... }}}// Use generics to use instanceof
if(0 instanceofSet){ Set<? > m = (Set<? >)o; }Copy the code

Eliminate non-inspection warnings

Unchecked warnings – forced conversions, method calls, plain arrays, conversions warnings

Simple ==> use generics, can be eliminated

Difficult ==> @suppressWarnings (“unchecked”) // Be sure to use validation annotations for reasons

Lists take precedence over arrays

What’s the difference between arrays and generics?

  1. Arrays are covariant and materialized; Generics are immutable and erasable.
  2. Arrays and generics cannot be used together (mixed) (generic array creation error)

Why isn’t List a superclass or a subclass of List?

Because the type information has been erased.

Why list first and array second?

Errors found principles – can be found at compile time, do not have to put into a running found that generic list (erase – compile-time checking type information, runtime type information erasure) prior to the array (runtime checking element type constraints), the like subway security, check for you before you enter the subway (generic list), and when you have entered the subway, It’s very dangerous for someone to check on you again.

Kind of generics

How do you learn to write generics?

  1. Change the name of the type parameter Object to E
  2. Replace all Object types with the corresponding type parameter
  3. There will be an error or a warning. For both errors and solutions, see the code below
Elements =newE[DEFAULT_INITIAL_CAPACITY]; = = >@suppressWarnings("unChecked")
elements = (E[])new Object[DEFAULT_INITIAL_CAPACITY];

E result = elements[--size];
==>
E result = (E)elements[--size]
==>
@SuppressWarnings("unCkecked") E result = (E)elements[--size]; Anyway, I need you to make sure there are no safety issuesclass DelayQueue<E extends Delayed> implements BlockingQueue<E>; E is called a restricted type parameter and each type is a subtype of itCopy the code

Method generization

public static <E> Set<E> union(Set<E> s1,Set<E> s2){
    Set<E> result = new HashSet<E>(s1);
    result.addAll(s2);
    return result;
}

// Eliminate the code chenyu
Map<String,List<String>> ana = new HashMap<String,List<String>>();
==>
Map<String,List<String>> ana = newHashMap(); 
public static <K,V> HashMap<K,V> newHashMap(a){
    return new HashMap<K,V>();
}

// The recursive type restricts the Comparable interface
public interface Comarable<T>{
    int compareTo(T o);
}

// Calculate the maximum value of the list based on the natural order of the elements
public static <T extends Comparable<T>> T max(List<T> list){
    Iterator<T> i = list.iterator();
    T result = i.next();
    while(i.hasNext()){
        T t = i.next();
        if(t.compareTo(result)>0){ result = t; }}return result;
}
Copy the code

Use restricted wildcards to increase the flexibility of the API

Generic parameter type characteristics?

  1. immutable
  2. List is not a subclass of List, but it is its own subclass

    Two ways to increase flexibility?

    PECS(producer-extends,consummer-super)

    Reasonable selection of strict parameter type, producer parameter, consumer parameter, packaging type safety and flexibility

    public class Stack<E> {
        public void push(E e);
        public E pop(a);
    }
    
    + pushAll
    
    + popAll
    
    // Subclasses cannot be pushed, because Integer is a subclass of Numble, but Integer cannot be inserted as Numble
    public void pushAll(Iterable<E> src){
    	for(E e: src){ push(e); }} Restricted wildcard types ==>public void pushAll(Iterable<? extends E> src){
    	for(E e: src){ push(e); }}// If E is Object, Numble cannot call Object because Object is the parent of Numble
    public void popAll(Collection<E> dst){
    	while(! isEmpty()){ dst.add(pop()); }} Restricted wildcard types ==>public void popAll(Connection<? super E> dst){
    while(! isEmpty()){ dst.add(pop()) } }Eg1: / / upgrade
    static <E> E reduce(List<? extends E> list ,Function<E> f);
    // Update EG2: The return type is still Set
            
             . Do not use wildcard types as return types unless flexibility is very important
            
    public static <E> Set<E> union(Set<? extends E> s1,Set<? extends E> s2)
    / / upgrade eg3:
    public static <T extends Comparable<? super T>> T max(List<? extends T> list)
        
    // Note that the type matches:
    max(List<? extends T> list){
    Iterator<? extends T> i = list.iterator();
    }
    
    // An unrestricted type argument that cannot put elements back into the list from which they were just taken
    public static void swap(List<? > list,int i,int j){ list.set(i,list.set(j,list.get(i))); } ==> Call swapHelper(List<E> List,int i,int j)                                                                                                  
    Copy the code

    Give priority to heterogeneous containers that are type safe

    Generic usage scenarios

    Sets (Set, Map, List), single-element containers (ThreadLocal, AtomicReference)

    1. Each container can only have a fixed tree type parameter
    2. Each key can have a different parameterized type
    3. Class String. Class belongs to the Class type

    How do you customize key types?

    Map<Class,Object> favorites = new HashMap,Object>()

    Enumerations and annotations

    Use emum instead of int/String constants

    Why is that?

    1. Hard coded writing errors that are not reported at compile time but are reported at run time
    2. Int prints poorly
    3. Enumeration = int + print + arbitrary add methods and fields
    4. The essence of enumeration is singleton generification, that is, enumeration of a single element
    5. Overrides toString in enumeration are easy to print
    6. Associate different behaviors with enumerated constants
    7. Never mind the performance cost of enumerations, use them when you have the opportunity

    Use EnumMap instead of indexed arrays

    1. Most groups are best converted to Map enumerated collections + generic design!

    2.EnumMap uses arrays indexed by Ordinal Numbers internally and hides implementation details

    3. The biggest problem with arrays is that the relationship between ordinals and array indexes cannot be guaranteed

    Nested EnumMap (page 142) EnumMap<… , EnumMap<… > >.

    5. It is silly to use Enum. Ordinal

    // Print all the garden flowers according to their species
    //1. Print map, key is type, vlaue is collection of flower objects (definition)
    //2. Go through the original set (type) and rewrite put
    //3. == Walk through the garden to get flower objects
    Map<Flower.Type, Set<Flower>> flowersByType = 
        new EnumMap<Flower.Type, Set<Flower>>(Flower.Type.class); 
    for(flower.type t: flower.type. Values ()) {--values Is the object for key returned? flowersByType.put(t,new HashSet<Flower>());
    }
    for(Flower f:garden){
    	flowersByType.get(f.type).add(f);
    }
    System.out.println(flowerByType);
    Copy the code

    Replace ordinal references with instance fields

    The ordinal method returns the numeric position (ordinal) of each constant type

    This method is designed to be used by EnumSet and EnumMap. Avoid using the ordinal method yourself entirely

    // Error case
    public enumEnsemble{ ONE,TWE,THTREE... ;public int numberOfDay(a){
        return ordinal()+1; }}// Correct example
    public enum Ensemble{
        ONE(1),TWE(2),THREE(3)... ;private int num;
        Ensemble(int day){num = day}
        public int numOfDay(a){return num;}
    }
    Copy the code

    Replace bitfields with EnumSet

    Why is that?

    1. Avoid manual errors and unsightly code!
    2. Enumsets are represented by a single long and perform as well as bitfields
    // bad code
    public class Text{
        public static final int STYLE_BOLD = 1 << 0; / / 1
        public static final int STYLE_ITALIC = 1 << 1; / / 2
        public void applyStyles(int styles){... } ==> text.applyStyles(STYLE_BOLD | STYLE_ITALIC); }//nice code
    public class Text{
        public enum Style{BOLD,ITALIC... }
        public void applyStyles(Set<Style> styles){... } ==> text.applyStyles(EnumSet.of(Style.BOLD,Style.ITALIC)); }Copy the code

    Simulate scalable enumerations with interfaces

    1. How can enumerations of primitive data types be implemented by extending enumerations

    2. Through the Collection <? Extends Operation> This restricted wildcard type

    3. Although you cannot write an extensible enumerated type, you can simulate it by writing an interface that implements that interface

    Annotations take precedence over named patterns

    Three drawbacks to naming patterns:

    1. Third-party libraries and frameworks require names that are written incorrectly, giving the illusion that the test is correct without execution
    2. There is no guarantee that they will only be used on the corresponding program element
    3. Unable to associate parameter values with program elements

    Annotation type:

    @Retention(retentionPolicy.runtime) -- RUNTIME retention@Target(ElementType.METHOD) -- scope, which makes sense in a METHODpublic @interface Test {} 
    
    //Retention(Health scope, source code, class, Runtime)
    / / Documented, Inherited, Target, scope, methods, properties, constructors, etc.)
    Copy the code
    1. Good programmers use annotations; average programmers have no chance to define annotation types
    2. But finally there is an opportunity to consider using annotation libraries, which many ides and static analysis tools or third-party support libraries provide
    3. What is the rationale for annotation implementation and how do you customize annotations and the ones you use most often

    Do use the Override annotation

    Prevent overwriting due to overloading or unintentional overwriting (add overwriting if needed)

    Define the type with the tag interface

    Should I use tagged interfaces or tagged annotations?

    1. Whether it is used only by classes and interfaces or by any program element
    2. Whether the tag is forever restricted to special interface elements

    Reference: Serializable markup interface (serialized interface)

    methods

    How are parameters and return values handled?

    How to design method signatures?

    How do I document a method?

    Focus on usability, robustness, and flexibility

    Check the validity of parameters

    1. Check the validity of parameters before errors occur to reduce the difficulty of debugging

    2. Use the @throws tag to identify the exceptions that are thrown in violation of the parameter value limit, for example, ArithmeticException

    IllegalArgumentException, IndexOutOfBoundsException, NullPointerException

    3. Use assertions for validation checks

    4. Once a validation check fails, your efforts will be reimbursed with interest

    / * * *@throws NullPointerException if object is null
     */
    public static <T> T requireNonNull(final T object, final String message) {
        if (object == null) {
            throw new NullPointerException(message);
        }
        return object;
    }
    Copy the code

    Make protective copies if necessary

    Do not use Clone for protective copies

    The protective copy is made before checking the validity of the parameters

    The Date class is mutable, so leave it to things like date.getTime () to return long for the time representation

    Design method signatures carefully

    1. Develop good naming habits, method names reflect taste
    2. Don’t go for convenience. Offer too many methods
    3. Avoid long argument lists, out of order, and hard to remember
      1. Split a method into multiple methods, such as the sublist of List combined with the indexOf and lastIndexOf methods
      2. Creating helper Classes
      3. Adopt Builder mode
    4. For parameter types, interfaces are preferred over classes, such as Map over HashMap or TreeMap, and List over ArrayList
    5. For Boolean parameters or parameters that determine fixed values, enumeration types are more elegant

    Careful with overloading

    Overloading is determined at compile time – overloading methods with the same name can easily result in calls to this or this method when called.

    How to avoid overloading – Never use two overloaded methods with the same number of arguments.

    When creating multiple methods that have similar functions but only different parameter types, try to distinguish them by method names rather than parameter types.

    When writing the API, please do not confuse the calling programmer, the call is not clear, to avoid overloading leads to hard-to-find errors.

    Coverage is run-time, so coverage is more secure. So avoids compile-time type impact

    public static String classify(Collection
              c){
        return c instanceof Set ? "Set" :
        	   c instanceof List ? "List" : "Unknow Collection"
    }
    Copy the code

    Be careful with variable parameters

    Mutable arguments are used when we write methods that specify the types of arguments but are uncertain about the number of arguments

    Sum (int… Sum (int [] args)

    ==> Create an array whose size is the number of arguments passed in the calling method

    // Variable arguments solve no-argument problems
    public static int min(int firstArg,int. args){
            int min = firstArg;
            for(intarg: args){ min = arg < min? arg:min; }return min;
    }
    Copy the code

    Mutable parameters are designed for printf, and the main function is in printf and reflection mechanism

    Arrays.asList ==> Arrays.toString() 
    Copy the code

    From a performance perspective, each call to a mutable parameter results in an array allocation and initialization, so flexibility vs. performance

    Returns a zero-length array or collection instead of NULL

    Null Pointers need to be considered every time, so try not to return null unless you consciously do so

    Code that never allocates a zero-length array

    // Returns a zero-length array
    private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
    public Cheese[] getCheeses[]{
        return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
    }
    // Returns an empty collection
    return Collections.emptyList();
    // Refer specifically to a few inner classes in the EmptyList series of Collections
    Copy the code

    Write a document injection for all exported API elements

    How to Write Doc Comments

    Add documentation comments for each exported class, interface, constructor, method, and domain declaration

    Method documentation comments:

    1. What does the method do rather than how does it do it
    2. The method can be called with all the prerequisites @throws tag or @param and post-conditions
    3. Possible side effects, such as starting a background thread, then the thread-safety of the method needs to be described
    4. @param@return (name phrase, parameter, or return value) @throws (if(if), name phrase (exception condition))

    And the text beginning with the tag does not end with a period

    1. @code tag {@code index<0} Multiple lines of code
      {@code index>=0}
    2. @ literal (characters) tag {@ literal | x + y + | y | | < | | x}
    3. The readability of the documentation should be better than that of the source code

    Summary Description – The first sentence of a document comment, a one-sentence Description of the API you wrote shows your ability to summarize

    More on:

    1. When the amount of code for annotations, interfaces, and enumerations is minimal, the amount of documentation is excessive.
    2. The thread-safety and serializable properties of a class need to be described
    3. Documentation for interfaces or base classes takes precedence over superclasses and implementation classes
    4. The HTML validity checker runs the HTML files generated by Javadoc
    5. The use of documentation comments should be mandatory, consistent, and standardized

    General programming

    Discusses the handling of local variables, control structures, the use of class libraries, the use of various data types, and the use of Reflection and native Method

    And optimization and naming conventions

    Minimize the scope of local variables

    1. Declare it where it is first used, rather than when it is used. If a variable is used before or after its intended use, the consequences can be serious
    2. Each variable declaration should contain an initialization expression (except for a try catch)
    3. If loop termination no longer requires loop variable content, for loop is superior to while (reuse element error and increased readability and brevity)
    4. Putting local variables inside a method or block of code minimizes scope, effectively avoiding another operation

    The for-each loop is superior to the for-loop

    According to?

    The for loop is better than the while loop, but error-prone due to iterators and index variables

    Use for-each loops to completely hide iterators and index variables, suitable for collections and arrays

    With a slight performance advantage, it evaluates the array index boundary value only once

    Nested traversals, where a NoSuchElementException is thrown if the number inside or outside is inconsistent. Nested loops may need to record the values traversed within the first loop, and for-each handles nesting perfectly

    Advise!

    If you’re writing a type that represents a set of elements, make it an Iterable, if not a Collection, so you can use for-each

    Three cases where for-each can’t be used!

    Filter — To remove the specified element call the remove method (modify)

    Replace – When iterating through a list or array to replace an element (modify)

    Parallel iterative

    Know how to use class libraries

    Random three disadvantages ==> pseudo-random number generator random.nextint (int), So

    1. Similar standard libraries have been certified by experts and have been validated and used countless times
    2. Don’t waste time offering special solutions to problems that aren’t related to your job. Focus on your app, not it
    3. Make your code mainstream, easy to read, easy to maintain, and reused by most developers

    Advise!

    1. The reason most programmers don’t use class libraries is because they don’t know. Of course the Java class library is huge, but it’s important to familiarize yourself with java.lang java.util java.io and the new features of each major release, and then look them up when you need them
    2. Focus on the Collections Framework
    3. Focus on the 1.5 version of the java.util.Concurrent package to simplify multithreaded programming tasks
    4. If what you’re doing is common, don’t reinvent the wheel

    Avoid floats and doubles if precise answers are required

    One way is to use Complex BigDecimal, inconvenient and slow, decimal points yourself (currency)

    Another option is to use int(simple) or long(complex)

    Base types are superior to reference types

    Java is divided into basic data types and reference types, each of which has a reference type

    The difference between them?

    1. The base data type has only values
    2. Reference type multiple NULL
    3. Basic types save more time and space

    It is always an error to use the == operator for reference data types

    Please declare the function as basic data type variables to avoid repeated packing and unpacking, resulting in performance degradation

    When do you use reference types?

    1. Elements, keys, and values in a collection. Java does not allow ThreadLocal types
    2. Reflected method calls are required to use boxing primitive types

    Avoid strings if other types are more appropriate

    Scenarios where strings are not suitable:

    1. It was originally int, float, BigInteger, yes or no Boolean, whatever it was!
    2. Not a good substitute for enumerated types
    3. Instead of an aggregate type (String compoundKey = className + “#” +i.next()), simply write a private static member class
    4. Not suitable for a unique key designed to be unforgeable — capability, see ThreadLocal’s get() method for key hiding

    Beware of string concatenation performance

    Use string concatenation + when simple output or display

    Use StringBuilder instead of String when the level of concatenation becomes large, or when concatenation is done using a for loop

    Use the Append method of StringBuilder

    Reference objects through interfaces

    More generally, parameters, return values, variables, and fields should all be declared using interface types if appropriate interface types exist

    Get in the habit of using interfaces as types to make your programs more flexible

    Vector<Subscriber> subscribers = new Vector<Subscriber>();
    ==> good code :
    List<Subscriber> subscribers = newVector<Subscriber>(); For example, replacing the ThreadLocal class HashMap with IdentityHashMap is a non-trivial matter, and there is no need to worry about the impactCopy the code

    If the object’s class is a class-based framework (Abstract class), the object should be referred to by its associated base class, such as TimerTask

    Interfaces take precedence over reflection

    Reflection provides programmatically accessible information about a class’s member names, domain types, methods, and so on

    Reflection is designed to:

    To create tool designs for component-based applications, such tools need to load classes. Normal applications should not access objects reflectively at run time. Current reflection mechanism use scenarios: browsers, object monitors, code analysis tools, interpreted embedded systems, RPC systems. Classes or outdated methods that are not available when compiled in real app

    Disadvantages of reflection:

    1. Lose the benefit of compile-time type checking
    2. The code for reflection access is very difficult to read and unwieldy and verbose
    3. Performance loss (from 2 to 50 times affected by machines)

    Usage Note: when you write programs to work with unknown classes at compile time

    Use local methods with caution

    Local methods are used for three purposes: mechanisms to access specific platforms, registries and file locks, the ability to access legacy code and data, and to provide system performance

    Using native methods to improve performance is not something that was advocated when it was possible now with the JVM’s block and Java platforms, such as BigInteger

    Native languages are not secure, may require gluing code, and are tedious and hard to read

    A Bug in your native code can kill you

    Optimize carefully

    Quotes:

    Many computer mistakes are attributed to efficiency (efficiency that is not necessarily achieved)

    Caring about the efficiency of small gains and losses, immature optimization is the root of all problems

    There are two rules to follow when it comes to optimization: first, don’t optimize and second, don’t optimize until you have an absolutely clear optimization solution

    Advise!

    API design has a very real impact on performance, which apis are optimized for performance is very important, and keeping the interface flexible is very important

    Don’t bother writing fast programs, write good programs, and speed will follow

    Performance tools are a good tool to use

    Follow generally accepted naming conventions

    Examples of literal conventions

    Identifier type example
    package com.xiaoyu.util, org.xiaoyu.dao.impl
    Class or interface HttpServlet, AsyncTask (word uppercase)
    Method or field ToString, equal, isUpperCase(lowercase first word, uppercase second word)
    Constant domain IP_ADDR(all caps, underlined between words)
    A local variable StuNumber,mString (similar to method name)
    Type parameters T, E, V, K and so on

    Syntactic naming convention

    Identifier type example
    class Name or the name of the phrase, Timer, BufferedWriter ChessPiece
    interface Collection,Comparator,Runnable,Iterable,Accessible
    annotations BindingAnnotation,Inject,ImplementedBy,Singleton
    Method or field Verb or phrasal verb, append or drawImage, returns Boolean is beginning isEmpty, isEnabled



    Method returns a function or property of a non-boolean object: speed(),color(),getTime(),getA+setA



    Convert object types: toType,toString,toArray

    Return View: asList

    Return and call object primitive type methods: typeValue, intValue

    Common names of static factories are valueOf, getInstance, newInstance, getType, and newType

    abnormal

    Take advantage of exceptions to improve the readability, reliability, and maintainability of the program, and introduce guidelines for exceptions

    Use exceptions only for exceptional situations

    Error functions of exceptions:

    1. Obscure the intent of the code
    2. It degrades its performance
    3. Cover a Bug
    4. Add complexity to the debugging process

    So, exceptions should only be used in exceptional cases and should never be used in normal control flow

    “Status Test Method” “Recognized Return Value”

    Use checked exceptions for recoverable cases and run time exceptions for programming errors

    Java programming provides three throwable structures

    1. Checked Exception
    2. Runtime exceptions indicate programming errors
    3. Error

    Never subclass Exception, it just annoys users of the API

    Avoid unnecessary use of checked exceptions

    Catch blocks are always characterized by assertion failure

    Standard exceptions are preferred

    Standards are meant to be reusable

    Reusable exception leaderboards

    1. IllegalArgumentExcetion, triggered when an argument passed is not appropriate — an illegal argument
    2. IllegalStateExcetion, which is triggered when the caller attempts to call an object that has not been properly initialized — illegal state
    3. IndexOutOfBoundsException, parameters in cross-border – special illegal
    4. ConcurrentModificationException and concurrent modification
    5. UnsupportedOperationException, object does not support this operation
    6. ArithmeticException, a NumberFormatException

    www.importnew.com/16725.html

    Throw an exception corresponding to the abstraction

    One of the most confusing exceptions is an exception thrown that has no obvious connection to the execution of the task, and is often thrown by the underlying abstraction. Right? !

    How to avoid it? — Abnormal translation

    public E get(int index) {
        try {
            return listIterator(index).next();
        } catch (NoSuchElementException exc) {
            throw new IndexOutOfBoundsException("Index: "+index);
        
    / / exception chain
            try{...//Use lower-level bidding
            }catch(LowerLevelException cause){
                throw new HigherLevelException(cause);
            }
    Copy the code

    Of course, do not abuse, you can check the validity of the arguments of the higher level method before passing arguments to the lower level method, so as to avoid the lower level method throwing exceptions

    And if you can’t avoid the underlying exceptions, let the higher-ups bypass them and isolate! And write it down.

    Every exception thrown by a method should be documented

    Include information to catch failures in the detail message

    If the failure situation is not easy to reproduce, it can be very difficult to analyze through the system log

    So, print out the details as you write the code

    Try to keep failure atomic

    1. That is, throw an exception at the beginning of the method to avoid executing the code that might be modified below
    2. An exception occurred before the object state was modified
    3. Using recovery code, the object is rolled back to the state before the operation began
    4. Performing operations on temporary copies, such as collections.sort, ensures that the list remains intact even if sorting fails

    Of course, don’t try too hard, wrong is wrong, and the API documentation should clearly indicate what state the named object will be in

    Don’t ignore exceptions

    It’s extremely irresponsible to try and catch without thinking about the consequences, at least if you can’t solve it, you can just print some logs

    concurrent

    Synchronous access to shared mutable data

    Synchronized Only one thread can execute a method or block of code at a time

    Understanding mutual exclusion: When an object is modified by one thread, it prevents another thread from observing inconsistent state inside the object (state consistency).

    Boolean reads and writes are atomic, allowing the first thread to poll (start false) and the second thread to change (false) to indicate that the first thread has terminated itself

    I++ is not an atomic operation

    Synchronization must be performed if mutable data is not shared or immutable data is shared and mutable data must be shared at all

    public class StopThread{
        private static boolean stopRequested;
        private static synchronized void requestStop(a){
            stopRequested = true;
        }
        private static synchronized boolean stopRequested(a){
            return stopRequested;
        }
        main(){
            Thread backgroudThread = new Thread(
                new Runnable(){
                    public void run(a){
                        int i = 0;
                        while(! stopRequested()) i++; }}); backgroundThread.start(); TimeUnit.SECOND.sleep(1);
            requestStop();
        }
    }
    
    
    or ==>
    private static volatile boolean stopRequested;// There is no need to write synchronous methods
    Copy the code

    Avoid excessive synchronization

    Excessive synchronization can lead to performance degradation, deadlocks, and uncertain behavior

    Deadlock cause: It tried to lock something, but it could not get the lock

    Analyze the internal synchronization of stringBuffers

    Split lock, split lock, non-blocking concurrency control

    Executors and tasks take precedence over threads

    // Replace the Executor Framework three steps for new thread
    ExecutorService executor = Executors.newSingleThreadExecutor();
    executor.execute(runnable);
    executor.shutdown();
    
    // The server is light loaded, and does not need to set anything
    Executors.newCachedThreadPool
    // Heavy load product, thread pool with fixed number of threads
    Executors.newFixedThreadPool 
    // Maximum use
    ThreadPoolExecutor
    
    Copy the code

    What Executor Famework does is execute

    What the Collections Framework does is aggregate

    Using ScheduledThreadPoolExecutor instead of the Timer, more flexible. A Timer uses only one thread. In the face of long tasks that affect accuracy, the Timer will stop if the thread throws an exception that is not caught. Executors, on the other hand, support multiple threads and gracefully recover from unchecked exception tasks thrown.

    Concurrency tools take precedence over Wait and notify

    Use more advanced concurrency tools instead of Wait and notify (too difficult manually)

    Concurrent Java.util. concurrent: Executor Framework, Concurrent Collection, Synchronizer

    Concurrent collections: ConcurrentMap, BlockingQueue (Producer and consumer queues)

    Synchronizer: CountDownLatch/CyclicBarrier – countdown latch, Semaphore

    System.nanotime is more accurate and precise, it is not affected by System clock adjustment (System.CurrentTimemills)

    Documentation of thread safety

    Levels of thread safety:

    • Immutable — String, Long, BigInteger
    • Unconditional thread safety – No concern for internal processing, Random, ConcurrentHashMap
    • Conditional thread-safe — Collections returned by the collections. synchronized wrapper, iterators that require external synchronization
    • Non-thread-safe — ArrayList, HashMap
    • Thread opposition — no consideration

    Private locks, which encapsulate the lock object in the object it synchronizes (private + final) apply to unconditional thread safety

    In short, conditional thread-safety must be documented by specifying which sequence of method calls requires external synchronization and which locks are acquired.

    Use delay initialization with caution

    Two-layer checking: Reduces the performance overhead of delayed initialization, plus volatile

    Do not rely on the thread scheduler

    Unrobust and non-portable

    Avoid thread groups

    The stack trace orientation a particular Thread in the domain of the application log. SetUncaughtExceptionHandler

    serialization

    To encode an object as a byte stream, serialization; Instead, it is deserialization.

    Serialized proxy pattern

    Carefully implement the Serializable interface

    The direct cost of serializing a class is very low, but the long-term cost is real, and once a class is published, it greatly reduces the flexibility of the class implementation.

    Deserialization of a class from an older version will often result in program failure.

    UID — Serialized version serialVersionUID, if you don’t serialize the UID explicitly, the automatically generated UID will change if the class changes, breaking compatibility and causing an InvalidClassException at runtime

    Deserialization, as a hidden constructor, has the same characteristics as other constructors and is prone to bugs and security holes

    As a new version of the class is released, the testing burden increases (to ensure that the serialization and deserialization processes are successful)

    Which classes need to be serialized (Date BigInteger, Throwable — exceptions pass from server to client, Component-GUI keep-send recovery, HttpServlet-call state cacheable, exist for this type of framework)

    Which classes should not be serialized (Thread pools, classes designed for inheritance + user interfaces – existing for extensions, otherwise burdened)

    ReadObjectNoData

    Inner classes should not be serialized

    Consider using a custom serialization form

    Variables represented by TRANSIENT do not serialize by default (instantaneous). WriteObject and readObject represent specific serialization forms

    @ serial label

    StringList

    Write the readObject method protectively

    The readObject method acts as a public constructor and, like other constructors, needs to check the validity of arguments and make protective copies of them if necessary

    For instance control, enumerated types take precedence over readResolve

    A Singleton implementing Serializable is no longer a Singleton unless it is done in readResolve

    Consider serialization instead of serialization instances

    Consider using the serialized proxy pattern when you cannot write a readObject or writeObject in a client extension class

    Journal entry?

    Know the rules, look behind them, break the rules, create new rules