一、String、StringBuffer和StringBuilder的区别
1.1相关介绍
String是只读字符串,并不是基本数据类型,而是一个对象。从底层源码来看是一个final修饰的字符数组,所引用的字符串不能改变,一经定义无法再增删改。每次对String操作都会生成新的String对象。
所以对于经常改变内容的字符串最好不用String,因为每次生成对象都会对系统性能产生影响,特别是内存当中引用对象多了以后,JVM的GC就会开始工作,这样速度会很慢。
private final char value[];
每次“+”操作都隐式在堆上new了一个跟原字符串相同的StringBuilder对象,再调用append方法拼接+后面的字符。
StringBuffer和StringBuilder都继承了AbstractStringBuilder抽象类,冲AbstractStringBuilder抽象类中可以看到它们底层是可变的字符数组,所以再进行频繁的字符串操作的时候,建议使用StringBuffer和StringBuilder操作。
/**
* The value is used for character storage.
*/
char[] value;
另外
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,是线程安全的
StringBuilder没有对方法加同步锁,是线程非安全的,StringBuilder效率更高。
1.2执行效率
StringBuilder > StringBuffer > String
1.3用法
操作少量的数据用String
在多线程编程中操作字符串缓冲区下操作大量数据用StringBuffer
在单线程操作字符串缓冲区下操作大量数据用StringBuilder
二、ArrayList和linkedList
Array(数组)是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的。
Array获取数据的时间复杂度是O(1),但是要删除数据却是开销很大,因为这需要重排数组中的所有数据, (因为删除数据以后, 需要把后面所有的数据前移)
缺点: 数组初始化必须指定初始化的长度, 否则报错
例如:
int[] a = new int[4];//推荐使用这种方式初始化
int b[] = {1,3,4,7};
List是一个有序的集合,可以包含重复的元素,提供了安索引访问的方式,继承Collection。
List有两个重要的实现类,ArrayList和linkedList
ArrayList可以看作是能够自动增长容量的数组
ArrayList的toArray方法返回一个数组
ArrayList的asList方法返回一个列表
ArrayList底层的实现是Array, 数组扩容实现
LinkList是一个双链表,在添加和删除元素时比ArrayList性能更好,但在get和set方面弱于ArrayList。
三、HashMap和HashTable的区别
3.1父类不同
HashMap继承自AbstractMap,而HashTable继承自Dictionary类。
不过它们都实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口
3.2对外提供的接口不同
Hashtable比HashMap多提供了elments() 和contains() 两个方法。
elments()方法继承自HashTable的父类Dictionary。elements()方法用于返回此HashTable中的value的枚举。
contains()方法用来判断该HashTable是否包含出入的value。它的作用与containsValue()一致。事实上containsValue()就只是调用了一下contains()方法。
3.3对null的支持不同
HashTable:key和value都不能为null
HashMap:key可以为null,但是只能有一个key为null,因为必须保证key的唯一性。不过可以有多个key值对应的value为null。
3.4安全性不同
HashMap线程不安全,在多并发环境下可能会产生死锁等问题,因为需要开发人员自己处理多线程安全问题。
HashTable是线程安全的,它的每个方法上都有synchronized关键字,可直接用于多线程中。
虽然HashMap是线程不安全的,但是效率远高于HashTable,这样设计是合理的,因为大部分场景使用的是单线程。
需要多线程的时候可以使用ConcurrentHashMap,它是线程安全的,但是它的效率比HashTable要高很多,因为ConcurrentHashMap使用了分段锁,并不对整个数据进行锁定。