java集合框架
collection和map
collection子类:
1.list 元素有序可重复
实现:arraylist类似动态数组,长度可变,默认10
不是线程安全的,可用vector代替
linkedlist.类似于双向链表.适合增删,不是线程安全的
arraylist,适用于查找
2.set 元素无序不可重复(根据hashcode确定位置)
实现:hashset,底层基于hashmap实现
linkedhashset.基于linkedhashmap实现,与hashset区别是增加了链式表结构
treeset:是一种二叉排序树
3.queue
实现:queue+list - > linkedlist
map
键值对形式,key不能重复,value允许为空
实现类:hashmap
线程安全的map:currenthashmap, 不仅线程安全而且效率高(底层红黑树查询效率较高)
数组和链表的区别
1.数组固定长度,容易浪费或不足,链表可以动态分配
2.数组是在栈中(除了new出来的)分配,方便但是自由度差,链表是在堆中分配,自由度大但是管理麻烦
3.数组用下标进行访问,速度快,链表必须从头访问,速度慢
4.链表适合增删
hashmap和hashtable的区别
1.hashmap是线程不安全的,hashtable是线程安全的
2.hashmap键,值都允许null存在,hashtable则不允许
3.线程原因,hashmap效率相对较高
hashmap的实现机制
1。维护一个每个元素都是一个链表的数组,链表中的每个节点是一个entry【】键值对的数组
2.实现了数组+链表的特性,所以增删查改都很快
3.每个新加入的节点放在链表首,然后该新加入的节点指向原链表首
4.对于每个key,对应的数组索引下标示int i = hash(key,hashcode)& (len - 1)
堆,栈,队列的区别
栈 用来存放局部变量,形参或者计算的中间结果,变量所处的作用域一旦结束就立即释放,先进后出
堆 用来存放数组和new的对象或者成员变量,凡是new出来的都存在堆中(新建对象),不自动回收,用户不能访问
队列 线性结构,先进先出(实现树的层次遍历)
string,stringbuffer和stringbuild区别
string每次操作字符串时都会生成新的对象
stringbuffer不会生成新对象,而且是线程安全的
stringbuilder是线程不安全的(推荐常用)
算法思想
1.贪心算法(局部最优解)
2.分治算法(将规模为n的问题分为k个小问题,每个问题相互独立且性质相同,求出小问题的解即得原问题的解)
3.动态规划算法(与分治法类似,前一问题为后一问题提供信息,根据可能的解保留最优解,丢弃其他局部解)
4.回溯算法(搜索尝试的过程,当不满足条件时回溯返回)
5.递归算法(对重复问题分解为子问题,有一个递归终止条件)
抽象类和接口的区别
1.继承方面:一个类只可以继承一个类,可以实现多个接口
2.抽象方法方面:接口中全是抽象方法,抽象类中即可以有抽象方法,又可以有方法体
3.构造方法方面:接口中无构造方法。抽象类中有构造方法
4.实例化方面:抽象类不可以被实例化,接口不可以被继承
5.修饰符方面:抽象类中方法可以用除了private以外的修饰符,接口中默认是public的
6.实现速度方面:抽象类比接口速度快
7.添加新方法时:抽象类不需要更改当前代码,但是接口需要更改实现该接口的类
object类的公用方法
1.equals判断是否相等
2.clone克隆对象
3.tostring
4.hashcode方法
5.线程同步的方法
6.getclass获取和当前类有关的信息
jdk1.8新特性
1.允许接口添加一个非抽象的方法实现,只需要使用default关键字即可
2.lambda表达式(允许把一个函数作为一个方法的参数传递进方法中)
4.Date time api加强对时间和日期的处理
5.optinal类,用来解决空指针异常
如何实现对树的层次遍历--->队列
链表(更改指针)
结构:数据域+下一个节点的指针域
作用:数据的存储按照一定的顺序存放,可以在任意节点增加,删除
类型:单向链表,双向链表,循环链表
优点:顺序结构,适合增删
缺点:有指针域,占用空间大;只知道头节点的地址,查找麻烦
1.链表反转:定义三个指针,分别记录当前遍历到的结点,它的前一个结点以及后一个结点,然后依次遍历,将当前结点的指针指向上一个结点
2.从尾到头打印链表(反转顺序第一时间想到栈)
3.合并有序链表
4.判断链表是否有环:定义两个指针,我们用两个指针去遍历:first指针每次走一步,second指针每次走两步,如果first指针和second指针相遇,说明有环。
5.求链表的倒数第k个结点
我们定义两个指针,第一个指针从链表的头指针开始遍历向前走k-1步,第二个指针保持不动:从第k步开始,第二个指针也开始从链表的头指针开始遍历,由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点.。