Java筆記:集合框架
阿新 • • 發佈:2018-02-25
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) { ArrayListView Code<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); } }
鏈表。
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);View Code//插入尾元素 for (int i = 100; i < 200; i++) list.push(i);//插入首元素 list.removeFirst();//刪除首元素 list.removeLast();//刪除尾元素 System.out.println(list); } }
哈希集。
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筆記:集合框架