JAVA-容器一{容器-单例集合-ArrayList}JAVA从基础开始 --6
概况
容器:管理和储存数据的 叫容器
java的容器是在内存层面的(临时存储)
1.变量 int i
2.数组 int[] i线性,可快速访问元素
只有length 没有其他方法 不方便使用
结构
单例集合
单列集合:将数据一个一个进行存储
Collection接口 定义了单例集合基本行为(抽象方法)
◆list接口 :存储有序,可重复,动态数组
ArrayList 类
LinkedLast类
Vector类◆Set接口 : 存储无序,不可重复的,数学中的集合 ,确定性
HashSet类
LinkedHashSet类
TreeSet类
使用
Collection接口 中的抽象方法
◆boolean add(Object element) – 增加元素到容器中
◆boolean remove(Object element – 从容器中移除元素
◆boolean contains(object element) – 容器中是否包含该元素
◆int size() – 容器中元素的数量
◆boolean isEmpty() – 容器是否为空
◆void clear() – 清空容器中所有元素
◆Iterator iterator() – 获得迭代器,用于遍历所有元素
◆boolean containsAll(Collection c) – 容器是包含C容器中的所有元素
◆boolean addAll(Collection c) – 将容器C中所有元素增加到本容器 --并集
◆boolean removeAll(Collection c) – 移除本容器和容器C中都包含的元素 – 开集
◆boolean retainall(Collection c) – 取本容器和容器C中都包含的元素,移除非交集元素 – 交集
Object[] toArray() – 转化成 Object数组
List 和 Set是Collection的子接口,所以拥有以上所有方法
jdk1.8之后 函数编程添加方法
List接口
有序 :存入数据与取出顺序是一致的 有对应的索引标记
可重复:List通常满足 e1.equals(e2)
常用方法 (多了些索引的方法)
◆void add (int index, Object element) – 在指定位括入元崇,以前元全部后移一位–同javascript中的 splice(n,m,Object)
◆Object set (int index,Object elemen – 像改指定位的元素
◆Object get (int index) – 返回指定位而的元东
◆Object remove(int index) – 删除指定位v的元素。后面元素全部移位–同javascript中的 splice(n,1)
◆int indexof (Object o) – 返回第个匹配元素的索引,如果没有该元素,返回-1
◆int lastindexof (Object o) – 返回最后一个匹配元素的索引,如果没有该元素,返回 -1
ArrayList容器类 – 单例集合
ArrayList是List皆苦的实现类,是List储存特征的具体实现 底层是用数组实现的储存
特点: 查询效率高,增删效率低,线程不安全
package top.baokeaia;
import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
// 封装循环数组
static void fo(List list, String msg) {
System.out.println("------------------------");
int listLength = list.size();
//自带方法判断容器是否是空
if (list.isEmpty()) {
System.out.println("list.isEmpty()值 = " + list.isEmpty());
System.out.println("isEmpty方法判断,容器数组是否为空");
return;
}
if (listLength <= 0) {
System.out.println("容器数组被清空或者数组出现异常");
return;
}
for (int i = 0; i < listLength; i++) {
System.out.println(list.get(i) + msg);
}
}
static void so(List list, String method, String[] value, String msg) {
System.out.println("------------------------");
for (String s : value) {
if (method == "contains") {
System.out.println(msg + s + method + "---" + list.contains(s));
} else if (method == "indexOf") {
System.out.println(msg + s + method + "---" + list.indexOf(s));
} else if (method == "lastIndexOf") {
System.out.println(msg + s + method + "---" + list.lastIndexOf(s));
}
}
}
public static void main(String[] args) {
List<String> list = new ArrayList();
//添加元素 add
boolean beijing = list.add("北京");
System.out.println(beijing);
list.add(1, "南昌");
list.add(2, "赣州");
//下标不能大于数组长度 list.add(2"nanchang");报异常!
//根据位置获取元素 get
System.out.println(list.get(0) + "sout");
System.out.println(list.get(1) + "sout");
//索引不在数组尺寸内,报异常!
//循环取数组
ArrayListTest.fo(list, "-----正常for循环全部数组");
if (false) {// 控制是否删除
//删除元素 remove
list.remove("北京");
ArrayListTest.fo(list, "-----通过元素删除北京后");
list.remove(1);
ArrayListTest.fo(list, "-----通过下标删除1后");
}
//替换元素 set
list.set(1, "赣县");
ArrayListTest.fo(list, "-----通过索引1替换成赣县后");
if (false) {// 控制是否清空
//清空容器
list.clear();
System.out.println("清空容器后的list长度" + list.size());
ArrayListTest.fo(list, "-----清空容器后的list长度");
}
//判断容器中是否包含指定元素 contains
String[] con = {"赣州", "南昌"};
ArrayListTest.so(list, "contains", con, "是否包含元素 ");
//查找元素位置 indexOf
String[] ind = {"北京", "赣州", "南昌"};
ArrayListTest.so(list, "indexOf", ind, "查找第一次出现的位置 ");
//从后面查找元素位置 lastIndexOf
String[] lastInd = {"北京", "南昌", "赣州"};
ArrayListTest.so(list, "lastIndexOf", lastInd, "查找最后一次出现的位置 ");
}
}
输出
单例集合转成数组
static void fo(Object[] list, String msg) {
System.out.println("------------------------");
// int listLength = list.size();
int listLength = list.length;
//自带方法判断容器是否是空
// if (list.isEmpty()) {
// System.out.println("list.isEmpty()值 = " + list.isEmpty());
// System.out.println("isEmpty方法判断,容器数组是否为空");
// return;
// }
if (listLength <= 0) {
System.out.println("容器数组被清空或者数组出现异常");
return;
}
for (int i = 0; i < listLength; i++) {
String str = (String) list[i];//集合不能直接(String[])批量强制转换,必须每一项单独做转换
System.out.println(str + msg);
}
}
//将ArrayList转成Object数组
Object[] arr = list.toArray(); //不能将数组强制类型转换
ArrayListTest.fo(arr, ":Object数组,ArrayList的size,get,isEmpty方法都不能使用");
//转换成指定类型的数组 --转换泛型类型数组
String[] strings = list.toArray(new String[list.size()]);
//可以将单例数组转换成String数组----但类型需要参考泛型类型
ArrayListTest.fo(strings, ":直接String数组 -- list.toArray(new String[list.size()])");
容器交集操作
List<String> a1 = new ArrayList<>();
//添加元素 add
a1.add("北京a1");
a1.add(1, "南昌");
a1.add(2, "赣州");
boolean b = a1.retainAll(list);
ArrayListTest.fo(a1,":容器的交集a1最后返回值");
System.out.println(b);
容器差集操作
//差集
boolean b1 = a1.removeAll(list);
ArrayListTest.fo(a1,":容器的差集a1最后返回值");
System.out.println(b1);
ArrayList源码分析
ArrayList底层存储方式
ArrayList底层是用数组实现存储
在ArrayList中
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
public ArrayList() {
//无参构造方法中,设定了需要用到的elementData数组是个空数组{}--初始化
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//add 方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//在add方法中
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//记录操作次数
// overflow-conscious code
if (minCapacity - elementData.length > 0) //第一次扩容后,长度为10,当再次add后,若长度小于10,则不扩容
grow(minCapacity);//主要函数,扩容elementData数组长度
}
//grow方法实现
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
//右移相当于除以二,若值为10,结果为5,newCapacity的值就为15
//相当于每次扩容,都是以1.5倍的容积来扩容的
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);
}
当方法执行完以后,elementData的长度扩容到了10
再在add方法中,把size++的下标的位置放入e元素