单列集合 : 一次添加一个元素(ArrayList、LinkedList、TreeSet、HashSet、LinkedHashSet)
一、Collection接口
1.List接口存取有序、有索引、可以存储重复的
2.Set接口存取无序、没有索引、不可以存储重复的
二、Collection使用
1.以多态的形式创建集合对象, 调用单列集合中的共有方法
Collection<String> c = new ArrayList<>();
2.Collection的常用方法:
public boolean add(E e) : 把给定的对象添加到当前集合中
public void clear() : 清空集合中所有的元素
public boolean isEmpty() : 判断当前集合是否为空
public boolean remove(E e) : 把给定的对象在当前集合中删除
public boolean contains(Object obj) : 判断当前集合中是否包含给定的对象
public int size() : 返回集合中元素的个数(集合的长度)
例:c.add(new Student("张三", 23));
c.clear();
boolean empty = c.isEmpty();
c.remove(new Student("张三", 23));
boolean st = c.contains(new Student("张三", 23));
c.size();
注:remove() contains() 底层依赖对象的equals方法
三、集合的通用遍历方式
1.迭代器
public Iterator<E> iterator() : 获取遍历集合的迭代器
public E next() : 从集合中获取一个元素
public boolean hasNext() : 如果仍有元素可以迭代,则返回 true
例:
// 1. 获取迭代器
Iterator<Student> it = c.iterator();
//2. 循环判断, 集合中是否还有元素
while (it.hasNext()) {
// 3. 调用next方法, 将元素取出
Student stu = it.next();
System.out.println(stu.getName() + "---" + stu.getAge());
}
注意: 如果next()方法调用次数过多, 会出现NoSuchElementException
迭代器源码分析:(只有简单相关源码)
private class Itr implements Iterator<E> {
int cursor; // 指针或者是游标,int类型会默认给0
public boolean hasNext() {//判断指针是否等于集合的长度
return cursor != size;
}
public E next() {
int i = cursor; //先把指针赋值给变量i
cursor = i + 1;//指针加1
return (E) elementData[lastRet = i];//返回下标是i个元素
}
}
2.增强 for 循环:简化迭代器的代码书写
JDK5之后出现的,其内部原理就是一个Iterator迭代器
格式:for (元素的数据类型 变量名 : 数组或者集合) { }
例:
for (Student stu : c) {
System.out.println(stu);
}
3.foreach 方法
default void forEach(Consumer<? super T> action)是一个默认方法
例:
//要的是接口,传入的应该是实现类,现在要的是函数类接口
c.forEach(new Consumer<Student>() {
@Override
public void accept(Student stu) {
System.out.println(stu);
}
});
//判断是否是函数式接口的关键@FunctionalInterface
//Lambda表达式:将光标放到Consumer上,alt+回车
c.forEach(stu -> System.out.println(stu));
四、List 接口(ArrayList、linkList(很少用))
存取有序、有索引、可以存储重复的
List接口的特点 : 存取有序, 有索引, 可以存储重复的
和索引有关的API :
public void add(int index, E element) : 在指定的索引位置, 添加元素
public E remove(int index) : 根据索引删除集合中的元素
public E set(int index, E element) : 根据索引修改集合中的元素
public E get(int index) : 返回指定索引处的元素
例:
List<Integer> list2 = new ArrayList<>();
list2.add(111); // Integer e = 111;
list2.add(222);
list2.add(333);
//在移除数字类型内容是需要进行手动装箱,否在会按照索引处理
list2.remove(Integer.valueOf(222));
List集合的遍历方式 :
1. 迭代器遍历
2. 增强for循环
3. foreach方法
4. 普通for循环
5. ListIterator (List集合特有的迭代器)
并发修改异常 : ConcurrentModificationException
① 场景: 使用[迭代器]遍历集合的过程中, 调用了[集合对象]的添加, 删除方法, 就会出现此
异常
② 解决方案: 迭代器的遍历过程中, 不允许使用集合对象的添加或删除, 那就使用迭代器, 自己的添加或删除方法
③ 删除方法 : 普通的迭代器有
④ 添加方法 : 普通迭代器没有, 需要使用List集合特有的迭代器
例:
List<String> list = new ArrayList<>();
list.add("Java");
list.add("世界");
list.add("你好");
ListIterator<String> it = list.listIterator();
while (it.hasNext()) {
String s = it.next();
if ("你好".equals(s)) {
//迭代器自己的添加方法
it.add("Hallow");
}
}
LinkedList :
LinkedList集合, 底层是双向链表结构, 查找元素的时候会从头部, 或者尾部逐个查找
但是它属于List体系中的集合, 也可以使用get方法, 根据索引直接获取元素.
LinkedList 特有方法 :
public void addFirst(E e) : 头部添加
public void addLast(E e) : 尾部添加
public E getFirst() : 获取第一个
public E getLast() : 获取最后一个
public E removeFirst() : 删除第一个
public E removeLast() : 删除最后一个
五、数据结构 (栈 队列 数组 链表)
数据结构是计算机底层存储、组织数据的方式,是指数据相互之间是以什么方式排列在一起的
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率
六、ArrayList类 LinkedList类
1.ArrayList 类
底层是基于数组实现的,根据查询元素快,增删相对慢
ArrayList 底层是数组结构的,数组默认长度为10
当数组添加满了之后,会自动扩容为1.5倍
源码解析:
① 使用空参构造器创建的集合,在底层创建一个默认长度为0的数组
② 添加第一个元素时,底层会创建一个新的长度为10的数组
③ 存满时,会扩容1.5倍
2.LinkedList类
底层基于双链表实现的,查询元素慢,增删首尾元素是非常快的