[关闭]
@CLSChen 2019-09-22T11:34:02.000000Z 字数 24793 阅读 1358

Java进阶

Java 编程


第19章 泛型

Java泛型详解:https://www.cnblogs.com/coprince/p/8603492.html

  1. Generic<T> //泛型类
  2. T //泛型类型参数

使用泛型可以提前检测出错误

  1. List arrayList = new ArrayList();
  2. arrayList.add("aaaa");
  3. arrayList.add(100);
  4. for(int i = 0; i< arrayList.size();i++){
  5. String item = (String)arrayList.get(i);
  6. Log.d("泛型测试","item = " + item);
  7. }
  8. // 运行结果
  9. java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  10. 在运行的时候检测出来,不可以将Integer类转换成String,报错。
  1. List arrayList<String>= new ArrayList<>();
  2. arrayList.add("aaaa");
  3. arrayList.add(100);
  4. // 编辑器报错,不可以向其中添加Integer。

  1. ArrayList<Integer> intList = new ArratList<>();
  2. intList.add(100);// 可以直接用100,而不用new Integer(100)

泛型使用[类型消除]

  1. // 未给ArrayList声明对象类型
  2. ArrayList dates = new ArrayList();
  3. dates.add(new Date());
  4. // 因此要进行强制类型转换
  5. Date date1 = (Date)dates.get(0);
  1. // 声明ArrayList泛型的对象为Date,ArrayList知道自己储存的是Date对象。
  2. ArrayList<Date> dates = new ArrayList<>();
  3. dates.add(new Date());
  4. // 可以直接读取
  5. Date date1 = dates.get(0);
  1. ArrayList<String> list1 = new ArrayList<>;
  2. ArrayList<Integer> list2 = new ArrayList<>;
  1. list1 instanceof ArrayList;
  2. list2 instanceof ArrayList;
  1. list1 instanceof ArrayList<String>;
  1. // 不能使用[泛型类型参数]创建对象和数组
  2. E test = new E();
  3. E[] testarray = new E[5];
  4. // 可以使用强制类型转换配合object类来做,但是仍然会有警告。
  5. E[] testarray = (E[])new object[5];
  6. ---
  7. // 使用[泛型类]创建对象是可以的
  8. ArrayList<String> test = new ArrayList<String>;
  9. // 但是使用[泛型类]创建数组也是不允许的
  10. ArrayList<String>[] testarray = new ArrayList<String>[];
  11. // 同样也可以使用强制类型转换,但是也会有警告
  12. ArrayList<String>[] testarray = (ArrayList<String>[])new ArrayList<String>[];
  13. ---
  14. // 静态方法和异常类不能是泛型的。

泛型通配符


泛型类的声明和构造方法

  1. // 泛型类定义
  2. class Generic<T>{
  3. // 构造方法
  4. public Generic();
  5. }
  6. // 创造类实例
  7. new Generic<String>

