Collection集合
Collection是单列集合的顶层实现,是一个接口,提供了如下方法
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
集合的遍历方法
- 通过迭代器进行遍历,集合调用iterator方法得到一个Iteratora对象,iterator中提供了如下方法
- 通过增强for循环
for(元素数据类型 变量名 : 数组/集合对象名) {
循环体; }
方法名 | 说明 |
---|---|
boolean hasNext() | 判断集合中是否存在下一元素 |
element next() | 得到集合的元素 |
List集合
list仍然是一个接口,提供了更细化的接口
List集合特点:
- 有索引
- 可以存储重复元素
- 存取顺序有序
List集合的特有方法
方法名 | 描述 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
ListIterator介绍
- 通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器
- 用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
并发修改异常
-
出现的原因
迭代器遍历的过程中,通过集合对象修改了集合中的元素,造成了迭代器获取元素中判断预期修改值和实际修改值不一致,则会出现:ConcurrentModificationException
-
解决的方案
用for循环遍历,然后用集合对象做对应的操作即可
List集合的具体实现
- ArrayList
- LinkedList
特点:
ArrayList:
- 底层采用数组实现
- 查询快
- 增加和删除慢
LinkedList:
- 底层采用链表实现
- 查询较慢
- 增删快
LinkedList
概述:和ArrayList集合一样,是List的具体实现
特有方法
方法名 | 说明 |
---|---|
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
Set集合
set集合是一个接口
set集合特点:
- 元素存取无序
- 没有索引,只能通过迭代器和增强for遍历
- 不能存储重复元素
哈希值
-
哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值 -
如何获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
-
哈希值的特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
HashSet
HashSet集合的特点
- 底层数据结构是哈希表
- 对集合的迭代顺序不做保证,也就是说取出元素顺序和存储集合时可能不一致
- 没有带索引的方法,故只能通过迭代器或者增强for循环进行遍历
- 由于实现了Set接口,故集合不可以存储重复元素
HashSet集合保证元素唯一性的原理
1.根据对象的哈希值计算存储位置
- 如果当前位置没有元素则直接存入
- 如果当前位置有元素存在,则进入第二步
2.当前元素的元素和已经存在的元素比较哈希值
- 如果哈希值不同,则将当前元素进行存储
- 如果哈希值相同,则进入第三步
3.通过equals()方法比较两个元素的内容
-
如果内容不相同,则将当前元素进行存储
-
如果内容相同,则不存储当前元素
图解:
哈希表
LinkedHashSet
LinkedHashSet集合特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复的元素
TreeSet
- 元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
- TreeSet():根据其元素的自然排序进行排序
- TreeSet(Comparator comparator) :根据指定的比较器进行排序
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以不包含重复元素的集合
栗子
package cn.dreamyi.demo1;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class StudentTest {
public static void main(String[] args) {
/**
* List集合 元素有顺序 有索引的方法 元素可重复
* ArrayList 底层采用数组实现 容易查询 不易大量增删
* LinkedList底层采用链表实现 容易增删 不易大量查询
*
* Set集合 元素无序、没有索引、不能重复
* TreeSet 具有排序功能 无序
* HashSet 底层采用哈希表实现 无序 且唯一性
* LinkedHashSet 采用链表和哈希表实现 具有有序和元素不重复特点
*/
/**
* 案例需求
*
* - 用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合
* - 要求:按照总分从高到低出现
*/
TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int i = o1.getAllScore() - o2.getAllScore();
i = i==0? o1.getChinese() - o2.getChinese(): i;
i = i==0? o1.getName().compareTo(o2.getName()) : i;
return i;
}
});
Student stu1 = new Student("zhangsan", 96, 98);
Student stu2 = new Student("wangwu", 94, 98);
Student stu3 = new Student("zhaoliu", 90, 100);
Student stu4 = new Student("libai", 90, 100);
Student stu5 = new Student("dufu", 95, 99);
treeSet.add(stu1);
treeSet.add(stu2);
treeSet.add(stu3);
treeSet.add(stu4);
treeSet.add(stu5);
Iterator<Student> iterator = treeSet.iterator();
while (iterator.hasNext()) {
Student stu = iterator.next();
System.out.println(stu.getName() + ","
+ stu.getChinese() + "," + stu.getMath() +","+stu.getAllScore());
}
System.out.println(treeSet.size());
}
}
package cn.dreamyi.demo1;
public class Student{
private String name;
private int chinese;
private int math;
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public Student(String name, int chinese, int math) {
this.name = name;
this.chinese = chinese;
this.math = math;
}
public int getAllScore(){
return this.chinese + this.math;
}
}