1、泛型

1.1 泛型类

定义格式
    修饰符 class 类名<类型> { }

1.2 泛型方法

定义格式
修饰符 <类型> 返回值类型 方法名(类型 变量名) { }

1.3 泛型接口

定义格式
    修饰符 interface 接口名<类型> {  }

1.4类型通配符

类型通配符: <?>
	ArrayList<?>: 表示元素类型未知的ArrayList,它的元素可以匹配任何的类型,但是并不能把元素添加到ArrayList中了,获取出来的也是父类类型

类型通配符上限: <? extends 类型>
	ArrayListList <? extends Number>: 它表示的类型是Number或者其子类型

类型通配符下限: <? super 类型>
	ArrayListList <? super Number>: 它表示的类型是Number或者其父类型

2、比较器

comparator 自然排序

  1. 使用空参构造创建TreeSet集合
  • 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
  1. 自定义的类实现Comparable接口
  • 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
  1. 重写接口中的compareTo方法
  • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
  1. TreeSet():根据其元素的自然排序进行排序

comparator比较器排序

  1. 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
  2. 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
  3. 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

两种比较方式总结

  • 两种比较方式小结
  1. 自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
  2. 比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
  3. 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序
  • 两种方式中关于返回值的规则
  • 如果返回值为负数,表示当前存入的元素是较小值,存左边
  • 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
  • 如果返回值为正数,表示当前存入的元素是较大值,存右边

3、数据结构

3.1二叉树

二叉树的特点

二叉树中,任意一个节点的度要小于等于2
	节点: 在树结构中,每一个元素称之为节点
	度: 每一个节点的子节点数量称之为度

3.2二叉查找树

二叉查找树的特点

  1. 二叉查找树,又称二叉排序树或者二叉搜索树
  2. 每一个节点上最多有两个子节点
  3. 左子树上所有节点的值都小于根节点的值
  4. 右子树上所有节点的值都大于根节点的值

二叉查找树添加节点规则

  1. 小的存左边
  2. 大的存右边
  3. 一样的不存

3.3平衡二叉树

平衡二叉树的特点

  1. 二叉树左右两个子树的高度差不超过1
  2. 任意节点的左右两个子树都是一颗平衡二叉树

平衡二叉树旋转

旋转触发时机
	当添加一个节点之后,该树不再是一颗平衡二叉树
  • 左旋
  • 就是将根节点的右侧往左拉,原先的右子节点变成新的父节点,并把多余的左子节点出让,给已经降级的根节点当右子节点
  • 右旋
  • 就是将根节点的左侧往右拉,左子节点变成了新的父节点,并把多余的右子节点出让,给已经降级根节点当左子节点

平衡二叉树旋转的四种情况

  • 左左
  • 左左: 当根节点左子树的左子树有节点插入,导致二叉树不平衡
  • 如何旋转: 直接对整体进行右旋即可
  • 左右
  • 左右: 当根节点左子树的右子树有节点插入,导致二叉树不平衡
  • 如何旋转: 先在左子树对应的节点位置进行左旋,在对整体进行右旋
  • 右右
  • 右右: 当根节点右子树的右子树有节点插入,导致二叉树不平衡
  • 如何旋转: 直接对整体进行左旋即可
  • 右左
  • 右左:当根节点右子树的左子树有节点插入,导致二叉树不平衡
  • 如何旋转: 先在右子树对应的节点位置进行右旋,在对整体进行左旋

3.4红黑树

红黑树的特点

1、平衡二叉B树
2、每一个节点可以是红或者黑
3、红黑树不是高度平衡的,它的平衡是通过"自己的红黑规则"进行实现的

红黑树的红黑规则有哪些

1、每一个节点或是红色的,或者是黑色的
2、根节点必须是黑色
3、如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为Nil,这些Nil视为叶节点,每个叶节点(Nil)是黑色的
4、如果某一个节点是红色,那么它的子节点必须是黑色(不能出现两个红色节点相连 的情况)
5、对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点

红黑树添加节点的默认颜色

添加节点时,默认为红色,效率高

java 去掉头和尾 java去尾法_开发语言

红黑树添加节点后如何保持红黑规则

  • 根节点位置
  • 直接变为黑色
  • 非根节点位置
  • 父节点为黑色
  • 不需要任何操作,默认红色即可
  • 父节点为红色
  • 叔叔节点为红色
  • 将"父节点"设为黑色,将"叔叔节点"设为黑色
  • 将"祖父节点"设为红色
  • 如果"祖父节点"为根节点,则将根节点再次变成黑色
  • 叔叔节点为黑色
  • 将"父节点"设为黑色
  • 将"祖父节点"设为红色
  • 以"祖父节点"为支点进行旋转

