1. 程式人生 > >Java筆記:集合框架

Java筆記:集合框架

system @override emp 底層 log 關聯 del java筆記 集合框架

一、接口

  • Collection:構建集合框架的基礎,定義集合的所有類都必須實現該接口。
  • List:線性表,Collection接口擴展。
  • Set:集,Collection接口擴展。
  • SorttedSet:以升序排序的集,Set接口擴展。
  • NavigableSet:可基於最接近匹配原則檢索元素的集,SortedSet接口擴展。
  • Queue:隊列,Collection接口擴展。
  • Deque:雙端隊列,Queue接口擴展。

二、集合類

動態數組。

技術分享圖片
import java.util.ArrayList;

class Solution {
    public static void main(String[] args) {
        ArrayList
<Integer> list = new ArrayList<>(100);//初始大小100 for (int i = 0; i < 100; i++) list.add(i); list.ensureCapacity(500);//重置大小為500 for (int i = 100; i < 500; i++) list.add(i); Integer[] arr = new Integer[list.size()]; arr = list.toArray(arr);//
獲取數組 for (int i : arr) System.out.println(i); } }
View Code

鏈表。

技術分享圖片
import java.util.LinkedList;

class Solution {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 100; i++)
            list.add(i);
//插入尾元素 for (int i = 100; i < 200; i++) list.push(i);//插入首元素 list.removeFirst();//刪除首元素 list.removeLast();//刪除尾元素 System.out.println(list); } }
View Code

哈希集。

技術分享圖片
import java.util.HashSet;

class Solution {
    public static void main(String[] args) {
        HashSet<Integer> setA = new HashSet<>();//默認容量16
        HashSet<Integer> setB = new HashSet<>(100, (float) 0.8);//初始容量為100,填充率到達0.8時擴容
    }
}
View Code

三、叠代器

叠代器是實現了Iterator接口或ListIterator接口的對象。ListIterator接口為Iterator接口的擴展,支持雙向遍歷。

技術分享圖片
import java.util.ArrayList;
import java.util.Iterator;

class Solution {
    public static void main(String[] args) {
        ArrayList<Character> list = new ArrayList<>();
        for (char c = ‘A‘; c <= ‘E‘; c++)
            list.add(c);
        //叠代器遍歷
        Iterator<Character> itr = list.iterator();
        while (itr.hasNext())
            System.out.print(itr.next());
        //foreach遍歷
        for (char c : list)
            System.out.print(c);
    }
}
View Code

實現了Spliterator的叠代器可循環遍歷,並且支持並行叠代。它將hasNext和next合並以提高效率。

技術分享圖片
import java.util.ArrayList;
import java.util.Spliterator;

class Solution {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++)
            list.add(i);
        Spliterator<Integer> splitr = list.spliterator();
        while (splitr.tryAdvance((i) -> System.out.println(i)));

        splitr = list.spliterator();
        splitr.forEachRemaining((i) -> System.out.println(i));
    }
}
View Code

四、映射

  • Map:將鍵映射到值。
  • Map.Entry:描述鍵值對。
  • SortedMap:以升序保存鍵,Map接口擴展。
  • NavigableMap:基於最接近匹配的鍵值對檢索,SortedMap接口擴展。

哈希映射,無序。

技術分享圖片
import java.util.HashMap;

class Solution {
    public static void main(String[] args) {
        HashMap<String, Integer> months = new HashMap<>();
        months.put("Jan", 1);
        months.put("Feb", 2);
        months.put("Mar", 3);
        months.put("Apr", 4);
        months.put("May", 5);
        months.put("June", 6);
        months.put("July", 7);
        months.put("Aug", 8);
        months.put("Sept", 9);
        months.put("Oct", 10);
        months.put("Nov", 11);
        months.put("Dec", 12);

        System.out.println(months.entrySet());
        System.out.println(months.keySet());//[June, Sept, Oct, Feb, Apr, Aug, Dec, May, Nov, Jan, July, Mar]
        System.out.println(months.values());//[6, 9, 10, 2, 4, 8, 12, 5, 11, 1, 7, 3]
    }
}
View Code

紅黑樹映射,有序。

技術分享圖片
import java.util.TreeMap;

