目录
什么是集合?
集合的分类
<> : 泛型
浅谈泛型
代码示例
细说泛型
泛型类
泛型方法
泛型接口
泛型通配符
Collection接口
集合的通用遍历方式
1、迭代器遍历
2、增强for循环
3、forEach方法
4、代码示例
List接口
方法
List集合的遍历方式
并发修改异常 : ConcurrentModificationException
数据结构——顺序表:ArrayList
构造方法
ArrayList 常用成员方法
代码示例
数据结构——双向链表:LinkedList
数据结构——红黑树:TreeSet
红黑规则
添加结点规则
数据结构——哈希表:HashSet
集合是一种容器,长度可变
List集合:存取有序、有索引、可以存取重复的
Set集合:存取无序、无索引、不能存取重复的
泛型可以对集合中数据的数据类型进行约束
例如:ArrayList
在JDK7版本之后,后面的尖括号中的内容可直接省略,直接写成ArrayList
目前: 使用泛型, 可以对集合中存储的数据, 进行类型限制
细节: 泛型中, 不允许编写基本数据类型
问题: 那我要是想集合中, 存储 整数, 小数, 字符... 这些数据, 怎么办呢?
解决: 使用基本数据类型, 所对应的包装类
byte -> Byte
short -> Short
int -> Integer (重点记忆)
long -> Long
float -> Float
double -> Double
boolean -> Boolean
char -> Character (重点记忆)
public static void main(String[] args) {
// 步骤1: 创建一个集合容器, 内部存储 11.1 22.2 33.3
ArrayList list1 = new ArrayList<>();
list1.add(11.1);
list1.add(22.2);
list1.add(33.3);
// 步骤2: 创建一个集合容器, 内部存储 张三, 李四, 王五
ArrayList list2 = new ArrayList<>();
list2.add("张三");
list2.add("李四");
list2.add("王五");
// 步骤3: 在控制台展示两个集合中的元素
System.out.println(list1);
System.out.println(list2);
}
// 以多态的形式创建集合对象, 调用单列集合中的共有方法
//左边接口名,右边实现类对象
Collection c = new ArrayList<>();
c.add("张三");
c.add("李四");
c.add("王五");
boolean b = c.contains("赵四");
System.out.println(b);
System.out.println(c.size());
List集合的遍历方式:
但这种方法不适用于Set集合,因为Set集合没有索引,所以下面介绍几种集合的通用遍历方法
public Iterator
public E next() : 从集合中获取一个元素
public boolean hasNext() : 如果仍有元素可以迭代,则返回 true
迭代器遍历三部曲
简化迭代器的书写,底层逻辑也是迭代器
其实我觉得增强for循环有点像vue中的v-for,v-for="(item,index) in arr",其中的item就相当于上述例子中的s,而arr相当于上述例子中的list
Collection c = new ArrayList<>();
c.add(new Student("张三", 23));
c.add(new Student("李四", 24));
c.add(new Student("王五", 25));
// 1. 获取迭代器
Iterator it = c.iterator();
// 2. 循环判断, 集合中是否还有元素
while (it.hasNext()) {
// 3. 调用next方法, 将元素取出
Student stu = it.next();
System.out.println(stu.getName() + "---" + stu.getAge());
}
System.out.println("--------------------");
// 使用增强for循环遍历集合
//idea增强for循环快捷键c.for+enter
for (Student stu : c) {
System.out.println(stu);
}
System.out.println("--------------------");
// foreach方法遍历集合
c.forEach(stu -> System.out.println(stu));
List接口的特点 : 存取有序, 有索引, 可以存储重复的
List list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.set(0, "赵六");
list.remove(1);
System.out.println(list.get(0));
System.out.println(list);
System.out.println("-------------------------");
List list2 = new ArrayList<>();
list2.add(111); // Integer e = 111;
list2.add(222);
list2.add(333);
list2.remove(Integer.valueOf(222)); //若希望根据元素删除而不是根据索引删除,则需要Integer.valueOf
System.out.println(list2);
通用遍历方式:
1. 迭代器遍历
2. 增强for循环
3. foreach方法
List集合特有的遍历方式:
1. 普通for循环
2. ListIterator (List集合特有的迭代器)
List list = new ArrayList<>();
list.add("abc");
list.add("bbb");
list.add("ccc");
list.add("abc");
for (int i = 0; i < list.size(); i++) { //普通for循环
String s = list.get(i);
System.out.println(s);
}
System.out.println("---------------");
ListIterator it = list.listIterator();
while(it.hasPrevious()){ //逆序遍历
String s = it.previous();
System.out.println(s);
}
System.out.println("---------------");
while (it.hasNext()) { //顺序遍历
String s = it.next();
System.out.println(s);
}
场景: 使用[迭代器]遍历集合的过程中, 调用了[集合对象]的添加, 删除方法, 就会出现此异常
解决方案: 迭代器的遍历过程中, 不允许使用集合对象的添加或删除, 那就使用迭代器自己的添加或删除方法。普通的迭代器有删除方法,普通迭代器没有添加方法, 需要使用List集合特有的迭代器的添加方法
List list = new ArrayList<>();
list.add("眼瞅着你不是真正的高兴");
list.add("温油");
list.add("离开俺们这旮表面");
list.add("伤心的人别扭秧歌");
list.add("私奔到东北");
ListIterator it = list.listIterator();
while (it.hasNext()) {
String s = it.next();
if ("温油".equals(s)) {
it.add("哈哈");
}
}
System.out.println(list);
当数组元素满了之后,会自动扩容为1.5倍
细节: 创建String, StringBuilder, ArrayList类的对象, 打印对象名, 都没有看到地址值, 而是元素内容
public ArrayList() : 创建一个空的集合容器
其中有一些方法是List接口提供的
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add("张三1");
list.add("张三2");
list.add("张三3");
String s = list.get(2);
System.out.println(s);
System.out.println(list.size());
}
private static void updateMethod() {
ArrayList list = new ArrayList<>();
list.add("张三1");
list.add("张三2");
list.add("张三3");
String result = list.set(1, "李四");
System.out.println(result);
System.out.println(list);
}
private static void removeMethod() {
ArrayList list = new ArrayList<>();
list.add("张三1");
list.add("张三2");
list.add("张三3");
System.out.println(list);
boolean flag = list.remove("李四");
System.out.println(flag);
System.out.println(list);
}
private static void addMethod() {
ArrayList list = new ArrayList<>();
list.add("张三1");
list.add("张三2");
list.add("张三3");
list.add(0, "张三4");
System.out.println(list);
}
public static void main(String[] args) {
LinkedList list = new LinkedList<>();
list.add("张三");
list.add("李四");
list.add("王五");
String s = list.get(1);
System.out.println(s);
}
private static void method2() {
LinkedList list = new LinkedList<>();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
System.out.println(list.getFirst());
System.out.println(list.getLast());
list.removeFirst();
list.removeLast();
System.out.println(list);
}
private static void method1() {
LinkedList list = new LinkedList<>();
list.addFirst("张三");
list.addFirst("李四");
list.addFirst("王五");
list.addLast("赵六");
// 王五 李四 张三 赵六
System.out.println(list);
}
学习TreeSet之前,大家需要先理解一些概念:树、二叉树、二叉查找树(二叉搜索树)、平衡二叉树、左(右)旋,对于这些概念,大家可以去网上搜索数据结构的动画演示,结合动画很快就能理解
接下来咱们详细说说红黑树,作者在学平衡二叉树的时候觉得还蛮简单的,但是学到红黑树的时候,被红黑树添加结点的规则给绕晕了,所以在这里有必要记录一下红黑规则和红黑树添加结点的规则
红黑树是一种自平衡的二叉查找树
TreeSet集合特点:排序、去重,代码示例:
未完待续