1.List
1.1List的实现类ArrayList,LinkedList,Vector的异同。
相同点:这三个实现类都是实现了List接口。存储的数据都是有序,可重复的数据
不同点:
ArrayList:List接口的主要实现类,线程不安全的,效率高,底层使用了Object[]数组存储
LinkedList:对频繁的插入删除操作,使用这个实现类比ArrayList效率高,底层使用了双向链表。
Vector:作为List的最早的实现类,线程安全,效率低。
1.2 ArrayList源码分析
在jdk1.7之前,当使用new ArrayList()的无参构造器创建对象时,会默认创建一个大小为10的Object[]的数组。每次调用add方法会进行判断,如果达到数组容量的最大值,会进行扩容,新建一个Object数组容量为原来数组的1.5倍,然后把原数组内容进行复制。
new ArrayList(int) 直接创建一个指定大小的数组。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
在jdk1.8之后,首先不会进行创建(
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
)当首次add时会进行创建。添加和扩容和1.7一样。
1.3 LinkedList源码分析
底层实现双向链表
参考:https://www.jianshu.com/p/ea5b7dd7dc01
1.4 ArrayList常用方法
2. Set
2.1 HashSet介绍
无序,不可重复的数据。
无序性:不代表随机性,存储的数据在底层数组中并不是按照数组的索引进行添加的,而是根据数组的哈希值进行相关的操作存储。
不可重复性:保证添加的元素按照equals判断时不能返回为true,表示相同的元素只能添加一个。
2.2 HashSet底层原理
HashSet底层就是HashMap
执行流程:
所以在想set插入数据时,确保插入的数据元素实现了hashCode方法和equals方法,且能确保同一个元素能获取相同的哈希值。
3.map
3.1 HashMap底层原理
以JDK1.7为例:
1.当new HashMap()时,会在底层创建一个Entry[]数组,初始容量为16,加载因子为0.7。
2.当执行put(key1,value1)方法时,首先会根据key的值获取一个哈希值。在把哈希值经过某种算法获取这个k-v存储在底层数组的索引值。
3.根据索引值找到存储该元素的位置,如果该位置为空,则直接添加。
4.如果这个位置上存在一个或多个元素时(链表结构)时,把上述获取到哈希值分别和每一个元素比较。
5.如果哈希值和所有元素都不一样,则把这个元素添加到Entry数组的这个索引位置处,指向原来元素。
6.如果哈希值和其中一个元素一样,就会调用equals方法,比较这两个key是否相同。
7.如果这两个key不同,则添加到Entry数组的这个索引位置处,指向原来元素。
8.如果这两个key相同,则把value1的值进行覆盖原来的值。
扩容原则:当Entry[]数组达到 数组容量*加载因子时开始扩容,新建一个容量为原容量2倍的Entry数组,然后把原数组的内容进行复制。
JDK1.8的改进:
1.new HashMap()时,不会立刻创建一个Node数组,而是等到添加元素时才开始创建。
2.底层不在创建Entry数组,而是Node数组。
3.JDK1.7底层是数组+链表。JDK1.8底层原理为数组+链表+红黑树
当数组中某一个索引位置上的以链表形式存在的数据大于8个,且数据的长度大于64时,此索引位置上的所有数据改为红黑树存储。
3.2 HashMap常用方法
Map<String,Integer> maps = new HashMap<>();
maps.put("a",15);
maps.put("b",20); //插入
maps.put("c",35);
System.out.println(maps);
maps.remove("a"); //删除
System.out.println(maps);
maps.put("b",40); //修改
System.out.println(maps);
Integer b = maps.get("b"); //查询
System.out.println(b);
boolean isA = maps.containsKey("a"); //是否包含某个key
System.out.println(isA);
Set<String> keys = maps.keySet(); //获取key的set集合
Collection<Integer> values = maps.values(); //获取所有的values
Set<Map.Entry<String, Integer>> entries = maps.entrySet(); // 获取所有的k-v
Iterator<String> iterator = keys.iterator();
while(iterator.hasNext()){ //迭代器遍历
System.out.println(iterator.next());
}
for (Map.Entry<String, Integer> entry : entries) { //增强for遍历
System.out.println(entry.getKey()+":"+entry.getValue());
}
3.3properties使用
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
FileInputStream fps = new FileInputStream("src/jdbc.propertise");
properties.load(fps);
String name = properties.getProperty("name");
System.out.println(name);
fps.close();
}