class Solution {
    public static void main(String[] args) {
        TreeMap<String, Integer> months = new TreeMap<>();
        months.put("Jan", 1);
        months.put("Feb", 2);
        months.put("Mar", 3);
        months.put("Apr", 4);
        months.put("May", 5);
        months.put("June", 6);
        months.put("July", 7);
        months.put("Aug", 8);
        months.put("Sept", 9);
        months.put("Oct", 10);
        months.put("Nov", 11);
        months.put("Dec", 12);

        System.out.println(months.entrySet());
        System.out.println(months.keySet());//[Apr, Aug, Dec, Feb, Jan, July, June, Mar, May, Nov, Oct, Sept]
        System.out.println(months.values());//[4, 8, 12, 2, 1, 7, 6, 3, 5, 11, 10, 9]
    }
}
View Code

哈希映射鏈表實現,按插入順序叠代。

技術分享圖片
import java.util.LinkedHashMap;

class Solution {
    public static void main(String[] args) {
        LinkedHashMap<String, Integer> months = new LinkedHashMap<>();
        months.put("Jan", 1);
        months.put("Feb", 2);
        months.put("Mar", 3);
        months.put("Apr", 4);
        months.put("May", 5);
        months.put("June", 6);
        months.put("July", 7);
        months.put("Aug", 8);
        months.put("Sept", 9);
        months.put("Oct", 10);
        months.put("Nov", 11);
        months.put("Dec", 12);

        System.out.println(months.entrySet());
        System.out.println(months.keySet());//[Jan, Feb, Mar, Apr, May, June, July, Aug, Sept, Oct, Nov, Dec]
        System.out.println(months.values());//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    }
}
View Code

五、比較器

如果希望以不同的方式排序元素,可以再構造集合時指定比較器。

Comparator是泛型接口,部分方法如下

  • compare:比較對象的大小。
  • equals:測試比較器的排序順序是否相同。
  • reversed:獲取相反順序的比較器。
  • reverseOrder:獲取相反元素的自然順序比較器。
  • naturalOrder:獲取自然順序比較器。
  • nullsFirst:認為null比其他值小的比較器。
  • nullsLast:認為null比其他值大的比較器。
  • thenComparing:當首次比較相等時指定其他比較器。
技術分享圖片
import java.util.Comparator;
import java.util.TreeSet;

class Student {
    String name;
    int total;

    Student(String name, int total) {
        this.name = name;
        this.total = total;
    }

    @Override
    public String toString() {
        return name + " " + total;
    }
}

class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student a, Student b) {
        if (a.total != b.total)
            return a.total - b.total;
        else return a.name.compareTo(b.name);
    }
}

class Solution {
    public static void main(String[] args) {
        TreeSet<Student> set = new TreeSet<>(new StudentComparator().reversed());
        StringBuilder nameBuilder = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            int total = (int) (750 * Math.random());
            for (int j = 0; j < 3; j++)
                nameBuilder.append((char) (25 * Math.random() + 65));
            set.add(new Student(nameBuilder.toString(), total));
            nameBuilder.delete(0, nameBuilder.length());
        }
        System.out.println(set);
    }
}
View Code

函數式接口。

技術分享圖片
Comparator<Student> comp = (a, b) -> {
    if (a.total != b.total)
        return a.total - b.total;
    else return a.name.compareTo(b.name);
};
TreeSet<Student> set = new TreeSet<>(comp);
View Code

thenComparing。

技術分享圖片
import java.util.Comparator;
import java.util.TreeSet;

class Student {
    String name;
    int total;

    Student(String name, int total) {
        this.name = name;
        this.total = total;
    }

    @Override
    public String toString() {
        return name + " " + total;
    }
}

class ComparatorA implements Comparator<Student> {
    @Override
    public int compare(Student a, Student b) {
        return a.total - b.total;
    }
}

class ComparatorB implements Comparator<Student> {
    @Override
    public int compare(Student a, Student b) {
        return a.name.compareTo(b.name);
    }
}

class Solution {
    public static void main(String[] args) {
        ComparatorA compA = new ComparatorA();
        Comparator<Student> comp = compA.thenComparing(new ComparatorB());
        TreeSet<Student> set = new TreeSet<>(comp);
        StringBuilder nameBuilder = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            int total = (int) (750 * Math.random());
            for (int j = 0; j < 3; j++)
                nameBuilder.append((char) (25 * Math.random() + 65));
            set.add(new Student(nameBuilder.toString(), total));
            nameBuilder.delete(0, nameBuilder.length());
        }
        System.out.println(set);
    }
}
View Code


六、集合算法

