1. 程式人生 > 實用技巧 >[速查] 常用演算法

[速查] 常用演算法

單例

1 執行緒不安全的懶漢式

public class Singleton {
    // 單例物件
    private static Singleton instance;
    // 私有建構函式
    private Singleton() {}
    // 靜態的工廠方法
    public static Singleton getInstance(){
      if (instance == null) {
        /*new操作不是原子操作,多執行緒情況下執行這裡時,
          多個執行緒同時判斷為null,new了多個物件,不再是
          執行緒安全。*/
        instance = new Singleton();
       }
        return instance;
    }
}

2 通過加鎖實現的執行緒安全的懶漢式

public class SingletonExample3 {
    // 私有建構函式
    private SingletonExample3() {}
    // 單例物件
    private static SingletonExample3 instance = null;
    // 執行緒安全但效率低
    public static synchronized SingletonExample3 getInstance() {
        if (instance == null) {
            instance = new SingletonExample3();
        }
        return instance;
    }
}

3 雙重鎖檢測的懶漢模式

public class SingletonExample5 {
    // 私有建構函式
    private SingletonExample5() {}
    // 單例物件 volatile + 雙重檢測機制 -> 禁止指令重排
    private volatile static SingletonExample5 instance = null;
    // 靜態的工廠方法
    public static SingletonExample5 getInstance() {
        if (instance == null) { // 雙重檢測機制
            synchronized (SingletonExample5.class) { // 同步鎖
                if (instance == null) {
                    instance = new SingletonExample5();
                }
            }
        }
        return instance;
    }
}

3 執行緒安全的餓漢模式

public class SingletonExample2 {
    // 私有建構函式
    private SingletonExample2() {
        /*
        餓漢模式的不足,如果這裡載入的內容很多的話可能會引起效能問題。
         */
    }
    // 單例例項在類裝載時進行建立所以是執行緒安全的
    private static SingletonExample2 instance = new SingletonExample2();
    // 靜態的工廠方法
    public static SingletonExample2 getInstance() {
        return instance;
    }
}

4 靜態內部類保證執行緒安全:

這種寫法仍然使用JVM本身機制保證了執行緒安全問題(這種模式是最早出現的一種模式,不用鎖機制,提高效能)

class Singleton4 {
    private static class SingletonHolder4 {
        private static final Singleton4 INSTANCE = new Singleton4();
    }
    private Singleton4() {
    }
    public static final Singleton4 getInstance() {
        return SingletonHolder4.INSTANCE;
    }
}

5 列舉實現執行緒安全的單例

public class SingletonExample7 {
    private SingletonExample7() {}
    public static SingletonExample7 getInstance() {
        return Singleton.INSTANCE.getInstance();
    }
    private enum Singleton {
        INSTANCE;
        private SingletonExample7 singleton;
        // JVM保證這個方法絕對只調用一次
        Singleton() {
            singleton = new SingletonExample7();
        }
        public SingletonExample7 getInstance() {
            return singleton;
        }
    }
}

排序

選擇排序

public class Selection<T extends Comparable<T>> extends Sort<T> {

    @Override
    public void sort(T[] nums) {
        int N = nums.length;
        for (int i = 0; i < N - 1; i++) {
            int min = i;
            for (int j = i + 1; j < N; j++) {
                if (less(nums[j], nums[min])) {
                    min = j;
                }
            }
            swap(nums, i, min);
        }
    }
}

2 冒泡

public class Bubble<T extends Comparable<T>> extends Sort<T> {

    @Override
    public void sort(T[] nums) {
        int N = nums.length;
        boolean isSorted = false;
        for (int i = N - 1; i > 0 && !isSorted; i--) {
            isSorted = true;
            for (int j = 0; j < i; j++) {
                if (less(nums[j + 1], nums[j])) {
                    isSorted = false;
                    swap(nums, j, j + 1);
                }
            }
        }
    }
}

3 插入

public class Insertion<T extends Comparable<T>> extends Sort<T> {

    @Override
    public void sort(T[] nums) {
        int N = nums.length;
        for (int i = 1; i < N; i++) {
            for (int j = i; j > 0 && less(nums[j], nums[j - 1]); j--) {
                swap(nums, j, j - 1);
            }
        }
    }
}

4 快速

public class QuickSort<T extends Comparable<T>> extends Sort<T> {

    @Override
    public void sort(T[] nums) {
        shuffle(nums);
        sort(nums, 0, nums.length - 1);
    }

    private void sort(T[] nums, int l, int h) {
        if (h <= l)
            return;
        int j = partition(nums, l, h);
        sort(nums, l, j - 1);
        sort(nums, j + 1, h);
    }

    private void shuffle(T[] nums) {
        List<Comparable> list = Arrays.asList(nums);
        Collections.shuffle(list);
        list.toArray(nums);
    }
}