泛型方法的声明

  1. public static <T> void print(E[] list){};
  1. public class GenericTest {
  2. //这个类是个泛型类,在上面已经介绍过
  3. public class Generic<T>{
  4. private T key;
  5. public Generic(T key) {
  6. this.key = key;
  7. }
  8. //我想说的其实是这个,虽然在方法中使用了泛型,但是这并不是一个泛型方法。
  9. //这只是类中一个普通的成员方法,只不过他的返回值是在声明泛型类已经声明过的泛型。
  10. //所以在这个方法中才可以继续使用 T 这个泛型。
  11. public T getKey(){
  12. return key;
  13. }
  14. /**
  15. * 这才是一个真正的泛型方法。
  16. * 首先在public与返回值之间的<T>必不可少,这表明这是一个泛型方法,并且声明了一个泛型T
  17. * 这个T可以出现在这个泛型方法的任意位置.
  18. * 泛型的数量也可以为任意多个
  19. * 如:public <T,K> K showKeyName(Generic<T> container){
  20. * ...
  21. * }
  22. */
  23. public <T> T showKeyName(Generic<T> container){
  24. System.out.println("container key :" + container.getKey());
  25. T test = container.getKey();
  26. return test;
  27. }
  28. /**
  29. * 这个方法是有问题的,编译器会为我们提示错误信息:"UnKnown class 'E' "
  30. * 虽然我们声明了<T>,也表明了这是一个可以处理泛型的类型的泛型方法。
  31. * 但是只声明了泛型类型T,并未声明泛型类型E,因此编译器并不知道该如何处理E这个类型。*/
  32. public <T> T showKeyName(Generic<E> container){
  33. ...
  34. }
  35. /**
  36. * 这个方法也是有问题的,编译器会为我们提示错误信息:"UnKnown class 'T' "
  37. * 对于编译器来说T这个类型并未项目中声明过,因此编译也不知道该如何编译这个类。
  38. * 所以这也不是一个正确的泛型方法声明。*/
  39. public void showkey(T genericObj){
  40. }
  41. }

泛型方法不受类的限制

  1. public class GenericFruit {
  2. class Fruit{
  3. @Override
  4. public String toString() {
  5. return "fruit";
  6. }
  7. }
  8. class Apple extends Fruit{
  9. @Override
  10. public String toString() {
  11. return "apple";
  12. }
  13. }
  14. class Person{
  15. @Override
  16. public String toString() {
  17. return "Person";
  18. }
  19. }
  20. class GenerateTest<T>{
  21. public void show_1(T t){
  22. System.out.println(t.toString());
  23. }
  24. //在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。可以类型与T相同,也可以不同。
  25. //由于泛型方法在声明的时候会声明泛型<E>,因此即使在泛型类中并未声明泛型,编译器也能够正确识别泛型方法中识别的泛型。
  26. public <E> void show_3(E t){
  27. System.out.println(t.toString());
  28. }
  29. //在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。
  30. public <T> void show_2(T t){
  31. System.out.println(t.toString());
  32. }
  33. }
  34. public static void main(String[] args) {
  35. Apple apple = new Apple();
  36. Person person = new Person();
  37. GenerateTest<Fruit> generateTest = new GenerateTest<Fruit>();
  38. //apple是Fruit的子类,所以这里可以
  39. generateTest.show_1(apple);
  40. //编译器会报错,因为泛型类型实参指定的是Fruit,而传入的实参类是Person
  41. //generateTest.show_1(person);
  42. //使用这两个方法都可以成功
  43. generateTest.show_2(apple);
  44. generateTest.show_2(person);
  45. //使用这两个方法也都可以成功
  46. generateTest.show_3(apple);
  47. generateTest.show_3(person);
  48. }
  49. }

静态方法直接声明为泛型方法

  1. public static <T> void print(T t){}
  2. // 注意static位置在<T>前

受限泛型类型

  1. Public static <T extends Generic> void print(T t){}

示例:对一个对象数组进行排序。

  1. package chapter19;
  2. public class GenericSort {
  3. public static void main(String[] args) {
  4. // Create an Integer array
  5. Integer[] intArray = { new Integer(2), new Integer(4), new Integer(3) };
  6. // Create a Double array
  7. Double[] doubleArray = { new Double(3.4), new Double(1.3), new Double(-22.1) };
  8. // Create a Character array
  9. Character[] charArray = { new Character('a'), new Character('J'), new Character('r') };
  10. // Create a String array
  11. String[] stringArray = { "Tom", "Susan", "Kim" };
  12. // Sort the arrays
  13. sort(intArray);
  14. sort(doubleArray);
  15. sort(charArray);
  16. sort(stringArray);
  17. // Display the sorted arrays
  18. System.out.print("Sorted Integer objects: ");
  19. printList(intArray);
  20. System.out.print("Sorted Double objects: ");
  21. printList(doubleArray);
  22. System.out.print("Sorted Character objects: ");
  23. printList(charArray);
  24. System.out.print("Sorted String objects: ");
  25. printList(stringArray);
  26. }
  27. /** Sort an array of comparable objects */
  28. public static <E extends Comparable<E>> void sort(E[] list) {
  29. E currentMin;
  30. int currentMinIndex;
  31. for (int i = 0; i < list.length - 1; i++) {
  32. // Find the minimum in the list[i..list.length-1]
  33. currentMin = list[i];
  34. currentMinIndex = i;
  35. for (int j = i + 1; j < list.length; j++) {
  36. if (currentMin.compareTo(list[j]) > 0) {
  37. currentMin = list[j];
  38. currentMinIndex = j;
  39. }
  40. }
  41. // Swap list[i] with list[currentMinIndex] if necessary;
  42. if (currentMinIndex != i) {
  43. list[currentMinIndex] = list[i];
  44. list[i] = currentMin;
  45. }
  46. }
  47. }
  48. /** Print an array of objects */
  49. public static void printList(Object[] list) {
  50. for (int i = 0; i < list.length; i++)
  51. System.out.print(list[i] + " ");
  52. System.out.println();
  53. }
  54. }

通配泛型

  1. // 非受限通配
  2. <?>
  3. // 受限通配
  4. <? extends SuperClass>
  5. // 下限通配
  6. <? super T>

第20章 线性表List、栈Stack、队列Queue和优先队列Priority Queue

接口->抽象类->具体类

迭代器 Iterator<E>

  1. // 创建一个列表alist
  2. ArrayList<String> alist = new ArrayList<String>();
  3. alist.add("new york")
  4. alist.add("new york2")
  5. // 为alist生成一个迭代器
  6. Iterator<String> alistRator = alist.iterator();
  7. // 使用迭代器来访问列表
  8. while(alistRator.hasNext()){
  9. System.out.println("iterator.next().toUpperCase()" + " ");
  10. }
  11. //输出:new york new york2
foreach可以用于Iterator的任何实例。
  1. ArrayList<String> alist = new ArrayList<String>();
  2. alist.add("new york")
  3. alist.add("new york2")
  4. for(String a:alist){
  5. System.out.println("a.toUpperCase()" + " ");
  6. }

线性表 List接口

List接口中的通用方法

数组线性表类ArrayList和链表类LinkedList

微信截图_20190418153729.jpg-84.4kB

微信截图_20190418154125.jpg-118.2kB

  1. // 非常低效
  2. for (int i = 0; i < list.size(); i++){
  3. a = get(i);
  4. }
  5. // 高效
  6. for(int i : list){
  7. a = i;
  8. }

Comparator接口(不是comparable!)

  1. // 如果前面的小于后面的,返回一个负值,相等为0,大于为正值。
  2. public int compare(T element1, T element2)
  1. // 注意,该方法实现了Serializable接口来进行序列化,在实现comparator接口的地方最好都在后面跟上Serializable接口。
  2. public class Geocom
  3. implements Comparator<GeometricObject>, java.io.Serializable{
  4. public int compare(GeometricObject o1, GeometricObject o2){
  5. double area1 = o1.getArea();
  6. double area2 = o2.getArea();
  7. if(area1 > area2)
  8. return 1;
  9. else if(area1 < area2)
  10. return 0;
  11. else
  12. }
  13. }

线性表和合集的静态方法

微信截图_20190419144926.jpg-248.9kB

  1. // 使用Arrays的静态asList方法来方便的创建列表
  2. List<String> list = Arrays.asList("red","green","blue");
  3. // 使用sort静态方法来排序
  4. Collections.sort(list);
  5. // 使用重载的sort方法来调用reverseOrder比较器来倒序排序
  6. Collections.sort(list, Collections.reverseOrder);
  1. List<String> list1 = Arrays.asList("red","green","blue");
  2. List<String> list2 = Arrays.asList("yellow");
  3. Collections.copy(list1,list2);
  4. // list1 : yellow green blue

向量类Vector和栈类Stack

微信截图_20190421142422.jpg-249.2kB

微信截图_20190421143257.jpg-100.3kB


队列Queue和优先队列

双端队列接口Deque和链表类LinkedList

2.jpg-88.4kB

  1. import java.util.*;
  2. public class PriorityQueueDemo {
  3. public static void main(String[] args) {
  4. PriorityQueue<String> queue1 = new PriorityQueue<>();
  5. queue1.offer("Oklahoma");
  6. queue1.offer("Indiana");
  7. queue1.offer("Georgia");
  8. queue1.offer("Texas");
  9. System.out.println("Priority queue using Comparable:");
  10. while (queue1.size() > 0) {
  11. System.out.print(queue1.remove() + " ");
  12. }
  13. PriorityQueue<String> queue2 = new PriorityQueue<>(4, Collections.reverseOrder());
  14. queue2.offer("Oklahoma");
  15. queue2.offer("Indiana");
  16. queue2.offer("Georgia");
  17. queue2.offer("Texas");
  18. System.out.println("\nPriority queue using Comparator:");
  19. while (queue2.size() > 0) {
  20. System.out.print(queue2.remove() + " ");
  21. }
  22. }
  23. }
  24. //输出结果:
  25. > Priority queue using Comparable:
  26. > Georgia Indiana Oklahoma Texas
  27. > Priority queue using Comparator:
  28. > Texas Oklahoma Indiana Georgia

第21章 集合(set)和映射表(map)


集合

image.png-752.2kB


HashSet哈希集合 负载系数

  1. Set<String> hashSet = new HashSet<>();
  2. // 等价于
  3. Set<String> hashSet = new HashSet<>(16, 0.75);

LinedSet、TreeSet

image.png-1133.8kB

  1. Ser<GeometricObject> set = new TreeSet<>(new GeoComparator);

映射表(Map)

image.png-694.4kB
TIM图片20190503162623.png-382.4kB


HashMap哈希表、LinkedHashMap、TreeMap

  1. // 默认按插入顺序排序
  2. Map<String,Integer> linkmap = new LinkedHashMap<>();
  3. // 按照访问顺序排序(最后访问的在最后面)
  4. Map<String,Integer> linkmap = new LinkedHashMap<>(16, 0.75, true);
  1. Map<String, Integer> tmap = new TreeMap<>();
  2. Map<String, Integer> tmap = new TreeMap<>(new Comparator);

image.png-615.6kB


单元素与不可变的合集和映射表

image.png-530.7kB

第22章 开发高效算法

时间复杂度


image.png-363.6kB


动态编程思想

  1. public static int fib(int n){
  2. if(n == 0)
  3. return 0;
  4. else if (n <= 2)
  5. return 1;
  6. else
  7. return fib(n - 1) + fib(n - 2);
  8. }
  1. public static int fib(int n){
  2. int f0 = 0;
  3. int f1 = 1;
  4. int f2 = 1;
  5. if(n == 0)
  6. return 0;
  7. else if (n <= 2)
  8. return 1;
  9. for(int i = 3; i < n; i++){
  10. f0 = f1;
  11. f1 = f2;
  12. f2 = f0 + f1;
  13. }
  14. }
  1. public static int fib(int n, int ppre, int pre){
  2. if(n <= 1)
  3. return ppre;
  4. else
  5. return fib(int n - 1, int pre, int ppre + pre);
  6. }
  7. main{
  8. fib(5, 1, 1);
  9. }

使用欧几里得算法求解最大公约数。

  1. gcd(m, n)表示求mn的最大公约数。
  2. 如果m % n=0,那么gcd(m, n)为n
  3. 否则,gcd(m, n)就是gcd(n, m % n)。
  4. // 时间复杂度为O(logn)
  5. public static int gcd(int m, int n){
  6. if(m % n == 0)
  7. return n;
  8. else
  9. return gcd(n, m % n);
  10. }

for循环的小技巧

  1. // 计算很多次
  2. for(int i = 0; i < (int)math.sqrt(number); i++)
  3. // 整个for循环只计算一次
  4. int sqrtnum = (int)math.sqrt(number);
  5. for(int i = 0; i < sqrtnum; i++)

排序


插入排序 InsertionSort O(n^2)

  1. public static void main(String[] args) {
  2. int[] a = {1, 3, 5, 7, 24, 73, 72, 2};
  3. int[] b = new int[8];// b数组的大小要和a一样。
  4. int cur = 0;
  5. for (int i = 0; i < a.length; i++) {
  6. cur = a[i];
  7. int j;
  8. // important
  9. for (j = i; j > 0 && b[j - 1] > cur; j--) { // 4
  10. b[j] = b[j - 1];
  11. }
  12. b[j] = cur; // 5
  13. }
  14. for (int x : b) {
  15. System.out.print(x + " ");
  16. }
  17. }
  1. // 注意,这段代码的精妙之处就在于不需要创建子数组。
  2. public static void insertionSort(int[] list){
  3. for (int i = 0; i < list.length; i++) {
  4. int cur = list[i];
  5. int j;
  6. // 注意,当i == j == 0时,for循环并不会执行,但是j = i仍然会发生,结果就是将第一个插入元素直接插入第一位。而这里并没有新数组,因此就是将list[0]的值赋给list[0]的无意义操作。
  7. for (j = i; j > 0 && list[j - 1] > cur; j--) {
  8. list[j] = list[j - 1];
  9. }
  10. list[j] = cur;
  11. }
  12. for (int x:list
  13. ) {
  14. System.out.print(x + " ");
  15. }
  16. }
  17. public static void main(String[] args) {
  18. int[] a = {1, 3, 5, 7, 24, 73, 72, 2};
  19. insertionSort(a);
  20. }

冒泡排序 BubbleSort O(n^2)

  1. public class BubbleSort {
  2. public static void main(String[] args) {
  3. int[] a = {6, 5, 7, 2, 9, 1, 0};
  4. boolean b = true;
  5. // 如果上次仍有排序,则继续循环,设置排序序号为false
  6. for (int j = 0; j < a.length && b; j++) {
  7. b = false;
  8. //注意每次循环次数减一
  9. for (int i = 1; i < a.length - j; i++) {
  10. if (a[i - 1] > a[i]) {
  11. // 交换元素
  12. int temp = a[i];
  13. a[i] = a[i - 1];
  14. a[i - 1] = temp;
  15. // 若本次仍存在冒泡,则继续大循环。
  16. // 否则默认终止循环。
  17. b = true;
  18. }
  19. }
  20. }
  21. for (int x : a) {
  22. System.out.print(x + " ");
  23. }
  24. }
  25. }

在最佳情况下,冒泡排序的时间为O(n),即一次全部冒泡成功。
最差情况为每次都要冒泡,为O(n^2)。


归并排序(MergeSort)O(nlogn)

微信截图_20190508193832.jpg-287.1kB

  1. import java.util.Arrays;
  2. public class MergeSort {
  3. public static void main(String[] args) {
  4. int[] a = {1, 3, 5, 2, 8};
  5. mergeSort(a);
  6. for (int x : a) {
  7. System.out.print(x + " ");
  8. }
  9. }
  10. public static void mergeSort(int[] list) {
  11. if (list.length > 1) { // 递归结束条件
  12. int[] firstHalf = new int[list.length / 2];
  13. int[] secondHalf = new int[list.length - firstHalf.length];
  14. // System里的数组复制方法,注意复制后半部分的时候,要从firstHalf.length开始复制(第二个参数),长度是secondHalf.length(最后一个参数)。
  15. System.arraycopy(list, 0, firstHalf, 0, firstHalf.length);
  16. System.arraycopy(list, firstHalf.length, secondHalf, 0, secondHalf.length);
  17. mergeSort(firstHalf);
  18. mergeSort(secondHalf);
  19. merge(firstHalf, secondHalf, list);
  20. }
  21. }
  22. public static void merge(int[] list1, int[] list2, int[] temp) {
  23. int index1 = 0;
  24. int index2 = 0;
  25. int index3 = 0;
  26. // 选取两个数组中较小的数放入最终数组,并在某个数组被读取完后停止。
  27. while (index1 < list1.length && index2 < list2.length) {
  28. if (list1[index1] < list2[index2])
  29. temp[index3++] = list1[index1++];
  30. else
  31. temp[index3++] = list2[index2++];
  32. }
  33. // 将剩下的数直接复制进最终数组。
  34. while (index1 < list1.length) {
  35. temp[index3++] = list1[index1++];
  36. }
  37. while (index2 < list2.length) {
  38. temp[index3++] = list2[index2++];
  39. }
  40. }
  41. }

快速排序

  1. package demo2;
  2. public class QuickSort {
  3. public static void quickSort(int[] list) {
  4. quickSort(list, 0, list.length - 1);
  5. }
  6. public static void quickSort(int[] list, int first, int last) {
  7. // 对于每个快速排序,last必须大于first,如果last=-1,就结束递归。
  8. if (last > first) {
  9. // 返回主元的位置,然后通过主元分割前后两端,并依次进行快速排序。
  10. int indexOfPivot = partition(list, first, last);
  11. quickSort(list, first, indexOfPivot - 1);
  12. quickSort(list, indexOfPivot + 1, last);
  13. }
  14. }
  15. // 返回主元的正确位置,并交换处于不正确位置的元素,使得主元的前面都小于主元,后面都大于主元。
  16. public static int partition(int[] list, int first, int last) {
  17. int pivot = list[first];
  18. int start = first++;
  19. int temp = 0;
  20. while (first < last) {
  21. // 当发现前后两个特例之后,将他们交换。
  22. // 如果只有小数列有特例,那么last会一直往前,越过大数列,停在小数列的最后一个位置。
  23. // 这种情况大数列本身就是排好序的,因此将小数列中的特例与小数列的最后一位交换。
  24. while (first < last && list[first] < pivot)
  25. first++;
  26. while (first < last && list[last] > pivot)
  27. last--;
  28. if (first < last) {
  29. temp = list[last];
  30. list[last] = list[first];
  31. list[first] = temp;
  32. }
  33. }
  34. // last的数小于等于pivot时停下。相当于将last放置在小数列的最后一个位置上,即大数列的第一个之前的那个位置。
  35. while (list[last] > pivot) {
  36. last--;
  37. }
  38. // 然后将last的数和第一个数(pivot)交换。
  39. list[start] = list[last];
  40. list[last] = pivot;
  41. // 返回last现在所在的位置,也就是主元现在的位置。
  42. return last;
  43. }
  44. public static void main(String[] args) {
  45. int[] a = {5, 2, 9, 3, 8, 4, 0, 1, 6, 7};
  46. quickSort(a);
  47. for (int x : a) {
  48. System.out.print(x + " ");
  49. }
  50. }
  51. }

堆排序 (HeapSort) O(nlogn)

  1. package demo2;
  2. public class Heap<E extends Comparable<E>> {
  3. private java.util.ArrayList<E> list = new java.util.ArrayList<>();
  4. public Heap() {
  5. }
  6. public Heap(E[] objects) {
  7. for (int i = 0; i < objects.length; i++) {
  8. add(objects[i]);
  9. }
  10. }
  11. public void add(E newObject) {
  12. list.add(newObject);
  13. int cur = list.size() - 1;
  14. while (cur > 0) {
  15. int par = (cur - 1) / 2;
  16. if (list.get(par).compareTo(list.get(cur)) < 0) {
  17. E temp = list.get(cur);
  18. list.set(cur, list.get(par));
  19. list.set(par, temp);
  20. } else
  21. break;
  22. // change par to cur.
  23. cur = par;
  24. }
  25. }
  26. public E remove() {
  27. if (list.size() == 0) return null;
  28. E removeObject = list.get(0);
  29. list.set(0, list.get(list.size() - 1));
  30. list.remove(list.size() - 1);
  31. int cur = 0;
  32. while (cur < list.size()) {
  33. int son1 = cur * 2 + 1;
  34. int son2 = cur * 2 + 2;
  35. // 左子节点要严格小于list才不会越界
  36. if (son1 >= list.size()) break;
  37. // 找到两个子节点中比较大的
  38. int max = son1;
  39. if (son2 < list.size()) {
  40. if (list.get(son1).compareTo(list.get(son2)) > 0)
  41. max = son1;
  42. else
  43. max = son2;
  44. }
  45. if (list.get(cur).compareTo(list.get(max)) < 0) {
  46. E temp = list.get(cur);
  47. list.set(cur, list.get(max));
  48. list.set(max, temp);
  49. cur = max;
  50. } else
  51. break;
  52. }
  53. return removeObject;
  54. }
  55. public int getSize() {
  56. return list.size();
  57. }
  58. }
  1. package demo2;
  2. public class HeapSort {
  3. public static <E extends Comparable<E>> void heapSort(E[] list) {
  4. // 通过list新建堆
  5. Heap<E> a = new Heap<>(list);
  6. // 注意,remove出来的是堆中最大的元素,因此要从后面开始遍历。
  7. for (int i = list.length - 1; i >= 0; i--) {
  8. list[i] = a.remove();
  9. }
  10. }
  11. public static void main(String[] args) {
  12. Integer[] a = {5, 2, 9, 3, 8, 4, 0, 1, 6, 7};
  13. heapSort(a);
  14. for (Integer x : a
  15. ) {
  16. System.out.print(x + " ");
  17. }
  18. }
  19. }

第24章 实现线性表、栈、队列和优先队列

线性表的通用特性

image.png-133.9kB
image.png-1424.4kB

数组线性表

image.png-483.8kB

栈和队列

优先队列

第25章 二叉搜索树

第26章 AVL树 平衡二叉搜索树

第27章 散列

散列码

反射

廖雪峰的官方网站:https://www.liaoxuefeng.com/wiki/1252599548343744/1264799402020448

第30章 多线程和并行程序设计

创建单个线程以及Thread类的一些方法

image.png-633.6kB

  1. TaskClass task = new TaskClass();// TaskClass类实现了Runnable接口
  2. Thread thread = new Thread(task);// 通过TaskClass创建一个线程
  3. thread.start();// 启动它
  1. MyThread mythread = new MyThread();// Myshread类继承了Thread类
  2. mythread.start();// 直接启动子类就好
  1. new Thread(new Runnable(){}).start();
  2. // 填充run()方法
  3. new Thread(new Runnable(){
  4. @Override
  5. public void run(){
  6. System.out.println("nihao");
  7. }
  8. }).start();
  9. // 可以使用Lambda表达式进一步简化,将new Runnable(){} 变成()-> {}
  10. // 并且不用写run()的方法头!
  11. new Thread(()->{
  12. System.out.println("nihao");
  13. }).start();

线程池 Executor接口以及Executors方法

image.png-1035.8kB

  1. ExecutorService executor = Executors.newFixedThreadPool(3);
  2. // 如果设置为1,那么三个线程将串行执行。
  3. // 如果是newCachedThreadPool(),所有任务都并发执行。
  4. executor.execute(new PrintChar('a', 100));// +execute(Runnable object):void
  5. executor.execute(new PrintChar('b', 100));
  6. executor.execute(new PrintNum(100));
  7. executor.shutdown();

线程同步 synchronized关键字

  1. synchronized(expr){ // expr必须是一个对象的引用
  2. //...
  3. }
  4. synchronized(account){
  5. account.toString();
  6. }
  7. synchronized后面的括号中填上this,就可以锁定当前对象或者当前类。

显式加锁 Lock接口

image.png-669.1kB

  1. private static Lock lock = new ReentrantLock();
  2. lock.lock();
  3. try{
  4. }catch{
  5. }finally{
  6. lock.unlock();
  7. }
  8. 尽量把锁的释放放在finally里,这样可以确保锁被释放。

image.png-327.5kB

  1. private static Lock lock = new ReentrantLock();
  2. private static Condition newDeposit = lock.newCondition();

image.png-346.9kB

image.png-308.8kB

监视器

image.png-360.6kB

信号量

image.png-449kB

image.png-855kB

死锁

image.png-291.1kB

线程状态

image.png-706.7kB

同步合集

image.png-847.1kB

image.png-165.9kB

并行编程

https://www.cnblogs.com/cjsblog/p/9078341.html

image.png-960.8kB

image.png-382.6kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注