4、集合

java 去掉头和尾 java去尾法_开发语言_02

Collection

List 存取有序,可以重复,有索引

ArrayList
底层是数组结构实现,查询快、增删慢
LinkedList
底层是链表结构实现,查询慢、增删快

Set 不可以存储重复元素,没有索引,不能使用普通for循环遍历

HashSet
底层数据结构是哈希表,存取无序,不可以存储重复元素,没有索引,不能使用普通for循环遍历

哈希表结构

  • JDK1.8以前
    数组 + 链表
  1. 创建一个默认长度16,默认加载因子为0.75的数组,数组名为table
  2. 根据元素的哈希值跟数组的长度计算出应存入的位置
  3. 判断当前位置是否为null,如果是null直接存入
  4. 如果位置不为null,表示有元素,则调用equal方法比较属性值
  5. 如果一样,则不存,如果不一样,则存入数组,老元素挂在新元素下面
  • JDK1.8以后
节点个数少于等于8个
 		数组 + 链表
 节点个数多于8个
 		数组 + 红黑树

java 去掉头和尾 java去尾法_数组_03


HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法

TreeSet
不可以存储重复元素,没有索引,可以将元素按照规则进行排序

构造器

  • TreeSet():根据其元素的自然排序进行排序
  • TreeSet(Comparator comparator) :根据指定的比较器进行排序

自然排序Comparable的使用

  1. 使用空参构造创建TreeSet集合
    用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
  2. 自定义的实体类实现Comparable接口
    自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
  3. 重写接口中的compareTo方法
    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
实例代码
								public class Student implements Comparable<Student>{
									 @Override
								    public int compareTo(Student o) {
								        //按照对象的年龄进行排序
								        //主要判断条件: 按照年龄从小到大排序
								        int result = this.age - o.age;
								        //次要判断条件: 年龄相同时,按照姓名的字母顺序排序
								        result = result == 0 ? this.name.compareTo(o.getName()) : result;
								        return result;
								    }
								}

								 //创建集合对象
        						TreeSet<Student> ts = new TreeSet<>();
        						ts.add(ew Student("zhangsan",28));
        						//遍历集合
						        for (Student student : ts) {
						            System.out.println(student);
						        }

比较器排序Comparator的使用

  1. 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
  2. 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
  3. 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
实例代码
 								 TreeSet<Teacher> ts = new TreeSet<>(new Comparator<Teacher>() {
						            @Override
						            public int compare(Teacher o1, Teacher o2) {
						                //o1表示现在要存入的那个元素
						                //o2表示已经存入到集合中的元素
						              
						                //主要条件
						                int result = o1.getAge() - o2.getAge();
						                //次要条件
						                result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
						                return result;
						            }
						        });

Map集合

Map集合的特点

  • 双列集合,一个键对应一个值
  • 键不可以重复,值可以重复

遍历方式

获取所有键的集合。用keySet()方法实现
    Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
HashMap

HashMap集合概述和特点

  • HashMap底层是哈希表结构的
  • 依赖hashCode方法和equals方法保证键的唯一
  • 如果键要存储的是自定义对象,需要重写hashCode和equals方法

TreeMap

TreeMap集合概述和特点

  • TreeMap底层是红黑树结构
  • 依赖自然排序或者比较器排序,对键进行排序
  • 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则

5、数组高级操作

二分查找

二分查找概述
二分查找也叫折半查找,每次可以去掉一半的查找范围,从而提高查找的效率
需求
在数组{1,2,3,4,5,6,7,8,9,10}中,查找某个元素的位置
实现步骤
1. 定义两个变量,表示要查找的范围。默认min = 0 ,max = 最大索引
2. 循环查找,但是min <= max
3. 计算出mid的值
4. 判断mid位置的元素是否为要查找的元素,如果是直接返回对应索引
5. 如果要查找的值在mid的左半边,那么min值不变,max = mid -1.继续下次循环查找
6. 如果要查找的值在mid的右半边,那么max值不变,min = mid + 1.继续下次循环查找
7. 当min > max 时,表示要查找的元素在数组中不存在,返回-1
注意事项
有一个前提条件,数组内的元素一定要按照大小顺序排列,如果没有大小顺序,是不能使用二分查找法的

冒泡排序

冒泡排序概述
一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按要求完成排序
如果有n个数据进行排序,总共需要比较n-1次
每一次比较完毕,下一次的比较就会少一个数据参与

快速排序

