JAVA容器(集合)
一,容器
变量:存储单个数据的空间
数组[]:存储若干个相同类型数据的集合|容器
数组的优势在于是一种简单的线性序列,可以快速的访问数组元素,效率高。
如果从 效率和类型检查的角度讲,数组是最好的。
劣势不灵活:容量事先定义好,不能随着需求的变化而扩容。
数组有时远远不能满足我们的需求。我们需要一种 灵活的 , 容量可以随时扩充的容器来装载我们的对象。
1.1 Collection接口
Collection是一个接口,只是规定了一些方法,即作为一个容器就应该具有这些功能。在Collection 中并没有任何的可以存储数据的地方,因此只是作为一个规范存在。
- 添加 add
- 删除 remove
- 记数 size
- 包含 contains
- 清空 clear
- 是否为空 isEmpty
1.2 List extends Collection
List作为有序的Collection。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户 可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。同样是一个接口也只是 提供了一些抽象方法,做出相应的规范
- 可以存放很多数据,List中的数据可以重复
- 获取 get
- 查询对象出现的索引 indexOf(Object)
void add( Object element);
void add (int index, Object element);
Object get (int index);
Object set (int index,Object element);//修改某一位置的元素
Object remove (int index);
int indexOf (Object o);//返回某个元素的索引。如果没有该数据,返回-1
二,容器的使用
2.1 List
List接口下有两个实现类 LinkedList 和 ArrayList ,其中都实现了List中的方法,并且都给出了可 以存储数据的空间。
List<String> list = new LinkedList<>();
list.add("a");
list.add("b");
list.add(1,"good");
list.add(0,"nice");
list.add("hello");
System.out.println(list.size());
list.remove("a");
System.out.println(list.size());
list.set(0,"first");
System.out.println(list.get(0));
list.clear();
System.out.println(list.size());
2.2 List遍历
普通for循环 ,利用List元素有下标的特点,依次获取每一个元素
for (int i=0; i<list.size(); i++){
System.out.println(list.get(i));
}
增强for 依次获取集合中每一个元素存入一个临时变量中
for (String temp : list) {
System.out.println(temp);
}
底层用双向链表实现的List。特点:查询效率低,增删效率高,线程不安全。
底层用数组实现的List。特点:查询效率高,增删效率低,线程不安全。
2.3 迭代器(Iterator)
所有实现了Collection接口的容器类都有一个 iterator 方法用以返回一个实现了Iterator接口的对 象。
Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
Iterator接口定义了如下方法:
- boolean hasNext(); //判断是否有元素没有被遍历
- Object next(); //返回游标当前位置的元素并将游标移动到下一个位置
- void remove(); //删除游标左面的元素,在执行完next之后该 ,操作只能执行一次
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
在List中为我们提供了一个listIterator(int index)方法,
可以从列表中的指定位置开始,返回列表中元素的列表迭代器(按正确顺序)。
//利用listIterator(int index)反向输出数组
ListIterator<String> it = list.listIterator(list.size());//指定开始位置
while(it.hasPrevious()){//反向遍历
it.previous();//反向输出
}
2.4 ArrayList
ArrayList是List接口的实现类
特点: 有序 可重复
ArrayList :
- 底层结构: 可变数组
- 优点: 根据索引查询效率高,访问速度快
- 缺点: 增删涉及到数组的拷贝问题等效率较低
- 应用场景: 大量做查询,少量做增删的情况下适合使用ArrayList存储数据
- 扩容: 初始容量为10,扩容机制->int newCapacity = oldCapacity + (oldCapacity >> 1); 每次扩容原容量的1.5倍,利用Arrays.copyOf实现扩容
- 新增方法: void forEach(Consumer<? super E> action) 对 Iterable每个元素执行给定操作,直到处理 Iterable所有元素或操作引发异常。
ArrayList<Integer> list = new ArrayList<>();
//foreach
list.forEach(System.out::println);//遍历集合
2.5 LinkedList链表
特点: 有序 可重复
底层结构: 双向链表
优点 : 做查询效率较低
缺点 : 做增删效率较高
应用场景 : 大量做增删少量做查询推荐使用LinkedList
新增功能 : 新增了一些可以操作链表头尾的方法
2.6 Set
Set 无序 不可重复|去重
新增方法: Set<E> of(E… elements)返回包含任意数量元素的不可修改集。
无序: 存放的顺序与内部真实存储的顺序不一致(内部与自己存储的规则)
去重: 两个数据调用equals方法返回值true,相同需要去重,false不同可以添加
以为Set集合无序的特点,只能使用for…each和iterator迭代器循环遍历
//static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。
Set<Integer> set3 = Set.of(1,2,3,4,5);
2.7 HashSet
HashSet
- 底层结构: 哈希表 (数组+链表+红黑树) ->是由HashMap维护
- 优点 : 查询,增删效率较高
- 缺点 : 无序
- 应用场景: 实现不存储相同数据,查询,增删效率较高的时候建议使用HashSet
- 新增功能: 无新增功能
- 去重: 需要在存储数据的类型中重写hashcode与equals方法实现数据的去重