集合框架定義了可用於集合和映射的算法,這些算法被定義為Collections中的靜態方法。

技術分享圖片
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;

class Solution {
    public static void main(String[] args) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int i = 0; i < 10; i++)
            list.add(i);
        Comparator<Integer> comp = Collections.reverseOrder();//獲取整數的反向比較器
        Collections.sort(list, comp);
        System.out.println(list);//[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
        System.out.println(Collections.max(list));
        System.out.println(Collections.min(list));
        Collections.shuffle(list);//隨機化
        System.out.println(list);
    }
}
View Code

數組算法。

技術分享圖片
import java.util.Arrays;
import java.util.Collections;
import java.util.Spliterator;
import java.util.stream.Stream;

class Solution {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3, 4, 5};
        System.out.println(Arrays.binarySearch(arr, 0));//-1
        Integer[] cpyA = Arrays.copyOf(arr, 3);//1 2 3
        Integer[] cpyB = Arrays.copyOfRange(arr, 0, 3);//1 2 3
        System.out.println(Arrays.equals(cpyA, cpyB));

        Arrays.sort(arr, Collections.reverseOrder());
        Arrays.parallelSort(arr);//並行排序

        Spliterator<Integer> splitr = Arrays.spliterator(arr);//獲取叠代器
        Stream<Integer> stream = Arrays.stream(arr);//獲取流
    }
}
View Code

七、遺留類與接口

Vector實現了動態數組。ArrayList與其的主要區別是Vector是同步的,並且包含許多遺留方法。

技術分享圖片
import java.util.Collections;
import java.util.Vector;

class Solution {
    public static void main(String[] args) {
        Vector<Integer> vector = new Vector<>();
        for (int i = 0; i < 100; i++)
            vector.addElement(i);
        vector.sort(Collections.reverseOrder());
        for (int i = 0; i < vector.size(); i++)
            System.out.println(vector.elementAt(i));
    }
}
View Code

Stack是Vector的子類,實現了標準的堆棧。不反對使用,但ArrayDeque是更好的選擇。

技術分享圖片
import java.util.Stack;

class Solution {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        for (int i = 0; i < 100; i++)
            stack.push(i);
        while (!stack.empty())
            System.out.println(stack.pop());
    }
}
View Code

Dictionary是表示鍵值對存儲庫的抽象類。已被Map完全取代,不推薦使用。
Hashtable原本是Dictionary的具體實現,隨著集合的出現Hashtable被重新設計並實現了Map接口。Hashtable與HashMap的主要區別是Hashtable是線程安全的,兩者的底層均是數組+鏈表實現,填充率均為0.75,但Hashtable不直接支持叠代器。

技術分享圖片
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

class Solution {
    public static void main(String[] args) {
        Hashtable<String, Integer> table = new Hashtable<>();
        table.put("A", 1);
        table.put("C", 2);
        table.put("B", 4);
        table.put("E", 3);
        table.put("D", 5);
        Set<String> set = table.keySet();
        Iterator<String> itr = table.keySet().iterator();
        while (itr.hasNext())
            System.out.println(itr.next());
    }
}
View Code

Properties是Hashtable的子類,用於保存值的列表。Properties可以指定默認屬性。如果沒有值與特定鍵關聯,就會返回默認屬性。

技術分享圖片
import java.util.Properties;

class Solution {
    public static void main(String[] args) {
        Properties p = new Properties();
        p.put("A", "1");
        p.put("B", "2");
        p.put("C", "3");
        System.out.println(p.getProperty("E", "-1"));//-1
    }
}
View Code

使用store方法和load方法可以將Properties存儲到磁盤以及從磁盤中加載。

技術分享圖片
import java.io.*;
import java.util.Properties;

class Solution {
    public static void main(String[] args) throws IOException {
        Properties information = new Properties();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String name, number;
        FileInputStream fin = null;
        try {
            fin = new FileInputStream("file.txt");
        } catch (FileNotFoundException exc) {
            System.out.println("File not found");
        }
        try {
            if (fin != null) {
                information.load(fin);//載入信息
                fin.close();
            }
        } catch (IOException exc) {
            System.out.println("Error reading file");
        }
        name = reader.readLine();
        number = reader.readLine();
        information.put(name, number);
        FileOutputStream fout = new FileOutputStream("file.txt");
        information.store(fout, "Information");//存儲信息
        fout.close();
    }
}
View Code

Java筆記:集合框架