快速排序概述
冒泡排序算法中,一次循环结束,就相当于确定了当前的最大值,也能确定最大值在数组中应存入的位置
快速排序算法中,每一次递归时以第一个数为基准数,找到数组中所有比基准数小的.再找到所有比基准数大的.小的全部放左边,大的全部放右边,确定基准数的正确位置
核心步骤
1. 从右开始找比基准数小的
2. 从左开始找比基准数大的
3. 交换两个值的位置
4. 红色继续往左找,蓝色继续往右找,直到两个箭头指向同一个索引为止
5. 基准数归位

代码实现

private static void quiteSort(int[] arr, int left, int right) {
		     	// 递归结束的条件
		        if(right < left){
		            return;
		        }

		        int left0 = left;
		        int right0 = right;

		        //计算出基准数
		        int baseNumber = arr[left0];

		        while(left != right){
					//1,从右开始找比基准数小的
		            while(arr[right] >= baseNumber && right > left){
		                right--;
		            }
					//2,从左开始找比基准数大的
		            while(arr[left] <= baseNumber && right > left){
		                left++;
		            }
					//3,交换两个值的位置
		            int temp = arr[left];
		            arr[left] = arr[right];
		            arr[right] = temp;
		        }
		        //基准数归位
		        int temp = arr[left];
		        arr[left] = arr[left0];
		        arr[left0] = temp;
		     
				// 递归调用自己,将左半部分排好序
		        quiteSort(arr,left0,left-1);
		      	// 递归调用自己,将右半部分排好序
		        quiteSort(arr,left +1,right0);
		    }

6、可变参数

可变参数定义格式

修饰符 返回值类型 方法名(数据类型… 变量名) {  }

7、Stream流

Stream流的三类方法

  • 获取Stream流
  • 创建一条流水线,并把数据放到流水线上准备进行操作
  • 中间方法
  • 流水线上的操作
  • 一次操作完毕之后,还可以继续进行其他操作
  • 终结方法
  • 一个Stream流只能有一个终结方法
  • 是流水线上的最后一个操作

生成Stream流的方式

  • Collection体系集合
  • 使用默认方法stream()生成流, default Stream stream()
  • Map体系集合
  • 把Map转成Set集合,间接的生成流
  • 数组
  • 通过Arrays中的静态方法stream生成流
  • 同种数据类型的多个数据
  • 通过Stream接口的静态方法of(T… values)生成流

中间操作方法

方法名

说明

Stream filter(Predicate predicate)

用于对流中的数据进行过滤

Stream limit(long maxSize)

返回此流中的元素组成的流,截取前指定参数个数的数据

Stream skip(long n)

跳过指定参数个数的数据,返回由该流的剩余元素组成的流

static Stream concat(Stream a, Stream b)

合并a和b两个流为一个流

Stream distinct()

返回由该流的不同元素(根据Object.equals(Object) )组成的流

终结操作方法

方法名

说明

void forEach(Consumer action)

对此流的每个元素执行操作

long count()

返回此流中的元素数

8、常用API

  • Math
  • System
  • Object
  • Objects
  • BigDecimal
  • 舍入模式
    BigDecimal.ROUND_UP 进一法
    BigDecimal.ROUND_FLOOR 去尾法
    BigDecimal.ROUND_HALF_UP 四舍五入
  • 常用方法

方法名

说明

public BigDecimal add(另一个BigDecimal对象)

加法

public BigDecimal subtract (另一个BigDecimal对象)

减法

public BigDecimal multiply (另一个BigDecimal对象)

乘法

public BigDecimal divide (另一个BigDecimal对象)

除法

public BigDecimal divide (另一个BigDecimal对象,精确几位,舍入模式)

除法

  • Arrays
  • Date
  • SimpleDateFormat
  • LocalDate 表示日期(年月日)
  • LocalTime 表示时间(时分秒)
  • LocalDateTime 表示时间+ 日期 (年月日时分秒)
  • Period 日期计算,适用于 LocalDate
  • Duration 时间计算,适用于 LocalDateTime
  • Optional 类对象管理工具
  • Optional概述
    可能包含或不包含非null值的容器对象
  • 方法介绍

方法名

说明

static Optional of(T value)

获取一个Optional对象,封装的是非null值的对象

static Optional ofNullable(T value)

获取一个Optional对象,Optional封装的值对象可以是null也可以不是null

T get()

如果存在值,返回值,否则抛出NoSuchElementException

boolean isPresent()

如果存在值,则返回true,否则为false

T orElse(T other)

如果不为空,则返回具体的值,否则返回参数中的值

T orElseGet(Supplier<? extends T> supplier)

如果不为空,则返回具体的值,否则返回由括号中函数产生的结果

void ifPresent (Consumer<? super T> action)

如果不为空,则使用该值执行给定的操作,否则不执行任何操作

void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

如果不为空,则使用该值执行给定的操作,否则执行给定的基于空的操作