今日学习笔记
1、 集合(容器)
Collection接口中包括List和Set两种集合方式,List是有序可重复,而Set则是无序不可重复的。
Collection实现类中包括许多的方法,而这些方法也大部分在List和Set中也都通过继承而实现。
Int size()//容器元素的数量
Boolean add(Object obj)//增加元素到容器中
Boolean remove(Object obj)//从容器中移除元素
Boolean contains(Object obj)//容器中是否包含该元素
Boolean isEmpty(Object obj)//容器是否为空
Void clear()//清空容器容器中所有的元素
Object[] toArray()//转化为Object数组
以及许多All*方法。
2、List集合
List是有序、可重复的容器。
有序:List中每个元素都有索引标记。可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素。
可重复:List允许加入重复的元素。更确切地讲,List通常允许满足e1.equals(e2) 的元素重复加入容器。
List接口常用的实现类有3个:ArrayList、LinkedList和Vector。
LinkedList底层用双向链表实现的存储。特点:查询效率低,增删效率高,线程不安全。
ArrayList底层是用数组实现的存储。 特点:查询效率高,增删效率低,线程不安全。我们一般使用它。
Vector底层是用数组实现的List,相关的方法都加了同步检查,因此“线程安全,效率低”。
除了Collection接口中的方法,List多了一些跟顺序(索引)有关的方法:
Void add(int index,Object obj)//在指定位置插入元素以前的元素全部后移一位
Object set(int index, Object obj)//修改指定位置的元素
Object get(int index)//返回指定位置的元素
Object remove(int index)//删除指定位置的元素,后面元素全部前移一位
Int indexof(Object obj)//返回第一个匹配元素的索引位置,没有则返回-1
Int lastIndexof(Object obj)//返回最后一个匹配元素的索引位置,没有则返回-1
3、Map集合
Map就是用来存储“键(key)-值(value) 对”的。 Map类中存储的“键值对”通过键来标识,所以“键对象”不能重复。
Map 接口的实现类有HashMap、TreeMap、HashTable、Properties等。
HashMap采用哈希算法实现,是Map接口最常用的实现类。 由于底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新的键值对会替换旧的键值对。 HashMap在查找、删除、修改方面都有非常高的效率。
HashTable类和HashMap用法几乎一样,底层实现几乎一样,只不过HashTable的方法添加了synchronized关键字确保线程同步检查,效率较低。
HashMap与HashTable的区别
HashMap: 线程不安全,效率高。允许key或value为null。
HashTable: 线程安全,效率低。不允许key或value为null。
4、手写Collection源码
package com.test.mycollection;
/**
* @author
* @version JDK1.8
* @创建时间 2019年8月20日 下午9:53:33
* @类说明 手写一个基本的ArrayList,熟练掌握其特性。
*/
public class MyArraryList<E> {
private Object[] elementData;
private int size;
private static final int DEFALT_CAPACITY = 10;
//无参构造器
public MyArraryList() {
elementData = new Object[DEFALT_CAPACITY];
}
//有参构造器
public MyArraryList(int capacity) {
if (capacity < 0) {
throw new RuntimeException("数组长度不能为负数");
} else if (capacity == 0) {
Object[] elementData = new Object[DEFALT_CAPACITY];
} else {
elementData = new Object[capacity];
}
}
public void add(E e) {
if (size == elementData.length) {
//数组扩容
Object[] newArray = new Object[elementData.length + (elementData.length >> 1)];//注意运算优先级
//数组拷贝
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
elementData = newArray;
}
elementData[size++] = e;
}
//set、get方法
public E get(int index) {
checkRange(index);
return (E) elementData[index];
}
public void set(Object obj, int index) {
checkRange(index);
elementData[index] = obj;
}
//检查数组索引是否越界
public void checkRange(int index) {
if (index < 0 || index > size - 1) {
throw new RuntimeException("索引不正确!" + index);
}
}
//size方法
public int size() {
return size;
}
//isEmpty
public boolean isEmpty() {
return false;
}
//remove方法前置比较寻找
public void remove(E element) {
for (int i = 0; i < size; i++) {
if (element.equals(get(i))) {
remove(i);
}
}
}
//remove移除并Copy数组
public void remove(int index) {
int numMoved = elementData.length - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < size; i++) {
sb.append(elementData[i] + ",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
MyArraryList s1 = new MyArraryList(20);
for (int i = 0; i < 10; i++) {
s1.add("刘畅"+i);
}
System.out.println(s1.get(0));
s1.remove("刘畅2");
System.out.println(s1);
}
}