ArrayList 和 LinkedList的区别
Array(数组)是基于索引的(index)的数据结构
Array 获取数据是很快,可以根据下标索引,时间复杂度为O(1)。但删除数据时却很麻烦,删除除末尾下标元素为的其他下标元素,都需要将后面每个元素都向前移动一位。因此删除末尾下标外的元素,平均时间复杂度为O(n)
数组初始化必须指定初始化的长度
List 是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式,它继承Collection。
List 有两个重要的是实现类:ArrayList 和 LinkedList
ArrayList: 可以看做是能够自动增长容量的数组,底层实现是Array,数组扩容实现
toArray 方法返回一个数组
asList方法返回一个列表
HashMap 和 HashTable 的区别
1. 对外提供的接口不同
HashTable 比 HashMap 多提供了 elements()和 contains()两个方法。elements()方法继承自 HashTable 的父类 Dictionnary。elements()方法用于放回此HashTable 中的 value的枚举
contains ()方法判断该 Hashtable 是否包含传入的value
2. 对 null 的支持不同
Hashtable:key 和 value 都不能为null
HashMap:key可以为 null ,但是这样的key 只能有一个,因为必须确保key 的唯一性;可以有多个key值对应的value 为null
3. 安全性不同
HashTable 线程安全,因为每个方法上都有synchronized 关键字,因此可以直接用于多线程中
HashMap 虽然线程不安全,但效率远高于Hashtable
泛型常用特点
"泛型" 意味着编写的代码可以被不同类型的对象所重用
常用的ArrayList 就是个泛型类,ArrayList 作为集合可以存放各种元素,如Integer,String,自定义的各种类型等。但我们在具体使用时,可以通过具体的规则来约束,例如
List <Integer> data = new ArrayList<>()
使用泛型,我们不必因为添加元素类型的不同而单独定义不同类型的集合,我们可以单独顶一个一个集合来存放整型,浮点型,字符串型数据。因为只要把底层储存设置Object即可,添加的数据全部都可以向上转型为Object。更重要的是我们可以根据自己的想法控制储存的数据类型
Java创建对象的四种方式
- new 创建新对象
- 通过反射机制
- 采用clone机制
- 通过序列化机制
不相同的对象是否有相同的hashcode
有可能,在产生hash冲突时,两个不相同的对象有可能产生相同的 hashcode 值。当hash 冲突产生时,一般可以有以下方式来处理:
拉链法:每个哈希表节点中都有一个next 指针,多个哈希表节点可以用next 指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表进行储存
开放地址法:一旦产生冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入
双哈希法:有多个不同的hash 函数,发生冲突时,使用第二个、第三个hash 函数... 直到哈希函数计算地址无冲突
深拷贝和浅拷贝的区别
浅拷贝:只复制对象的 "引用地址",新旧对象共享底层的引用类型数据,修改一方会影响另一方
深拷贝:复制对象的 "完整内容"(包括引用类型的底层数据),新旧对象完全独立,修改一方不会影响另一方。
Java 中的数据类型分为两类,这是理解拷贝的基础:
基本数据类型(int、double、boolean 等):直接存储具体值,不存在 "引用"。
引用数据类型(String、ArrayList、自定义类等):变量存储的是 "内存地址"(引用),真正的数据存在该地址指向的内存空间中
final 的用法
- 被final 修饰的类不可以被继承
- 被final 修饰的方法不可以被重写
- 被final 修饰的变量不可以被改变(比如说变量的值)。若修饰的是引用,那么表示引用不可变,引用指向的内容可以被修改。
- 被final 修饰的方法,JVM 会将其尝试内联,以提高运行效率
- 被final 修饰的常量,在编译阶段会存入常量池中
static 的用法
static 关键字的基本用法:静态变量 和静态方法
被static 修饰的 变量/方法 都属于类的静态资源,类实例所共享
除静态变量和静态方法外,static 也用于静态块,多用于初始化操作
``